/* ===== Reset acotado ===== */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:auto}
body,h1,h2,h3,h4,p,figure,blockquote,dl,dd,ul,ol{margin:0}
ul[class],ol[class]{list-style:none;padding:0}
img,picture,video,canvas,svg{display:block;max-width:100%}
input,button,textarea,select{font:inherit;color:inherit}
button{background:none;border:0;cursor:pointer;padding:0}
a{color:inherit;text-decoration:none}
:where(h1,h2,h3,h4){text-wrap:balance}
p{text-wrap:pretty}

/* Ningún elemento decorativo (revelados laterales, sobreescaneo de parallax,
   halos) puede generar scroll horizontal. `clip` en lugar de `hidden`: no crea
   contenedor de scroll, así que el sticky del header y Lenis siguen funcionando. */
html,body{overflow-x:clip}
html{background:var(--white)}
body{
  font-family:var(--font-text);
  font-size:var(--t-base);
  line-height:1.6;
  color:var(--fg);
  background:var(--bg);
  overflow-x:clip;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  font-feature-settings:"cv05" 1,"ss03" 1;
}
/* Lenis toma el control del scroll; sin JS el scroll nativo sigue funcionando */
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}
.lenis.lenis-stopped{overflow:hidden}

::selection{background:var(--ink-500);color:#fff}

/* ===== Accesibilidad ===== */
.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}
.skip{position:fixed;top:.5rem;left:.5rem;z-index:999;padding:.7rem 1.1rem;background:var(--acc-600);color:#fff;font-weight:600;transform:translateY(-160%);transition:transform .2s}
.skip:focus{transform:none}
:focus-visible{outline:2px solid var(--acc-500);outline-offset:3px;border-radius:1px}

/* ===== Rejilla y contenedores ===== */
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter)}
.wrap-narrow{max-width:72rem}
.section{position:relative;padding-block:var(--sec-y);background:var(--bg);color:var(--fg)}
/* Respaldo del salto por ancla cuando no hay JS (o el navegador restaura una
   posición): la cabecera fija no puede comerse el arranque de la sección. */
[id]{scroll-margin-top:calc(var(--header-h) + .5rem)}
.grid{display:grid;gap:clamp(1.25rem,2.4vw,2.5rem)}

/* ===== Tipografía de sistema ===== */
.display{
  font-family:var(--font-display);
  font-weight:700;
  line-height:.92;
  letter-spacing:-.035em;   /* Poppins necesita tracking negativo en display */
  text-transform:uppercase;
}
.h1{font-size:var(--t-3xl)}
.h2{font-size:var(--t-2xl)}
.h3{font-family:var(--font-display);font-weight:600;font-size:var(--t-xl);line-height:1.12;letter-spacing:-.02em}
.lede{font-size:var(--t-lg);line-height:1.5;color:var(--fg-soft);max-width:52ch}
.body{max-width:var(--measure);color:var(--fg-soft)}
.body + .body{margin-top:1.1em}
.body strong{color:var(--fg);font-weight:600}

/* Capa de datos: es lo que hace que el sitio se lea como ingeniería */
.mono{
  font-family:var(--font-mono);
  font-size:var(--t-mono);
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--fg-mute);
}
.mono--accent{color:var(--accent)}

/* Etiqueta de sección: número + título, con el filete de la marca */
.eyebrow{display:flex;align-items:center;gap:.85rem;margin-bottom:clamp(1.5rem,3vw,2.75rem)}
.eyebrow::after{content:"";flex:1;height:1px;background:var(--line-strong)}
.eyebrow__n{font-family:var(--font-mono);font-size:var(--t-mono);color:var(--accent);letter-spacing:.1em}
.is-mist .eyebrow__n,[data-theme="light"] .eyebrow__n{color:var(--acc-600)}
.eyebrow__t{font-family:var(--font-mono);font-size:var(--t-mono);letter-spacing:.22em;text-transform:uppercase;color:var(--fg-mute)}

/* ===== Botones ===== */
.btn{
  --btn-bg:var(--ink-500);--btn-fg:var(--white);
  display:inline-flex;align-items:center;justify-content:center;gap:.7rem;
  min-height:52px;padding:.9rem 1.6rem;
  background:var(--btn-bg);color:var(--btn-fg);
  font-family:var(--font-text);font-weight:600;font-size:var(--t-sm);
  letter-spacing:.02em;border-radius:var(--radius);
  position:relative;overflow:hidden;isolation:isolate;
  transition:color var(--dur-fast) var(--ease-out),transform var(--dur-fast) var(--ease-out);
}
.btn::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--acc-500);transform:translateY(101%);transition:transform .38s var(--ease-out)}
.btn:hover::before,.btn:focus-visible::before{transform:none}
.btn:active{transform:translateY(1px)}
.btn__ico{width:1em;height:1em;flex:none;transition:transform .38s var(--ease-out)}
.btn:hover .btn__ico{transform:translateX(4px)}

.btn--ghost{--btn-bg:transparent;--btn-fg:var(--fg);border:1px solid var(--line-strong)}
.btn--ghost::before{background:var(--fg)}
.btn--ghost:hover,.btn--ghost:focus-visible{color:var(--bg)}
.btn--sm{min-height:44px;padding:.6rem 1.05rem;font-size:var(--t-xs)}
/* Botón imantado: el JS escribe el transform en línea, así que aquí se
   quita la transición de transform para no pelear con el rAF. */
.btn--mag{will-change:transform;transition:color var(--dur-fast) var(--ease-out)}
.btn--mag>span{display:inline-block;will-change:transform}
.btn--mag:active{transform:none}

/* Inclinación 3D siguiendo al puntero. El JS sólo escribe --rx y --ry. */
[data-tilt]{--rx:0deg;--ry:0deg;transform:perspective(900px) rotateX(var(--rx)) rotateY(var(--ry));
  transform-style:preserve-3d;transition:transform .5s var(--ease-out)}

/* Halo que sigue al puntero dentro de la caja. */
[data-spot]{--mx:50%;--my:50%;position:relative;isolation:isolate}
[data-spot]::after{content:"";position:absolute;inset:0;z-index:4;pointer-events:none;opacity:0;
  transition:opacity .45s var(--ease-out);
  background:radial-gradient(320px circle at var(--mx) var(--my),rgba(120,175,255,.14),transparent 62%)}
[data-spot]:hover::after{opacity:1}

/* Enlace con subrayado que se dibuja */
.link{position:relative;color:var(--fg);font-weight:500;padding-bottom:2px}
.link::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:1px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .4s var(--ease-out)}
.link:hover::after,.link:focus-visible::after{transform:none;transform-origin:left}

/* ===== Estados de revelado =====
   Regla dura: el contenido es visible por defecto. Sólo se oculta si el JS
   arrancó (html.js) y el usuario no pidió menos movimiento. */
.js .reveal:not(.is-in){opacity:0}
.js .mask>*{display:block}
.js .mask:not(.is-in)>*{transform:translateY(110%)}
/* El recorte va sobre el hijo, no sobre la caja: en display uppercase con
   line-height .92 la mancha del glifo excede la caja de línea y `overflow:hidden`
   a secas le comía la cabeza a los títulos. El padding lo devuelve y el margen
   negativo mantiene el ritmo vertical. */
.mask{overflow:hidden;margin-block:-.16em}
.mask>*{will-change:transform;transition:transform .95s var(--ease-out);padding-block:.16em}
.reveal{transition:opacity .8s var(--ease-out),transform .8s var(--ease-out)}

/* Revelados con desplazamiento: se combinan con .reveal */
.js .from-b:not(.is-in){transform:translateY(38px)}
.js .from-l:not(.is-in){transform:translateX(-38px)}
.js .from-r:not(.is-in){transform:translateX(38px)}
.js .from-s:not(.is-in){transform:scale(.94)}
/* En pantallas angostas no hay margen lateral que gastar: los desplazamientos
   horizontales entran desde abajo. */
@media (max-width:760px){
  .js .from-l:not(.is-in),.js .from-r:not(.is-in){transform:translateY(38px)}
}

/* Cortina: la imagen se descubre detrás de un telón que se retira */
.wipe{position:relative;overflow:hidden}
.wipe::after{content:"";position:absolute;inset:0;z-index:3;background:var(--bg);
  transform-origin:bottom;transition:transform 1.05s var(--ease-out)}
.js .wipe.is-in::after{transform:scaleY(0)}
.wipe>*{transition:transform 1.4s var(--ease-out)}
.js .wipe:not(.is-in)>*{transform:scale(1.14)}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
  .js .reveal:not(.is-in),.js .mask:not(.is-in)>*{opacity:1;transform:none}
}

/* =============================================================
   Dirección de arte fotográfica — duotono azul acero
   Un único tratamiento para toda la fotografía del sitio. Sin esto
   conviven un ámbar, un ocre y un violeta y el conjunto se cae.
   ============================================================= */
.ph{position:relative;overflow:hidden;isolation:isolate;background:var(--ink-900)}
.ph>picture,.ph>img,.ph picture{display:block;width:100%;height:100%}
.ph img{width:100%;height:100%;object-fit:cover;filter:var(--ph-filter)}
.ph::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:var(--ph-tint);mix-blend-mode:color;opacity:var(--ph-tint-o)}
.ph::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:var(--ph-shade)}
/* Grados de intensidad */
.ph--soft{--ph-filter:saturate(.5) contrast(1.08) brightness(.97);--ph-tint-o:.6}
.ph--deep{--ph-filter:saturate(.16) contrast(1.2) brightness(.8);--ph-tint-o:.92}
.ph--flat::after{display:none}
.ph--steel{--ph-filter:saturate(.22) contrast(1.14) brightness(1.03);
  --ph-tint:linear-gradient(158deg,#2F5C9C 0%,#14294A 100%);--ph-tint-o:.86;
  --ph-shade:linear-gradient(to top,rgba(6,14,26,.4),rgba(6,14,26,0) 58%)}

/* Etiqueta sobre imagen */
/* La leyenda cae sobre la foto: el degradado de .ph no alcanza cuando debajo
   hay una superficie clara (un camion blanco, cielo). La sombra la sostiene
   sobre cualquier fondo sin meter una caja opaca encima de la imagen. */
.ph__tag{position:absolute;z-index:4;left:0;bottom:0;padding:.7rem .95rem;
  font-family:var(--font-mono);font-size:var(--t-mono);letter-spacing:.16em;
  text-transform:uppercase;color:#E2EBF7;
  text-shadow:0 1px 2px rgba(3,8,16,.92),0 2px 14px rgba(3,8,16,.75)}

/* ===== Superficie oscura con vida: no queremos rectángulos negros ===== */
.glowfield{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.glowfield::before,.glowfield::after{content:"";position:absolute;border-radius:50%;
  filter:blur(90px);opacity:.5}
.glowfield::before{width:46vw;height:46vw;left:-10vw;top:-14vw;
  background:radial-gradient(circle,rgba(46,111,223,.36),transparent 68%)}
.glowfield::after{width:52vw;height:52vw;right:-16vw;bottom:-20vw;
  background:radial-gradient(circle,rgba(27,58,107,.5),transparent 70%)}
/* Retícula técnica muy tenue */
.gridfield{position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:linear-gradient(rgba(160,190,235,.055) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(160,190,235,.055) 1px,transparent 1px);
  background-size:clamp(48px,6vw,88px) clamp(48px,6vw,88px);
  mask-image:radial-gradient(ellipse 90% 70% at 50% 40%,#000 20%,transparent 78%);
  -webkit-mask-image:radial-gradient(ellipse 90% 70% at 50% 40%,#000 20%,transparent 78%)}
.section>.wrap{position:relative;z-index:1}

/* ===== Marquesina ===== */
.marquee{display:flex;overflow:hidden;user-select:none;
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.marquee__row{display:flex;flex:none;gap:clamp(1.6rem,3.5vw,3.2rem);padding-right:clamp(1.6rem,3.5vw,3.2rem);
  animation:slide 34s linear infinite;will-change:transform}
.marquee:hover .marquee__row{animation-play-state:paused}
@keyframes slide{to{transform:translateX(-100%)}}
.marquee__i{display:flex;align-items:center;gap:.8rem;flex:none;
  font-family:var(--font-mono);font-size:var(--t-mono);letter-spacing:.22em;
  text-transform:uppercase;color:var(--fg-mute);white-space:nowrap}
.marquee__i::before{content:"";width:5px;height:5px;flex:none;background:var(--accent);transform:rotate(45deg)}
@media (prefers-reduced-motion:reduce){.marquee__row{animation:none}}

/* ===== Cifra animada ===== */
.num{font-family:var(--font-display);font-weight:700;letter-spacing:-.04em;
  line-height:.88;font-size:var(--t-3xl);color:var(--fg);font-variant-numeric:tabular-nums}
.num sup{font-size:.38em;vertical-align:super;font-weight:600;color:var(--accent);letter-spacing:0}

/* ===== Grano: unifica fotografías de orígenes distintos ===== */
.grain{position:fixed;inset:0;z-index:60;pointer-events:none;opacity:.055;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E")}
@media (prefers-reduced-motion:reduce){.grain{display:none}}
