/* ═══════════════════════════════════════════════════════════════════════
   TEKHNE — Sistema de diseño
   ───────────────────────────────────────────────────────────────────────
   Traducción a web de la identidad del manual de marca.

   Cuatro decisiones estructurales, por si hay que discutirlas más adelante:

   1. El lienzo es el gris #F0F0F0 del manual, no el beige. El beige es un
      color de paleta y funciona como superficie de acento; usado como fondo
      general apagaba el azul y el naranja, que son los que cargan la marca.

   2. Los titulares van en Google Sans Flex con peso medio (500), no en
      negrita extrema. El manual titula así, y el peso 800 con tracking muy
      cerrado es justamente lo que hacía leer la página como una plantilla.

   3. La regla azul corta sobre cada título y el énfasis naranja dentro del
      titular son los dos gestos que se repiten en todo el sitio. Salen del
      diseño de Figma y son lo que hace reconocible la página de un vistazo.

   4. Hay dos familias de contenedor: la tarjeta blanca redondeada para
      contenido con jerarquía propia, y la grilla de hairlines (celdas
      blancas separadas por 1px) que replica la retícula de la lámina de
      elementos gráficos. La segunda es la que da el aire editorial.
   ═══════════════════════════════════════════════════════════════════════ */

/* ══════════ TIPOGRAFÍAS PROPIAS ══════════
   Auto-hospedadas desde los archivos del manual: el sitio no depende de
   Google Fonts. Ambas son variables, así que un solo archivo cubre todos
   los pesos (73 KB y 79 KB, subseteadas a latín). */
@font-face{
  font-family:'Google Sans Flex';
  src:url('assets/fonts/GoogleSansFlex-var.woff2') format('woff2');
  font-weight:1 1000; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'DM Sans';
  src:url('assets/fonts/DMSans-var.woff2') format('woff2');
  font-weight:100 1000; font-style:normal; font-display:swap;
}

:root{
  /* ── PALETA DEL MANUAL (valores exactos) ─────────────────────── */
  --navy:#00024F;
  --azul:#183EEB;
  --naranja:#EE4C01;
  --rosa:#FFD3AC;
  --beige:#F5EFE0;

  /* ── DERIVADOS ───────────────────────────────────────────────── */
  --azul-hover:#0E2BA8;
  --naranja-hover:#D14201;
  --lienzo:#F0F0F0;       /* fondo de página: el gris de las láminas */
  --blanco:#FFFFFF;
  --tile:#DCDCDC;         /* gris de los recuadros de icono          */

  --tinta:#0D0F1A;        /* titulares                               */
  --texto:#535A6B;        /* párrafos                                */
  --tenue:#8A90A0;        /* metadatos                               */
  --linea:#E2E2E4;        /* hairline de la retícula                 */
  --linea-fuerte:#CFCFD4;

  --sobre-oscuro-70:rgba(255,255,255,.74);
  --sobre-oscuro-45:rgba(255,255,255,.45);

  --display:'Google Sans Flex',ui-sans-serif,system-ui,sans-serif;
  --texto-font:'DM Sans',ui-sans-serif,system-ui,sans-serif;

  --r-sm:8px; --r-md:14px; --r-lg:20px; --r-xl:28px; --r-pill:99px;
  --sombra-sm:0 1px 2px rgba(13,15,26,.04),0 4px 12px rgba(13,15,26,.04);
  --sombra-md:0 2px 4px rgba(13,15,26,.04),0 16px 40px rgba(13,15,26,.07);
  --sombra-lg:0 4px 8px rgba(13,15,26,.05),0 32px 68px rgba(13,15,26,.11);
  --ease:cubic-bezier(.22,.61,.36,1);
  --maxw:1240px;
}

/* ══════════ BASE ══════════ */
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  font-family:var(--texto-font);
  background:var(--lienzo);
  color:var(--texto);
  font-size:1rem;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;display:block}
ul{list-style:none}
a{color:inherit;text-decoration:none}
button{font:inherit;cursor:pointer;border:none;background:none;color:inherit}
::selection{background:var(--azul);color:#fff}
:focus-visible{outline:2px solid var(--azul);outline-offset:3px;border-radius:2px}

.container{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 32px}
section{padding:112px 0;position:relative}
section.tight{padding:64px 0}
.surface{background:var(--blanco)}
.surface-soft{background:var(--beige)}
.bordered{border-top:1px solid var(--linea);border-bottom:1px solid var(--linea)}

/* ══════════ ICONOS ══════════
   Todos vienen del sprite inyectado al principio del <body>. */
.ico{width:1.5rem;height:1.5rem;flex:none;display:block}
.ico-sm{width:1.15rem;height:1.15rem}

/* Recuadro de icono: el tile gris del manual con el line-art adentro.
   El radio (12 sobre 60) reproduce la proporción de las láminas. */
.card-ico{
  width:60px;height:60px;border-radius:12px;background:var(--tile);
  display:grid;place-items:center;margin-bottom:24px;
}
.card-ico .ico{width:34px;height:34px}
.card-ico.azul{background:var(--azul)}
.card-ico.azul .ico{color:#fff}
.card-ico.beige{background:var(--beige)}
/* `warm` marca los bloques que describen el problema, el "antes". Va en
   rosa pálido para diferenciarlos de los bloques de solución sin cambiar
   el line-art, que sigue siendo el mismo del set. */
.card-ico.warm,.card-ico.rosa{background:var(--rosa)}

/* ══════════ TIPOGRAFÍA ══════════ */
h1,h2,h3,h4{
  font-family:var(--display);
  color:var(--tinta);
  font-weight:500;
  line-height:1.14;
  letter-spacing:-.021em;
  text-wrap:balance;
}
h1{font-size:clamp(2.5rem,4.9vw,4.05rem);line-height:1.08;letter-spacing:-.028em}
h2{font-size:clamp(1.85rem,3.1vw,2.85rem)}
h3{font-size:1.28rem;font-weight:600;line-height:1.25;letter-spacing:-.014em}
h4{font-size:1.05rem;font-weight:600;letter-spacing:-.01em}
p{color:var(--texto)}
strong,b{font-weight:600}

.lead{font-size:clamp(1.06rem,1.3vw,1.2rem);color:var(--texto);line-height:1.6;max-width:60ch}
.lead b{font-weight:600;color:var(--tinta)}
/* Una bajada pegada al título es el error más visible de la maqueta: los
   .sec-head ya separan, pero fuera de ellos (banda oscura, contacto) el
   párrafo quedaba contra la línea base del titular. */
h1+.lead,h2+.lead,h3+.lead,h1+p,h2+p{margin-top:20px}

/* Énfasis dentro del titular: el gesto central de la marca. */
.hl{color:var(--azul)}
.hl-o{color:var(--naranja)}
.dot{color:var(--naranja)}

/* Regla azul corta sobre el título: el segundo gesto que se repite en todo
   el sitio. Se dibuja como ::before del antetítulo en vez de pedir un
   elemento extra, así ninguna página tiene que acordarse de ponerla. */
.regla{display:block;width:44px;height:4px;background:var(--azul);margin-bottom:26px;border-radius:2px}
.regla.centro{margin-inline:auto}
.regla.naranja{background:var(--naranja)}

.eyebrow{
  display:block;font-family:var(--texto-font);
  font-size:.79rem;font-weight:600;letter-spacing:.15em;text-transform:uppercase;
  color:var(--azul);margin-bottom:14px;
}
.eyebrow::before{
  content:"";display:block;width:44px;height:4px;border-radius:2px;
  background:var(--azul);margin-bottom:22px;
}
.sec-head.center .eyebrow::before,.cta-final .eyebrow::before{margin-inline:auto}
.eyebrow.on-dark{color:#8CA0FF}
.eyebrow.on-dark::before,.dark-band .eyebrow::before{background:#6E86FF}
.eyebrow.naranja{color:var(--naranja)}
.eyebrow.naranja::before{background:var(--naranja)}

/* Gráfico de la lámina usado como marca de sección, por encima del
   antetítulo. Es decorativo: siempre va con aria-hidden. */
.marca-seccion{width:76px;height:auto;display:block;margin-bottom:22px}

.sec-head{max-width:46rem;margin-bottom:60px}
.sec-head.center{margin-inline:auto;text-align:center}
.sec-head .lead{margin-top:20px}
.sec-head.center .lead{margin-inline:auto}

/* ══════════ BOTONES ══════════
   El naranja es la acción principal en el cuerpo de la página; el azul es
   la acción de la barra de navegación. Así es en el diseño de Figma. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  font-family:var(--texto-font);font-weight:600;font-size:.97rem;line-height:1;
  padding:16px 28px;border-radius:var(--r-sm);border:1.5px solid transparent;
  white-space:nowrap;
  transition:transform .22s var(--ease),box-shadow .22s var(--ease),
             background .18s,color .18s,border-color .18s;
}
.btn .ico{width:1.15rem;height:1.15rem;transition:transform .22s var(--ease)}
.btn:hover{transform:translateY(-2px)}
.btn:hover .ico{transform:translateX(3px)}
.btn:active{transform:translateY(0)}
.btn:disabled{opacity:.55;cursor:wait;transform:none;pointer-events:none}

.btn-primary,.btn-accent{
  background:var(--naranja);color:#fff;
  box-shadow:0 6px 16px rgba(238,76,1,.26);
}
.btn-primary:hover,.btn-accent:hover{background:var(--naranja-hover);box-shadow:0 14px 30px rgba(238,76,1,.32)}
.btn-azul{background:var(--azul);color:#fff;box-shadow:0 6px 16px rgba(24,62,235,.24)}
.btn-azul:hover{background:var(--azul-hover);box-shadow:0 14px 30px rgba(24,62,235,.3)}
.btn-outline{border-color:var(--linea-fuerte);color:var(--tinta);background:var(--blanco)}
.btn-outline:hover{border-color:var(--tinta);box-shadow:var(--sombra-sm)}
.btn-quiet{background:var(--blanco);color:var(--tinta);border-color:var(--linea)}
.btn-quiet:hover{border-color:var(--azul);color:var(--azul);box-shadow:var(--sombra-sm)}
.btn-sm{padding:11px 20px;font-size:.9rem}
.dark-band .btn-outline,.on-dark .btn-outline,.footer .btn-outline{
  border-color:rgba(255,255,255,.4);color:#fff;background:transparent;
}
.dark-band .btn-outline:hover,.on-dark .btn-outline:hover{background:#fff;color:var(--navy)}

.actions{display:flex;gap:14px;flex-wrap:wrap;margin-top:36px}

/* Enlace con flecha: la flecha es el icono del set, no un carácter. */
.arrow-link{
  display:inline-flex;align-items:center;gap:9px;margin-top:20px;
  font-weight:600;font-size:.96rem;color:var(--azul);
  transition:gap .2s var(--ease);
}
.arrow-link .ico{width:1.05rem;height:1.05rem}
.arrow-link:hover{gap:14px;color:var(--azul-hover)}

/* ══════════ RECURSOS GRÁFICOS DE FONDO ══════════ */

/* Retícula de la lámina de elementos: hairlines cada 84px. Se usa como
   fondo de sección, siempre desvanecida hacia los bordes para que no
   compita con el texto. */
.rejilla{position:relative;isolation:isolate;--celda:84px}
.rejilla::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(to right,var(--linea) 1px,transparent 1px),
    linear-gradient(to bottom,var(--linea) 1px,transparent 1px);
  background-size:var(--celda) var(--celda);
  -webkit-mask-image:radial-gradient(ellipse 78% 68% at 50% 42%,#000 30%,transparent 78%);
  mask-image:radial-gradient(ellipse 78% 68% at 50% 42%,#000 30%,transparent 78%);
}

/* Halo naranja: la mancha de color que aparece sangrando en los bordes
   del diseño de Figma. */
.halo{
  position:absolute;border-radius:50%;pointer-events:none;z-index:0;
  background:radial-gradient(circle,rgba(238,76,1,.42) 0%,rgba(238,76,1,.10) 48%,transparent 70%);
  filter:blur(4px);
}
.halo.azul{background:radial-gradient(circle,rgba(24,62,235,.30) 0%,rgba(24,62,235,.07) 48%,transparent 70%)}

/* ══════════ NAVBAR ══════════ */
.nav{
  position:sticky;top:0;z-index:100;background:rgba(255,255,255,.92);
  backdrop-filter:saturate(180%) blur(14px);
  -webkit-backdrop-filter:saturate(180%) blur(14px);
  border-bottom:1px solid var(--linea);
}
.nav-row{display:flex;align-items:center;gap:26px;height:78px}

/* El logo es SVG en línea: hereda el color del texto y funciona sobre
   cualquier fondo. El PNG anterior traía fondo blanco opaco y por eso
   había que enmascararlo con recuadros. */
.brand{display:flex;align-items:center;flex:none;color:var(--tinta)}
.brand .logo{height:29px;width:auto;display:block}
/* El logo se dibuja con <use> desde el sprite, y <use> arma un subárbol
   que los selectores de descendencia no atraviesan: una regla como
   `.footer .logo-simbolo{fill:#fff}` no llega al path. Lo que sí entra es
   la herencia, así que la palabra usa currentColor y el símbolo una
   variable propia. Sobre fondo oscuro se reversa cambiando las dos. */
.footer .brand,.dark-band .brand{color:#fff;--tinta-simbolo:#fff}

.nav-menu{display:flex;align-items:center;gap:2px;margin-left:auto}
/* :not(.nav-cta) es imprescindible: el CTA vive dentro del menú y sin la
   exclusión estas reglas le pisan el color al botón. */
.nav-menu>a:not(.nav-cta),.nav-drop>button{
  display:flex;align-items:center;gap:7px;padding:10px 15px;border-radius:var(--r-sm);
  font-size:.95rem;font-weight:500;color:var(--texto);
  transition:color .18s,background .18s;position:relative;
}
.nav-menu>a:not(.nav-cta):hover,.nav-drop>button:hover{color:var(--azul);background:rgba(24,62,235,.05)}
.nav-menu>a:not(.nav-cta).active,.nav-drop.active>button{color:var(--tinta);font-weight:600}
.nav-menu>a:not(.nav-cta).active::after,.nav-drop.active>button::after{
  content:"";position:absolute;left:15px;right:15px;bottom:0;height:3px;
  border-radius:2px;background:var(--azul);
}
.caret{width:.62rem;height:.62rem;color:var(--tenue);transition:transform .2s}
.nav-drop{position:relative}
.nav-drop:hover .caret,.nav-drop.open .caret{transform:rotate(180deg)}

.pill-ia{
  font-size:.6rem;font-weight:700;letter-spacing:.1em;padding:3px 7px;border-radius:4px;
  background:var(--azul);color:#fff;
}

.dropdown{
  position:absolute;top:calc(100% + 12px);left:-10px;min-width:390px;padding:10px;
  background:var(--blanco);border:1px solid var(--linea);border-radius:var(--r-md);
  box-shadow:var(--sombra-lg);opacity:0;visibility:hidden;transform:translateY(-8px);
  transition:all .22s var(--ease);
}
.nav-drop:hover .dropdown,.nav-drop.open .dropdown{opacity:1;visibility:visible;transform:translateY(0)}
.dropdown a{display:flex;gap:14px;padding:13px;border-radius:var(--r-sm);transition:background .16s}
.dropdown a:hover{background:var(--lienzo)}
.dropdown .di{
  width:42px;height:42px;flex:none;border-radius:10px;background:var(--tile);
  display:grid;place-items:center;
}
.dropdown .di .ico{width:24px;height:24px}
.dropdown b{display:block;font-size:.95rem;color:var(--tinta);font-weight:600}
.dropdown small{display:block;font-size:.83rem;color:var(--tenue);line-height:1.45;margin-top:2px}
.nav-cta{flex:none;margin-left:10px}
.burger{
  display:none;margin-left:auto;padding:8px;border:1px solid var(--linea-fuerte);
  border-radius:var(--r-sm);color:var(--tinta);
}
.burger .ico{width:1.3rem;height:1.3rem}

/* ══════════ HERO ══════════ */
.hero{padding:96px 0 104px;position:relative;overflow:hidden}
.hero .halo.uno{width:520px;height:520px;top:-120px;right:-180px}
.hero .halo.dos{width:280px;height:280px;bottom:-120px;left:-120px}

/* ── Los degradados siguen al puntero ──
   El naranja va hacia donde está el cursor y el azul hacia el punto opuesto
   del hero, así que entre los dos recorren toda la superficie. El JS mide
   una sola vez dónde queda cada halo en reposo y después sólo lo desplaza,
   de manera que sin JS la composición queda exactamente como está escrita
   acá y no hace falta duplicar las posiciones en dos lugares.
   Se anima `translate` y no `top/left`: son manchas enormes y desenfocadas,
   y mover la caja dispararía layout en cada cuadro. */
.hero .halo,.hero-inner .halo{transition:translate .34s var(--ease);will-change:translate}
.hero .halo.uno,.hero-inner .halo.uno{translate:var(--dx,0px) var(--dy,0px)}
.hero .halo.dos,.hero-inner .halo.dos{translate:var(--mx,0px) var(--my,0px)}
@media(prefers-reduced-motion:reduce){
  .hero .halo,.hero-inner .halo{transition:none;translate:none}
}
.hero-grid{display:grid;grid-template-columns:1.04fr .96fr;gap:64px;align-items:center;position:relative;z-index:1}
.hero h1{margin-bottom:26px}
.hero .lead{max-width:52ch}

/* ══════════ ENTRADA DEL TITULAR ══════════
   Cada palabra sube desde su propia línea con el foco resolviéndose, en
   cascada, y una hairline de barrido baja por el bloque: la lectura se arma
   sola, como una pantalla que termina de sincronizar.

   El desenfoque va en la palabra y el recorte en su envoltorio: si el mismo
   elemento llevara filter y overflow, el filtro crearía un contexto nuevo y
   el recorte dejaría de morder el desplazamiento.

   La estructura la arma el JS (ver main.js), igual que la clase .titulo-tec:
   si el script no corre no hay nada oculto y el titular se lee tal como está
   escrito en el HTML. */
.titulo-tec{position:relative}
.titulo-tec .pal{
  display:inline-block;overflow:hidden;
  /* Sin este colchón el recorte le corta la cola a la g y a la j. */
  padding-bottom:.14em;margin-bottom:-.14em;
}
.titulo-tec .pal-i{display:inline-block;transform:translateY(105%);opacity:0}
.titulo-tec.entra .pal-i{
  animation:tituloPalabra .72s cubic-bezier(.16,1,.3,1) both;
  animation-delay:var(--d,0ms);
}
@keyframes tituloPalabra{
  from{transform:translateY(105%);opacity:0;filter:blur(7px)}
  to{transform:none;opacity:1;filter:blur(0)}
}
/* Barrido: una hairline naranja→azul que recorre el titular una sola vez. */
.titulo-tec.entra::after{
  content:"";position:absolute;left:-2%;right:-2%;top:0;height:2px;
  background:linear-gradient(90deg,transparent,var(--naranja) 22%,var(--azul) 78%,transparent);
  animation:tituloBarrido .95s cubic-bezier(.33,0,.2,1) both;
  pointer-events:none;
}
@keyframes tituloBarrido{
  0%{opacity:0;transform:translateY(0) scaleX(.7)}
  18%{opacity:.95;transform:translateY(18%) scaleX(1)}
  100%{opacity:0;transform:translateY(100%) scaleX(1)}
}
@media(prefers-reduced-motion:reduce){
  .titulo-tec .pal-i{transform:none;opacity:1}
  .titulo-tec.entra .pal-i{animation:none}
  .titulo-tec.entra::after{display:none}
}


.hero-badge{
  display:inline-flex;align-items:center;gap:10px;padding:8px 16px 8px 10px;
  border-radius:var(--r-pill);background:var(--blanco);border:1px solid var(--linea);
  font-size:.85rem;font-weight:500;color:var(--texto);margin-bottom:28px;
  box-shadow:var(--sombra-sm);
}
.hero-badge .ico{width:1.1rem;height:1.1rem;color:var(--azul)}
.hero-badge b{color:var(--tinta);font-weight:600}

/* ── Diagrama del ecosistema (hero) ──
   Diez sistemas en dos anillos. Los anillos giran en sentidos opuestos y
   cada píldora contrarrota con la misma duración: orbita, pero su texto se
   mantiene siempre derecho. Sin la contrarrotación las etiquetas darían
   vueltas sobre sí mismas y no habría forma de leerlas. */
.orbe{position:relative;width:100%;aspect-ratio:1;max-width:470px;margin-inline:auto}

/* Guías: sólo dibujan las dos órbitas, no giran.
   El aro va en degradado naranja→azul como el resto del set gráfico. Un
   border no admite degradado, así que se pinta el fondo y se recorta el
   relleno con mask-composite: queda un aro de grosor constante que sigue la
   curva sin importar el tamaño del círculo. */
.orbe-guia{
  position:absolute;left:50%;top:50%;translate:-50% -50%;border-radius:50%;
  pointer-events:none;padding:1.4px;opacity:.5;
  background:linear-gradient(170deg,var(--naranja),var(--azul));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
}
.orbe-guia.externa{width:100%;height:100%}
.orbe-guia.interna{width:60%;height:60%}

/* ── Núcleo: la nube en malla ──
   Sin disco, sin marco y sin fondo: la nube se apoya directamente sobre la
   retícula del hero. Ancha como es, manda el ancho y no el alto. */
.orbe-nucleo{
  position:absolute;left:50%;top:50%;translate:-50% -50%;
  width:46%;display:grid;place-items:center;z-index:3;
}
.orbe-nucleo .nube{width:100%;height:auto;overflow:visible}

/* ── Conexiones internas ──
   Lo único que se mueve son las aristas: cada una se traza de un nodo al otro,
   se sostiene un momento y se retira por el extremo opuesto, así que la red
   interior se rearma sola en configuraciones distintas. Antes lo que corría
   eran pulsos cortos sobre una malla fija; ahora la malla misma es la que
   cambia, y los nodos quedan quietos para que la lectura sea la conexión.

   El dibujado usa pathLength="1" en cada línea (está en el marcado): con el
   largo normalizado a 1, un dasharray de 1 cubre cualquier arista sin tener
   que medir su longitud real, que es lo que obligaría a calcularlas en JS.
   Llevar el desfase de 0 a -1 continúa el barrido en la misma dirección: la
   conexión se retira por donde iba, en lugar de desdibujarse hacia atrás. */
/* La malla queda quieta y tenue: es la estructura. */
.nube-malla line{opacity:.32}

/* ── Pulsos ──
   Sobre cada hilo corre un trazo corto: es la copia de la malla recortada a
   un guion de 16 unidades seguido de un hueco enorme, y lo que se anima es el
   corrimiento del patrón. Da tráfico circulando por la red sin necesidad de
   medir el largo real de cada segmento, porque el hueco siempre supera al
   más largo. Cada hilo arranca en un momento distinto para que nunca se vean
   todos alineados. */
.nube-pulsos line{
  stroke-dasharray:16 320;
  stroke-dashoffset:336;
  animation:nubePulso 3.4s linear infinite;
  opacity:.95;
}
@keyframes nubePulso{to{stroke-dashoffset:0}}
.nube-pulsos line:nth-child(4n+1){animation-duration:4.1s;animation-delay:-.6s}
.nube-pulsos line:nth-child(4n+2){animation-duration:3.1s;animation-delay:-1.9s}
.nube-pulsos line:nth-child(4n+3){animation-duration:4.6s;animation-delay:-2.7s}
.nube-pulsos line:nth-child(4n){animation-duration:3.7s;animation-delay:-1.2s}

/* Los nodos respiran en el lugar. transform-box:fill-box pone el origen en el
   centro del círculo; sin eso escalarían alrededor del vértice del lienzo. */
.nube-nodos circle{
  transform-box:fill-box;transform-origin:center;
  animation:nubeNodo 4.4s ease-in-out infinite;
  transition:r .3s var(--ease);
}
.nube-nodos circle:nth-child(2n){animation-duration:5.6s;animation-delay:-1.1s}
.nube-nodos circle:nth-child(3n){animation-duration:6.2s;animation-delay:-2.4s}
@keyframes nubeNodo{50%{scale:1.22}}

.nube-borde{filter:drop-shadow(0 2px 7px rgba(24,62,235,.14))}

/* Al apuntar la nube, la malla se enciende, los pulsos aceleran y los nodos
   crecen: responde como una sola pieza en vez de nodo por nodo. */
.orbe-nucleo:hover .nube-malla line{opacity:.75}
.orbe-nucleo:hover .nube-pulsos line{animation-duration:1.3s}
.orbe-nucleo:hover .nube-nodos circle{r:6}
.orbe-nucleo:hover .nube-borde{filter:drop-shadow(0 2px 12px rgba(238,76,1,.32))}

@media(prefers-reduced-motion:reduce){
  .nube-pulsos{display:none}
  .nube-nodos circle{animation:none}
  .nube-malla line{opacity:.5}
}

.orbe-anillo{
  position:absolute;left:50%;top:50%;translate:-50% -50%;border-radius:50%;
  will-change:rotate;
}
.orbe-anillo.externo{width:100%;height:100%;animation:orbe-ccw 76s linear infinite}
.orbe-anillo.interno{width:60%;height:60%;animation:orbe-cw 52s linear infinite}

/* La posición sobre el anillo sale del ángulo que declara cada ítem */
.orbe-item{
  position:absolute;
  left:calc(50% + 50% * cos(var(--a)));
  top:calc(50% + 50% * sin(var(--a)));
  translate:-50% -50%;
}
.orbe-item span{
  display:block;white-space:nowrap;
  background:var(--blanco);border:1px solid var(--linea);border-radius:var(--r-pill);
  padding:9px 17px;font-size:.83rem;font-weight:600;color:var(--tinta);
  box-shadow:0 4px 16px rgba(13,15,26,.08);
  transition:border-color .22s,color .22s,box-shadow .22s;
}
.orbe-item span:hover{border-color:var(--azul);color:var(--azul);box-shadow:0 8px 22px rgba(24,62,235,.2)}
/* Contrarrotación: misma duración que su anillo, sentido opuesto */
.orbe-anillo.externo .orbe-item span{animation:orbe-cw 76s linear infinite}
.orbe-anillo.interno .orbe-item span{animation:orbe-ccw 52s linear infinite}

@keyframes orbe-cw{to{rotate:360deg}}
@keyframes orbe-ccw{to{rotate:-360deg}}

/* Bajada al contenido: punto naranja + flecha */
.orbe-baja{display:flex;flex-direction:column;align-items:center;gap:6px;margin-top:26px;color:var(--tinta)}
.orbe-baja i{width:9px;height:9px;border-radius:50%;background:var(--naranja);display:block}
.orbe-baja svg{width:22px;height:34px}

@media(max-width:640px){
  .orbe-item span{font-size:.72rem;padding:7px 12px}
  .orbe-nucleo{width:30%}
}
@media(prefers-reduced-motion:reduce){
  .orbe-anillo,.orbe-item span{animation:none}
}

/* Hero de páginas internas */
.hero-inner{padding:88px 0 76px;position:relative;overflow:hidden}
.hero-inner .halo.uno{width:480px;height:480px;top:-190px;right:-150px}
.hero-inner .halo.dos{width:300px;height:300px;bottom:-150px;left:-110px}
.crumbs{font-size:.85rem;color:var(--tenue);margin-bottom:24px;display:flex;gap:9px;align-items:center;flex-wrap:wrap}
.crumbs a:hover{color:var(--azul)}

/* ══════════ CLIENTES (marquesina) ══════════ */
.trust-banner{background:var(--blanco);border-top:1px solid var(--linea);border-bottom:1px solid var(--linea)}
.trust-eyebrow{
  display:block;text-align:center;font-size:.79rem;font-weight:600;text-transform:uppercase;
  letter-spacing:.15em;color:var(--azul);margin-bottom:.5rem;
}
.trust-title{
  text-align:center;font-family:var(--display);font-weight:500;
  font-size:clamp(1.6rem,2.5vw,2.1rem);color:var(--tinta);margin-bottom:2.5rem;letter-spacing:-.02em;
}
.trust-marquee{
  position:relative;width:100%;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.trust-track{display:flex;width:max-content;animation:marquesina 58s linear infinite;will-change:transform}
.trust-marquee:hover .trust-track{animation-play-state:paused}
.trust-logos{display:flex;align-items:center;gap:3.75rem;padding:.5rem 1.875rem}
/* Los logos van en color, como en el diseño: son marcas ajenas y en gris
   pierden la carga de credibilidad que aportan. La opacidad apenas por
   debajo de 1 los asienta sobre el fondo sin apagarlos. */
.trust-logos img{
  height:64px;width:auto;max-width:186px;object-fit:contain;
  opacity:.92;transition:opacity .3s ease,transform .3s var(--ease);
}
.trust-logos img:hover{opacity:1;transform:scale(1.04)}
@keyframes marquesina{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){
  .trust-track{animation:none;flex-wrap:wrap;justify-content:center;width:100%;max-width:1100px;margin:0 auto}
  .trust-logos{flex-wrap:wrap;justify-content:center}
  .trust-logos:last-child{display:none}
  .trust-marquee{-webkit-mask-image:none;mask-image:none}
}

/* ══════════ MÉTRICAS ══════════ */
.stats-band{background:var(--navy);color:#fff;position:relative;overflow:hidden}
/* Resplandor de reposo: el que ya estaba, siempre presente. */
.stats-band::before{
  content:"";position:absolute;top:-60%;left:8%;width:560px;height:560px;pointer-events:none;
  background:radial-gradient(circle,rgba(24,62,235,.55) 0%,transparent 66%);
}
/* Haz que acompaña al puntero. Va como capa aparte de la de reposo para
   que el fondo no cambie cuando no hay nadie encima.
   Se mueve con `translate` y no con la posición del degradado: la posición
   de un radial-gradient no es animable, así que seguiría al cursor a los
   saltos. Con translate hay transición y el haz arrastra apenas detrás,
   que es lo que lo hace leer como luz y no como cursor. */
.stats-band::after{
  content:"";position:absolute;top:0;left:0;width:540px;height:540px;
  margin:-270px 0 0 -270px;pointer-events:none;opacity:0;
  translate:var(--mx,50%) var(--my,50%);
  background:radial-gradient(circle,rgba(24,62,235,.62) 0%,rgba(24,62,235,.14) 45%,transparent 68%);
  transition:translate .55s var(--ease),opacity .45s ease;
  will-change:translate;
}
.stats-band.iluminado::after{opacity:1}

.stats-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:32px;position:relative}
.stat{transition:opacity .35s ease}
/* Al enfocar una cifra, las otras ceden. Si el navegador no soporta :has()
   simplemente no atenúa: el resto del efecto sigue funcionando. */
.stats-grid:has(.stat:hover) .stat{opacity:.5}
.stats-grid .stat:hover{opacity:1}
.stat b{
  display:block;font-family:var(--display);font-size:clamp(2.5rem,4vw,3.4rem);font-weight:500;
  letter-spacing:-.035em;color:var(--naranja);line-height:1;margin-bottom:12px;
  /* Cifras de ancho fijo: durante el conteo el número cambia de dígitos y
     sin esto el texto vibra de izquierda a derecha. */
  font-variant-numeric:tabular-nums;
  transition:text-shadow .35s ease;
}
.stat:hover b{text-shadow:0 0 30px rgba(238,76,1,.55)}
.stat span{color:var(--sobre-oscuro-70);font-size:.95rem;line-height:1.45;display:block}

@media(prefers-reduced-motion:reduce){
  .stats-band::after{display:none}
  .stat,.stat b{transition:none}
}

/* ══════════ GRILLAS ══════════ */
.grid{display:grid;gap:24px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}

/* ══════════ TARJETAS ══════════ */
/* Columna flexible para que el enlace de cierre se apoye en el pie de la
   tarjeta: con textos de largo distinto, las flechas quedaban a tres
   alturas diferentes y la fila perdía la línea. */
.card{
  background:var(--blanco);border:1px solid var(--linea);border-radius:var(--r-lg);
  padding:34px;position:relative;display:flex;flex-direction:column;
  transition:transform .3s var(--ease),box-shadow .3s var(--ease),border-color .3s;
}
.card .arrow-link{margin-top:auto;padding-top:22px;align-self:flex-start}
.card:hover{transform:translateY(-4px);box-shadow:var(--sombra-md);border-color:var(--linea-fuerte)}
/* El título de tarjeta va en azul: es así en el diseño de Figma y separa
   con claridad el nivel de tarjeta del nivel de sección. */
.card h3{color:var(--azul);margin-bottom:12px}
.card h4{color:var(--azul);margin-bottom:10px}
.card p{font-size:.97rem;line-height:1.62}

/* Icono embebido en un h3: sube al renglón de arriba en vez de empujar
   el texto, para que el título no pierda su línea base. */
.h3-ico{display:block;margin-bottom:16px}
.h3-ico .ico{width:32px;height:32px}

.kicker{
  display:block;font-size:.72rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--tenue);margin-bottom:10px;
}
.kicker.warm{color:var(--naranja)}

/* ── Destacado: anillo degradado ──
   El borde degradado se dibuja como un anillo que envuelve la tarjeta
   completa, no como una franja apoyada arriba. La franja anterior se
   posicionaba en top/left/right:0, que en un absolute se resuelve contra el
   padding box: quedaba 1px adentro del borde y con el radio de 20px
   colapsado en 4px de alto, así que se leía corrida en las esquinas.

   El anillo va en inset:-1px para tapar el borde de 1px de .card y su radio
   compensa ese píxel, de modo que las curvas coinciden exactamente. El truco
   del relleno recortado (padding + mask-composite:exclude) deja pasar sólo
   la banda del degradado: un contorno de grosor constante que sigue la
   esquina redondeada sin importar el alto de la tarjeta. */
.card.feature{border-color:transparent;box-shadow:0 12px 34px rgba(24,62,235,.12)}
.card.feature::before{
  content:"";position:absolute;inset:-1px;border-radius:calc(var(--r-lg) + 1px);
  padding:1.5px;pointer-events:none;
  background:linear-gradient(115deg,var(--azul),var(--naranja));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  transition:padding .3s var(--ease),opacity .3s var(--ease);
}
/* Al pasar el cursor el anillo engorda desde el mismo eje, así que sigue
   apoyado en el contorno en vez de desbordarlo. */
.card.feature:hover{border-color:transparent}
.card.feature:hover::before{padding:2.5px}
@media (prefers-reduced-motion:reduce){
  .card.feature::before{transition:none}
}

/* ── Grilla de hairlines ──
   Celdas blancas separadas por 1px sobre el color de línea: es la
   retícula de la lámina de elementos gráficos, aplicada al contenido.
   Sin sombras ni radios: la estructura la da la línea. */
.grid-reticula{
  display:grid;gap:1px;background:var(--linea);
  border:1px solid var(--linea);border-radius:var(--r-lg);overflow:hidden;
}
.grid-reticula.g2{grid-template-columns:repeat(2,1fr)}
.grid-reticula.g3{grid-template-columns:repeat(3,1fr)}
.grid-reticula.g4{grid-template-columns:repeat(4,1fr)}
.grid-reticula>*{
  background:var(--blanco);padding:38px 32px;margin:0;border:none;border-radius:0;
  transition:background .28s var(--ease);
}
.grid-reticula>*:hover{background:#FAFAFB;transform:none;box-shadow:none}
.grid-reticula .card{box-shadow:none}

.tags{display:flex;flex-wrap:wrap;gap:7px;margin-top:22px}
.tag{
  font-size:.75rem;font-weight:600;padding:5px 12px;border-radius:var(--r-pill);
  background:var(--lienzo);border:1px solid var(--linea);color:var(--texto);
}
.tag.solid{background:var(--navy);color:#fff;border-color:var(--navy)}
.meta{
  display:block;margin-top:20px;padding-top:18px;border-top:1px solid var(--linea);
  font-size:.83rem;color:var(--tenue);
}
.meta b{color:var(--texto);font-weight:600}

/* ── Listas con tilde ──
   El tilde es el patrón de puntos del manual, no un check tipográfico. */
.checks{margin-top:22px}
.checks li{position:relative;padding:9px 0 9px 34px;font-size:.97rem;color:var(--texto);line-height:1.55}
.checks li::before{
  content:"";position:absolute;left:0;top:12px;width:20px;height:20px;
  background:
    radial-gradient(circle 2px at 4px 10px,var(--naranja) 99%,transparent) ,
    radial-gradient(circle 2px at 8px 14px,var(--naranja) 99%,transparent),
    radial-gradient(circle 2px at 12px 9px,var(--naranja) 99%,transparent),
    radial-gradient(circle 2px at 16px 4px,var(--naranja) 99%,transparent);
}
.checks li b{color:var(--tinta);font-weight:600}
/* Variante neutra: para listas que describen el "antes", donde un tilde
   naranja leería como algo positivo. */
.checks.neutral li::before{
  background:none;top:20px;left:2px;width:12px;height:2px;border-radius:1px;
  background-color:var(--linea-fuerte);
}

/* ══════════ TABS ══════════ */
.tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:40px}
.tab{
  padding:12px 22px;border-radius:var(--r-sm);border:1px solid var(--linea);
  background:var(--blanco);font-size:.93rem;font-weight:600;color:var(--texto);
  transition:all .22s var(--ease);
}
.tab:hover{border-color:var(--azul);color:var(--azul)}
.tab.active{background:var(--navy);border-color:var(--navy);color:#fff}
.panel{display:none;animation:aparecer .4s var(--ease)}
.panel.active{display:block}
@keyframes aparecer{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* Filtros del catálogo */
.filters{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:36px}
.filter{
  padding:10px 18px;border-radius:var(--r-pill);border:1px solid var(--linea);
  background:var(--blanco);font-size:.9rem;font-weight:600;color:var(--texto);
  transition:all .2s var(--ease);
}
.filter:hover{border-color:var(--azul);color:var(--azul)}
.filter.active{background:var(--azul);border-color:var(--azul);color:#fff}

/* ══════════ BANDA OSCURA ══════════ */
.dark-band{
  background:linear-gradient(150deg,#0B1A6E 0%,var(--navy) 62%);
  color:#fff;border-radius:var(--r-xl);padding:68px;
  position:relative;overflow:hidden;
}
.dark-band::before{
  content:"";position:absolute;top:-45%;right:-8%;width:600px;height:600px;pointer-events:none;
  background:radial-gradient(circle,rgba(24,62,235,.6) 0%,transparent 66%);
}
.dark-band>*{position:relative}
.dark-band h2,.dark-band h3,.dark-band h4{color:#fff}
.dark-band .card h3,.dark-band .card h4{color:#9FB2FF}
.dark-band p,.dark-band .lead{color:var(--sobre-oscuro-70)}
.dark-band .tag{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.2);color:#fff}
.dark-band .card{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.14)}
.dark-band .card:hover{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.26)}
.dark-band .card p{color:var(--sobre-oscuro-70)}
.dark-band .checks li{color:var(--sobre-oscuro-70)}
.dark-band .checks li b{color:#fff}
.dark-band .kicker{color:var(--sobre-oscuro-45)}

/* ── Cifras de caso ──
   Una tira de celdas separadas por hairlines, apoyada en una línea superior:
   las cifras dejan de flotar sueltas sobre el texto y se leen como un bloque
   de datos. La etiqueta iba en el blanco de fondo oscuro, que es de donde
   viene este componente; sobre tarjeta clara quedaba invisible, así que el
   color por defecto es el de metadato y el blanco pasó a ser la excepción
   dentro de .dark-band. */
/* Una sola fila de celdas iguales, sin importar si son dos o tres: con flex y
   wrap, la que no entraba caía sola a un segundo renglón arrastrando su
   separador, y ese borde huérfano era justo lo que se veía desprolijo.
   grid-auto-columns reparte el ancho entre las que haya. */
.kpi-row{
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);
  margin-top:34px;border-top:1px solid var(--linea);
}
.kpi{
  padding:20px 18px 2px;
  border-left:1px solid var(--linea);
  position:relative;min-width:0;
  /* La celda es el contenedor contra el que se mide la cifra. */
  container:cifra / inline-size;
}
/* La primera celda pierde el separador pero conserva el padding: si se lo
   sacáramos para alinear la cifra con el párrafo, esa celda quedaría más ancha
   que las otras dos y, como el cuerpo de la cifra se mide contra su celda,
   la primera cifra saldría más grande que sus hermanas. */
.kpi:first-child{border-left:0}
.kpi b{
  display:block;font-family:var(--display);font-weight:500;
  /* El cuerpo se mide contra el ancho de su propia celda y no del viewport: es
     la celda la que puede quedar angosta, y con vw una cifra como
     "+$1.000 M" se pasaba de largo y se cortaba. El coeficiente está elegido
     para que la más ancha del sitio entre completa incluso en la celda más
     chica. */
  font-size:clamp(1.15rem,16.5cqi,2.05rem);
  letter-spacing:-.035em;line-height:1.1;white-space:nowrap;
  /* El degradado del manual, aplicado a la propia cifra. */
  background:linear-gradient(155deg,var(--naranja),var(--azul));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.kpi span{
  display:block;margin-top:8px;font-size:.82rem;line-height:1.45;color:var(--tenue);
}
/* La cifra se levanta apenas al apuntarla y la celda se tiñe: da a entender
   que el dato es el protagonista sin necesidad de agrandar nada. */
.kpi::before{
  content:"";position:absolute;left:0;top:-1px;width:0;height:2px;
  background:linear-gradient(90deg,var(--naranja),var(--azul));
  transition:width .45s var(--ease);
}
.kpi:hover::before{width:100%}
.kpi b{transition:translate .35s var(--ease)}
.kpi:hover b{translate:0 -2px}

.dark-band .kpi-row{border-top-color:rgba(255,255,255,.16)}
.dark-band .kpi{border-left-color:rgba(255,255,255,.16)}
.dark-band .kpi span{color:var(--sobre-oscuro-70)}
/* Sobre navy el extremo azul del degradado se apaga: se cambia por la rampa
   cálida de la paleta, que sí contrasta.
   Va como background-image y no como el atajo background: el atajo repone
   background-clip en border-box, y con la cifra en color:transparent el
   degradado se pintaría en la caja en vez de en las letras, o sea texto
   invisible. */
.dark-band .kpi b{background-image:linear-gradient(155deg,#FF7A3C,var(--rosa))}

/* Debajo de cierto ancho tres cifras en fila no entran, y el corte no depende
   del tamaño de la ventana sino del de la tarjeta que las contiene: la misma
   tarjeta va a media pantalla en el escritorio y entera en el teléfono. Por eso
   la consulta es de contenedor y no de medio. El @media que sigue cubre lo
   mismo en navegadores sin soporte. */
.card,.dark-band{container:tarjeta / inline-size}
@container tarjeta (max-width:430px){
  .kpi-row{grid-auto-flow:row}
  .kpi{border-left:0;padding:16px 0 2px;border-top:1px solid var(--linea)}
  .kpi:first-child{border-top:0;padding-top:20px}
}
@media(max-width:640px){
  .kpi-row{grid-auto-flow:row}
  .kpi{border-left:0;padding:16px 0 2px;border-top:1px solid var(--linea)}
  .kpi:first-child{border-top:0;padding-top:20px}
  .dark-band .kpi{border-top-color:rgba(255,255,255,.16)}
}
@media(prefers-reduced-motion:reduce){
  .kpi::before{transition:none}
  .kpi:hover b{translate:none}
}

.pull-quote{
  text-align:center;max-width:56rem;margin-inline:auto;font-family:var(--display);
  font-size:clamp(1.3rem,2.3vw,1.95rem);font-weight:500;line-height:1.35;
  letter-spacing:-.024em;color:var(--tinta);
}
.pull-quote .mark{color:var(--naranja)}

/* ══════════ PASOS ══════════ */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--linea);
  border:1px solid var(--linea);border-radius:var(--r-lg);overflow:hidden}
.steps.four{grid-template-columns:repeat(4,1fr)}
.step{background:var(--blanco);padding:40px 34px;position:relative;transition:background .28s var(--ease)}
.step:hover{background:#FAFAFB}
/* Flecha punteada entre pasos, sobre la línea que separa las celdas: el
   disco blanco la abre como una muesca en la retícula en vez de taparla. */
.paso-flecha{
  position:absolute;right:-18px;top:50%;translate:0 -50%;z-index:2;
  width:36px;height:36px;border-radius:50%;background:var(--blanco);
  display:grid;place-items:center;color:var(--naranja);
}
.paso-flecha .ico{width:24px;height:24px}
.steps .step:last-child .paso-flecha{display:none}

.step .n{
  font-family:var(--display);font-size:2.5rem;font-weight:500;letter-spacing:-.04em;
  color:var(--tile);line-height:1;margin-bottom:22px;display:block;
}
.step:hover .n{color:var(--naranja)}
.step h3{margin-bottom:11px;color:var(--tinta)}
.step p{font-size:.95rem}

/* ══════════ FLUJO HORIZONTAL ══════════ */
.flow{
  display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--linea);
  border:1px solid var(--linea);border-radius:var(--r-lg);overflow:hidden;
}
.flow-cell{padding:32px 28px;background:var(--blanco);position:relative}
.flow-cell .fn{
  display:inline-block;font-size:.7rem;font-weight:700;letter-spacing:.13em;
  color:var(--naranja);margin-bottom:14px;
}
.flow-cell b{display:block;font-family:var(--display);font-size:1.06rem;font-weight:600;margin-bottom:8px;color:var(--tinta)}
.flow-cell p{font-size:.9rem;line-height:1.55}

/* ══════════ DIAGRAMA DE CAPAS ══════════ */
.layers{display:flex;flex-direction:column;align-items:center;gap:0}
.layer{
  width:100%;background:var(--blanco);border:1px solid var(--linea);border-radius:var(--r-md);
  padding:24px 30px;display:flex;align-items:center;gap:22px;flex-wrap:wrap;
  transition:border-color .25s,box-shadow .25s;
}
.layer:hover{border-color:var(--linea-fuerte);box-shadow:var(--sombra-sm)}
.layer-label{min-width:270px}
.layer-label small{
  display:block;font-size:.7rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--azul);margin-bottom:5px;
}
.layer-label b{font-family:var(--display);font-size:1.06rem;font-weight:600;color:var(--tinta)}
.layer .tags{margin:0;margin-left:auto}
.layer.core{
  background:var(--navy);border-color:var(--navy);justify-content:center;
  text-align:center;padding:30px;position:relative;overflow:hidden;
}
.layer.core::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(circle at 50% 0%,rgba(24,62,235,.6) 0%,transparent 62%);
}
.layer.core div{position:relative}
.layer.core b{color:#fff;font-size:1.15rem;letter-spacing:.02em;display:block}
.layer.core small{color:var(--sobre-oscuro-70);font-size:.86rem;letter-spacing:0;text-transform:none;font-weight:400}
.connector{width:1.5px;height:24px;background:linear-gradient(var(--linea-fuerte),var(--azul))}

/* ══════════ EXPLORADOR DEL ECOSISTEMA (Productos) ══════════
   Diagrama compacto como selector + panel de detalle al lado. La geometría
   sale de un único ángulo por nodo: CSS calcula la posición con cos()/sin()
   sobre los radios --rx/--ry, así que reencuadrar es cambiar dos valores. */
.eco-explorer{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,380px);gap:52px;align-items:center}

.eco-stage{--rx:29%;--ry:29%;position:relative;width:100%;max-width:620px;aspect-ratio:1;margin:0 auto}
.eco-ring{
  position:absolute;left:50%;top:50%;translate:-50% -50%;border-radius:50%;
  pointer-events:none;transform-origin:center;
}
.eco-ring.r-in{
  width:calc(var(--rx) * 2);height:calc(var(--ry) * 2);
  border:1.5px dashed rgba(238,76,1,.5);animation:girar 90s linear infinite;
}
.eco-ring.r-out{
  width:calc(var(--rx) * 2.7);height:calc(var(--ry) * 2.7);
  border:1.5px dashed rgba(13,15,26,.22);animation:girar-inv 140s linear infinite;
}
.eco-svg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:1}
.eco-link{
  stroke:var(--azul);opacity:.24;stroke-dasharray:1.6 2.4;
  /* El grosor se mide en píxeles de pantalla y no en unidades del viewBox: el
     SVG del mapa usa preserveAspectRatio="none" para estirarse con el
     escenario, y sin esto el trazo se engrosa distinto en horizontal que en
     vertical, así que las líneas hacia SICON o SIPRE no se veían del mismo
     calibre que las que van hacia arriba. */
  stroke-width:1;vector-effect:non-scaling-stroke;
  animation:flujo 3.4s linear infinite;
  transition:opacity .25s,stroke-width .25s,stroke .25s;
}
.eco-link.lit{stroke:var(--naranja);stroke-width:1.8;opacity:1;animation-duration:1.1s}
.eco-stage.focused .eco-link:not(.lit){opacity:.07}
/* El desplazamiento es múltiplo del patrón (1,6 + 2,4 = 4) para que el ciclo
   cierre sin salto. */
@keyframes flujo{to{stroke-dashoffset:-8}}
@keyframes halo{0%{transform:scale(1);opacity:.7}70%,100%{transform:scale(1.3);opacity:0}}

/* El núcleo es el asterisco del manual y no un disco: el disco navy con el
   símbolo adentro era la única pieza maciza del mapa y no pertenecía al
   lenguaje del manual, que en el centro de sus retículas pone siempre este
   asterisco de trazo. Sin fondo ni sombra, las líneas del mapa se recortan
   contra el hueco que les deja main.js. */
.eco-core{
  position:absolute;left:50%;top:50%;translate:-50% -50%;
  width:26%;aspect-ratio:1;
  display:grid;place-items:center;
  z-index:3;background:none;border:0;
  cursor:pointer;padding:0;font:inherit;
  transition:scale .28s var(--ease);
}
/* El centrado usa la propiedad `translate`. Si el hover usara
   transform:translate(-50%,-50%) scale(...) el -50% se aplicaría dos veces
   y el núcleo saltaría fuera del cursor, entrando en bucle de
   mouseenter/mouseleave. Por eso se escala con la propiedad independiente. */
.eco-core:hover,.eco-core:focus-visible{outline:none;scale:1.06}
.eco-logo{
  width:82%;height:auto;color:var(--azul);
  transition:scale .3s var(--ease),filter .35s var(--ease);
}
/* Variante muñeco del núcleo. El PNG está recortado a la figura, así que el
   ancho es figura pura y hay que soltar el max-width del reset global.
   El techo es 112%: las pastillas del anillo interior no escalan con el
   diagrama, y medido en el tamaño mínimo del explorador (470px) ahí quedan
   9px de aire contra la de arriba y la de abajo. Con 120% bajan a 3. */
.eco-muneco{width:112%;max-width:none;display:block}

/* En reposo está quieto. Al apuntarlo late y toma un resplandor: el latido
   corre sólo mientras el cursor está encima, y arranca desde el estado de
   reposo porque la animación se declara acá y no en la regla base. */
.eco-core:hover .eco-logo,.eco-core:focus-visible .eco-logo{
  animation:ecoLogoLatido 1.5s var(--ease) infinite;
  filter:drop-shadow(0 6px 16px rgba(24,62,235,.34));
}
@keyframes ecoLogoLatido{
  0%,100%{scale:1}
  38%{scale:1.11}
  70%{scale:.99}
}

.eco-pill{
  position:absolute;
  left:calc(50% + var(--rx) * var(--rm,1) * cos(var(--a)));
  top:calc(50% + var(--ry) * var(--rm,1) * sin(var(--a)));
  translate:-50% -50%;
  display:inline-flex;align-items:center;gap:8px;white-space:nowrap;
  background:var(--blanco);border:1px solid var(--linea);border-radius:var(--r-pill);
  padding:9px 15px;font:inherit;font-size:.78rem;font-weight:600;color:var(--tinta);
  box-shadow:0 5px 16px rgba(13,15,26,.08);cursor:pointer;z-index:4;
  transition:box-shadow .26s var(--ease),border-color .26s,color .2s;
}
/* Los nodos no flotan a propósito: las líneas se trazan una vez desde su
   posición real, y además son objetivos clickeables. */
.eco-pill i{width:7px;height:7px;border-radius:50%;flex:none}
.eco-pill .lbl-short{display:none}
.eco-pill:hover,.eco-pill:focus-visible{
  border-color:var(--azul);color:var(--azul);
  box-shadow:0 12px 26px rgba(24,62,235,.24);z-index:7;outline:none;
}
.eco-pill.active{
  border-color:var(--naranja);color:var(--naranja);
  box-shadow:0 12px 26px rgba(238,76,1,.22);z-index:6;
}

.eco-panel{
  background:var(--blanco);border:1px solid var(--linea);border-radius:var(--r-lg);
  padding:28px;box-shadow:var(--sombra-sm);
}
/* 16/10 con object-fit:contain: las ilustraciones traen el título adentro
   y con `cover` se les recortaba la parte de arriba. */
.eco-panel-media{
  aspect-ratio:16/10;border-radius:var(--r-md);overflow:hidden;margin-bottom:20px;
  background:var(--lienzo);border:1px solid var(--linea);
}
.eco-panel-media img{width:100%;height:100%;object-fit:contain}
.eco-panel-media.is-empty{display:none}
.eco-name{margin:12px 0 4px;font-size:1.3rem;color:var(--tinta)}
.eco-full{display:block;font-size:.8rem;font-weight:500;color:var(--tenue);margin-bottom:14px}
.eco-promise{font-size:.96rem;font-weight:600;color:var(--tinta);line-height:1.5}
.eco-bullets{margin-top:16px}
.eco-bullets li{padding:6px 0 6px 30px;font-size:.88rem}
.eco-bullets li::before{top:10px}
.eco-swap{animation:swapIn .34s var(--ease)}
@keyframes swapIn{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}

.eco-actors-row{margin-top:18px;padding-top:16px;border-top:1px solid var(--linea)}
.eco-actors-row .label{
  display:block;font-size:.7rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--tenue);margin-bottom:10px;
}
.eco-chips{display:flex;flex-wrap:wrap;gap:6px}
.eco-chip{
  display:inline-block;font-size:.75rem;font-weight:500;color:var(--texto);
  background:var(--lienzo);border:1px solid var(--linea);
  border-radius:var(--r-pill);padding:5px 11px;
}
.prod-full{display:block;font-size:.82rem;font-weight:600;color:var(--tenue);margin:-6px 0 12px}

.eco-legend{display:flex;gap:28px;flex-wrap:wrap;justify-content:center;margin-bottom:40px}
.eco-legend span{display:inline-flex;align-items:center;gap:9px;font-size:.85rem;font-weight:500;color:var(--texto)}
.eco-legend i{width:10px;height:10px;border-radius:50%;flex:none}
.c-fin{background:var(--azul)}
.c-efe{background:var(--navy)}
.c-usr{background:var(--naranja)}

/* c-fin/c-efe/c-usr nacieron como puntos de color de la leyenda, pero el JS
   se los pone también a la etiqueta de capa del panel. Ahí pintan un fondo
   saturado y el texto se quedaba con el gris de .tag: hay que forzar el
   blanco y sacarle el borde claro. */
.tag.eco-layer.c-fin,.tag.eco-layer.c-efe,.tag.eco-layer.c-usr{
  color:#fff;border-color:transparent;font-weight:600;
}

/* ══════════ TESTIMONIOS ══════════ */
.quote{
  background:var(--blanco);border:1px solid var(--linea);border-radius:var(--r-lg);
  padding:54px 40px 40px;
  position:relative;transition:transform .3s var(--ease),box-shadow .3s var(--ease);
}
.quote:hover{transform:translateY(-4px);box-shadow:var(--sombra-md)}
.quote::before,.quote::after{
  position:absolute;font-size:4rem;line-height:1;
  color:var(--naranja);opacity:.32;font-family:Georgia,serif;
}
.quote::before{content:"“";top:20px;left:24px}
.quote::after{content:"”";bottom:-6px;right:26px}
.quote p{font-size:1.02rem;line-height:1.62;color:var(--tinta);position:relative}
.quote-foot{display:flex;align-items:center;gap:14px;margin-top:26px;padding-top:22px;border-top:1px solid var(--linea)}
.avatar{width:46px;height:46px;border-radius:50%;background:var(--lienzo);border:1px solid var(--linea);flex:none}
.quote-foot b{display:block;font-size:.95rem;font-weight:600;color:var(--tinta)}
.quote-foot small{color:var(--tenue);font-size:.85rem}

/* ══════════ TIMELINE VERTICAL ══════════ */
.vtimeline{position:relative;max-width:920px;margin:0 auto}
.vtimeline::before{
  content:"";position:absolute;left:50%;top:0;bottom:0;width:2px;translate:-50% 0;
  background:linear-gradient(180deg,rgba(24,62,235,.3),rgba(24,62,235,.12));
  transform-origin:top;
}
.js .vtimeline::before{scale:1 0;transition:scale 1.3s var(--ease)}
.js .vtimeline.shown::before{scale:1 1}
.vtimeline::after{
  content:"";position:absolute;left:50%;top:-160px;width:2px;height:160px;translate:-50% 0;
  opacity:0;background:linear-gradient(180deg,transparent,var(--naranja) 50%,transparent);
}
.vtimeline.shown::after{opacity:1;animation:vtViaje 6s linear 1.1s infinite}
@keyframes vtViaje{from{top:-160px}to{top:100%}}

.vt-item{position:relative;width:50%;padding:0 48px 44px}
.vt-item:nth-child(odd){left:0}
.vt-item:nth-child(even){left:50%}
.vt-item:last-child{padding-bottom:0}
.vt-node{
  position:absolute;top:26px;width:18px;height:18px;border-radius:50%;z-index:2;
  background:var(--blanco);border:4px solid var(--azul);
  box-shadow:0 0 0 5px rgba(24,62,235,.12);
  transition:transform .35s var(--ease);
}
.vt-item:nth-child(odd) .vt-node{right:-9px}
.vt-item:nth-child(even) .vt-node{left:-9px}
.vt-item:last-child .vt-node{border-color:var(--naranja);box-shadow:0 0 0 5px rgba(238,76,1,.14)}
.vt-item:hover .vt-node{transform:scale(1.2)}
.vt-card{
  background:var(--blanco);border:1px solid var(--linea);border-radius:var(--r-lg);padding:28px;
  transition:transform .3s var(--ease),box-shadow .3s var(--ease),border-color .3s;
}
.vt-item:hover .vt-card{box-shadow:var(--sombra-md);border-color:var(--linea-fuerte)}
.vt-item:nth-child(odd):hover .vt-card{transform:translateX(-5px)}
.vt-item:nth-child(even):hover .vt-card{transform:translateX(5px)}
.vt-tag{
  display:inline-block;font-size:.72rem;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--naranja);margin-bottom:9px;
}
.vt-card h3{margin-bottom:10px;color:var(--tinta)}
.vt-card p{font-size:.95rem;line-height:1.58}

.vt-item{transition:opacity .65s var(--ease),transform .65s var(--ease)}
.js .vt-item{opacity:0}
.js .vt-item:nth-child(odd){transform:translateX(-28px)}
.js .vt-item:nth-child(even){transform:translateX(28px)}
.js .vt-item.shown{opacity:1;transform:none}
.js .vt-item:nth-child(2){transition-delay:.1s}
.js .vt-item:nth-child(3){transition-delay:.2s}
.js .vt-item:nth-child(4){transition-delay:.3s}
.js .vt-item:nth-child(5){transition-delay:.4s}

/* ══════════ COMPARATIVA (barras) ══════════ */
.bars{display:flex;flex-direction:column;gap:28px;max-width:48rem}
.bar-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:10px}
.bar-top b{font-size:1rem;font-weight:600;color:var(--tinta)}
.bar-top span{font-size:.8rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.bar-track{height:22px;border-radius:var(--r-pill);background:var(--tile);overflow:hidden}
.bar-fill{height:100%;border-radius:var(--r-pill);width:0;transition:width 1.1s var(--ease)}
.bar-fill.slow{background:var(--azul)}
.bar-fill.fast{background:var(--azul)}
.in-view .bar-fill.slow{width:100%}
.in-view .bar-fill.fast{width:17%}

/* ══════════ DETALLE PLEGADO ══════════
   El "+" gira a "×" al abrir. Va sobre <details> nativo: sin JS, con teclado
   resuelto y con el contenido presente para el buscador aunque esté plegado. */
.mas{margin-top:18px;border-top:1px solid var(--linea);padding-top:14px}
.mas summary{
  display:flex;align-items:center;gap:10px;cursor:pointer;list-style:none;
  font-size:.9rem;font-weight:600;color:var(--azul);
}
.mas summary::-webkit-details-marker{display:none}
.mas summary::before{
  content:"+";display:grid;place-items:center;flex:none;width:22px;height:22px;
  border:1px solid var(--azul);border-radius:50%;font-size:1rem;line-height:1;
  transition:transform .28s var(--ease),background .28s var(--ease),color .28s var(--ease);
}
.mas[open] summary::before{content:"×";transform:rotate(180deg);background:var(--azul);color:#fff}
.mas summary:hover::before{background:var(--azul);color:#fff}
.mas .checks{margin-top:14px}

/* ══════════ BANDA CLARA ══════════
   Misma pieza que .dark-band pero sobre superficie clara, para los bloques
   donde el texto es lo principal: sobre navy el cuerpo largo cansa la lectura
   y las tarjetas internas pierden contorno. */
.light-band{
  background:var(--blanco);border:1px solid var(--linea);
  border-radius:var(--r-xl);padding:68px;position:relative;overflow:hidden;
  box-shadow:var(--sombra-sm);
}
.light-band::before{
  content:"";position:absolute;top:-45%;right:-8%;width:600px;height:600px;pointer-events:none;
  background:radial-gradient(circle,rgba(24,62,235,.07) 0%,transparent 66%);
}
.light-band>*{position:relative}
/* Las tarjetas de adentro se apoyan en el lienzo para separarse del blanco de
   la banda: con fondo blanco sobre blanco desaparecerían. */
.light-band .card{background:var(--lienzo)}
.light-band .cita{
  margin-top:38px;font-size:1.12rem;font-style:italic;color:var(--tinta);max-width:52rem;
}

/* ══════════ MUÑECO DE MARCA ══════════
   El símbolo de Tekhne hecho objeto. Son dos fotos de la misma pieza: la de
   frente está siempre, y la ladeada se superpone sólo al apuntarlo. El cambio
   va con steps(1) y no con un fundido, porque cruzar las dos opacidades deja
   un fotograma donde se ven los dos cuerpos a la vez. */
/* El de "Sumate al equipo" queda al tamaño que tenía antes del recorte del
   PNG: la caja de 300px sobre el lienzo viejo mostraba una figura de
   169x206, y con el PNG recortado eso son 174px de ancho. */
.munheco{
  position:relative;width:min(174px,100%);margin:44px 0 30px;cursor:pointer;
  animation:munecoFlota 3.6s ease-in-out infinite;
}
.munheco img{width:100%;height:auto;display:block}
.munheco .pose-b{position:absolute;inset:0;opacity:0;transition:opacity .15s steps(1)}
.munheco:hover .pose-b{opacity:1}
.munheco:hover{animation:munecoSalta .55s var(--ease) infinite alternate}
/* La sombra respira con el flote: sin eso el muñeco parece deslizarse en
   vertical en lugar de despegarse del piso. */
.munheco::after{
  content:"";position:absolute;left:18%;right:18%;bottom:-22px;height:18px;border-radius:50%;
  background:radial-gradient(ellipse,rgba(13,15,26,.15),transparent 68%);
  animation:munecoSombra 3.6s ease-in-out infinite;
}
@keyframes munecoFlota{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
@keyframes munecoSalta{from{transform:translateY(0) rotate(-1deg)}to{transform:translateY(-15px) rotate(2deg)}}
@keyframes munecoSombra{0%,100%{transform:scaleX(1);opacity:.9}50%{transform:scaleX(.84);opacity:.6}}
@media (prefers-reduced-motion:reduce){
  .munheco,.munheco::after{animation:none}
  .munheco .pose-b{transition:none}
}

/* La fila de barras comparte el ancho con el muñeco: las barras conservan su
   escala comparativa y el muñeco toma el aire de la derecha. */
.barras-fila{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:52px;align-items:center}
.barras-fila .bars-wrap{min-width:0}
/* La pose recostada es más ancha que alta, así que se le da más caja y un
   flote más corto: acostado, un vaivén grande se leería como flotar en el aire. */
.munheco-echado{width:100%}
.munheco-echado::after{left:10%;right:10%;bottom:-12px;height:14px}
@media (max-width:900px){
  .barras-fila{grid-template-columns:1fr;gap:26px}
  .munheco-echado{width:min(320px,84%);justify-self:center}
}

/* Variante suelta: una sola pose, sin el cambio al apuntar. Mantiene el flote
   y el salto, que es lo que lo hace sentir vivo. */
.munheco-solo{margin:0;width:100%;justify-self:end}
.eco-intro{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:48px;align-items:center;margin-bottom:44px}
@media (max-width:900px){
  .eco-intro{grid-template-columns:1fr;gap:34px;justify-items:center}
  .munheco-solo{justify-self:center;width:min(260px,68%)}
}

/* Piezas que sólo aparecían sobre fondo claro y ahora también viven dentro del
   bloque navy de casos de la home. */
.dark-band .sec-head{margin-bottom:40px}
.dark-band .kicker.warm{color:#FFAE85}
/* El botón claro se invierte: sobre navy, un botón blanco pesa como un CTA
   principal y le robaría jerarquía al de la sección. */
.dark-band .btn-quiet{background:transparent;border-color:rgba(255,255,255,.4);color:#fff}
.dark-band .btn-quiet:hover{background:#fff;color:var(--navy);border-color:#fff;box-shadow:none}
.dark-band .arrow-link{color:#9FB2FF}
.dark-band .arrow-link:hover{color:#fff}
/* La tarjeta destacada pierde su halo azul, que sobre navy no se ve, y se
   distingue por un borde y un fondo apenas más presentes. */
.dark-band .card.feature{
  box-shadow:none;border-color:rgba(255,255,255,.28);background:rgba(255,255,255,.09);
}
.dark-band .card.feature::before{display:none}


/* ══════════ BANDA NAVY CON TARJETAS BLANCAS ══════════
   El marco sigue en navy —volante, titular y bajada en blanco— pero las
   tarjetas de adentro vuelven a ser blancas. Eso obliga a deshacer, sólo
   dentro de ellas, todas las inversiones que .dark-band aplica al contenido:
   si no, quedaría texto claro sobre blanco. */
.dark-band.tarjetas-claras .card{
  background:var(--blanco);border-color:var(--linea);
}
.dark-band.tarjetas-claras .card:hover{
  background:var(--blanco);border-color:var(--linea-fuerte);
}
.dark-band.tarjetas-claras .card h3,
.dark-band.tarjetas-claras .card h4{color:var(--azul)}
.dark-band.tarjetas-claras .card p,
.dark-band.tarjetas-claras .card .lead{color:var(--texto)}
.dark-band.tarjetas-claras .card .kicker{color:var(--tenue)}
.dark-band.tarjetas-claras .card .kicker.warm{color:var(--naranja)}
.dark-band.tarjetas-claras .card .checks li{color:var(--texto)}
.dark-band.tarjetas-claras .card .checks li b{color:var(--tinta)}
.dark-band.tarjetas-claras .card .tag{
  background:var(--lienzo);border-color:var(--linea);color:var(--texto);
}
.dark-band.tarjetas-claras .card .kpi-row{border-top-color:var(--linea)}
.dark-band.tarjetas-claras .card .kpi{border-left-color:var(--linea)}
.dark-band.tarjetas-claras .card .kpi span{color:var(--tenue)}
/* Vuelve la rampa naranja→azul: la cálida existe para contrastar con el navy,
   y acá el fondo de la cifra es blanco otra vez. Va como background-image
   porque el atajo repondría background-clip en border-box y la cifra, que está
   en color:transparent, se volvería invisible. */
.dark-band.tarjetas-claras .card .kpi b{
  background-image:linear-gradient(155deg,var(--naranja),var(--azul));
}
.dark-band.tarjetas-claras .card .arrow-link{color:var(--azul)}
.dark-band.tarjetas-claras .card .arrow-link:hover{color:var(--azul-hover)}
.dark-band.tarjetas-claras .card .btn-quiet{
  background:var(--blanco);border-color:var(--linea);color:var(--tinta);
}
.dark-band.tarjetas-claras .card .btn-quiet:hover{
  background:var(--blanco);border-color:var(--azul);color:var(--azul);box-shadow:var(--sombra-sm);
}
/* La destacada recupera su anillo degradado, que sobre la tarjeta translúcida
   no se veía y por eso lo había apagado. */
.dark-band.tarjetas-claras .card.feature{
  background:var(--blanco);border-color:transparent;box-shadow:0 12px 34px rgba(0,2,79,.28);
}
.dark-band.tarjetas-claras .card.feature::before{display:block}


/* ══════════ ECUACIÓN ══════════
   La idea de un caso resumida como fórmula: los operandos en texto normal y
   los signos en naranja, alineados en una sola línea que se parte en varias
   en pantallas chicas sin perder el orden de lectura. */
.ecuacion{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 22px;
  margin-top:34px;font-family:var(--display);font-size:1.14rem;font-weight:400;
}
.ecuacion span,.ecuacion b{display:inline-flex;align-items:baseline;gap:8px}
.ecuacion b{font-weight:600}
.ecuacion i{
  font-style:normal;font-weight:500;color:var(--naranja);
  /* Los signos se leen como operadores y no como parte de la palabra. */
  font-size:1.24em;line-height:1;
}
.dark-band .ecuacion{color:#fff}
.dark-band .ecuacion i{color:#FF8A4C}

/* Cita textual de una nota de prensa dentro de una tarjeta. */
.cita-nota{
  margin:14px 0 22px;padding-left:16px;border-left:2px solid var(--naranja);
  font-size:1.02rem;font-style:italic;line-height:1.55;
}
.dark-band .cita-nota{border-left-color:#FF8A4C;color:var(--sobre-oscuro-70)}

/* El icono de despegue marca que el enlace sale del sitio. */
.btn .ico{width:1em;height:1em;margin-left:.1em}

/* ══════════ MORFOSIS DE FIGURAS (heros de Productos y Servicios) ══════════
   Dos pares de láminas del manual que son, en realidad, la misma figura en dos
   estados: cuatro cuadrados apilados en isometría se reordenan en la espiral
   concéntrica, y cuatro círculos que se solapan se reordenan en la serie
   tangente. Por eso no hay dos dibujos cruzándose por opacidad, sino una sola
   forma por capa que viaja de un estado al otro; la reorganización en sí es lo
   que cuenta el gráfico.

   Las dos piezas comparten un único keyframe y cada capa declara su estado
   inicial y final en variables, así el timing y el easing se definen una sola
   vez. La estructura del transform es siempre la misma —trasladar, rotar,
   escalar— porque interpolar entre dos listas de transform exige que tengan
   las mismas funciones en el mismo orden; si una capa omitiera la rotación,
   el navegador dejaría de interpolar y saltaría de un estado al otro. */
.morfo{position:relative;display:grid;place-items:center}
.morfo svg{width:100%;height:auto;max-width:430px;overflow:visible}

.morfo-figura{
  fill:none;stroke:url(#morfo-rampa);stroke-width:2.2;
  /* El trazo no se adelgaza al escalar. Sin esto el círculo chico de la
     mamushka y el cuadrado interior de la espiral quedan como un pelo, y el
     rombo isométrico —achatado a la mitad en vertical— tendría el trazo
     horizontal más fino que el vertical. */
  vector-effect:non-scaling-stroke;
  animation:morfoReordenar var(--ciclo,9s) cubic-bezier(.68,0,.24,1) infinite both;
  animation-delay:var(--d,0s);
}
/* El escalonado de los delays es lo que hace que se lea como "se ordenan":
   con las cuatro capas moviéndose al mismo tiempo el cambio parece un salto
   único, y con demasiado desfase nunca se ven las cuatro juntas en el
   segundo estado. */
/* El orden importa: la lista se aplica al elemento de derecha a izquierda, así
   que el giro ocurre primero y el achatado después, sobre el eje vertical de
   la pantalla. Al revés —achatar y luego girar— el cuadrado isométrico sale
   como un paralelogramo inclinado en vez de un rombo apoyado en horizontal. */
@keyframes morfoReordenar{
  0%,18%  {transform:translate(var(--ax,0px),var(--ay,0px)) scale(var(--as,1),var(--asy,1)) rotate(var(--ar,0deg))}
  46%,76% {transform:translate(var(--bx,0px),var(--by,0px)) scale(var(--bs,1),var(--bs,1)) rotate(var(--br,0deg))}
  100%    {transform:translate(var(--ax,0px),var(--ay,0px)) scale(var(--as,1),var(--asy,1)) rotate(var(--ar,0deg))}
}

/* Guías de alineación: aparecen mientras las capas viajan y se quedan tenues
   en el estado ordenado. Son las que explican que el reordenamiento no es
   decorativo sino que las figuras caen sobre un eje común. */
.morfo-guia{
  fill:none;stroke:var(--naranja);stroke-width:1.1;stroke-dasharray:4 6;opacity:0;
  animation:morfoGuia var(--ciclo,9s) ease-in-out infinite both;
}
@keyframes morfoGuia{
  0%,16%{opacity:0}
  32%{opacity:.55}
  46%,76%{opacity:.24}
  88%,100%{opacity:0}
}

/* Punto de convergencia: el centro de la espiral y el vértice donde apoyan
   todos los círculos. Escala sobre su propia caja y no sobre el viewBox,
   porque en Servicios no está en el origen y con el origen del viewBox se
   desplazaría al crecer en lugar de abrirse en su lugar. */
.morfo-nucleo{
  fill:var(--naranja);transform-box:fill-box;transform-origin:center;
  animation:morfoNucleo var(--ciclo,9s) cubic-bezier(.68,0,.24,1) infinite both;
}
@keyframes morfoNucleo{
  0%,22%{transform:scale(0);opacity:0}
  46%,76%{transform:scale(1);opacity:1}
  90%,100%{transform:scale(0);opacity:0}
}

@media(prefers-reduced-motion:reduce){
  .morfo-figura,.morfo-guia,.morfo-nucleo{animation:none}
  /* Queda el estado ordenado, que es el que cierra el mensaje. */
  .morfo-figura{transform:translate(var(--bx,0px),var(--by,0px)) scale(var(--bs,1)) rotate(var(--br,0deg))}
  .morfo-guia{opacity:.24}
}

/* ══════════ MEDIA ══════════ */
.media{
  border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--linea);
  background:var(--blanco);box-shadow:var(--sombra-md);
}
.media img{width:100%;height:100%;object-fit:cover}
/* Variante para ilustraciones: el marco existe sólo para darles una
   superficie clara sobre fondo oscuro, así que no deben recortarse. */
.media-ilustracion{padding:20px;display:grid;place-items:center}
.media-ilustracion img{height:auto;object-fit:contain}
/* Ilustración sin marco: para las piezas cuyo fondo ya coincide con el
   lienzo del sitio, encuadrarlas dibujaría una caja alrededor de nada. */
.ilustracion{width:100%;height:auto;display:block}

/* ── Foco de luz sobre la ilustración ──
   Dos capas de la misma imagen: abajo la normal, arriba una copia
   "encendida" (más saturada y con halo naranja) recortada por un degradado
   radial que sigue al cursor. Al pasar por encima, el puente se ilumina
   sólo donde cae la luz.
   La copia se pinta como background y no como otro <img>: es la misma URL,
   así que no hay una segunda descarga, y de paso queda fuera del árbol de
   accesibilidad, que es lo correcto para una capa decorativa. */
/* El borde exterior se desvanece para que la ilustración se funda con la
   página en lugar de cortarse en un rectángulo. La elipse es generosa: sólo
   muerde el extremo de las nubes, que es justo lo que conviene difuminar. */
.ilus-luz{
  position:relative;display:block;--lx:50%;--ly:50%;
  -webkit-mask-image:radial-gradient(ellipse 88% 90% at 50% 47%,#000 60%,transparent 100%);
  mask-image:radial-gradient(ellipse 88% 90% at 50% 47%,#000 60%,transparent 100%);
}
/* Entra más despacio que el resto de los bloques: es una ilustración grande
   y con el tiempo de las tarjetas parecía un salto. */
.ilus-luz.reveal{transition-duration:1.15s}
.js .ilus-luz.reveal{transform:translateY(20px) scale(.985)}
.js .ilus-luz.reveal.shown{transform:none}
.ilus-luz img{width:100%;height:auto;display:block}
.ilus-brillo{
  position:absolute;inset:0;pointer-events:none;opacity:0;
  background:var(--ilus) center/100% 100% no-repeat;
  /* Luz blanca: varios halos de radios crecientes sobre los trazos, que es
     lo que hace que se lean como iluminados en vez de teñidos. */
  filter:drop-shadow(0 0 2px rgba(255,255,255,1))
         drop-shadow(0 0 6px rgba(255,255,255,.95))
         drop-shadow(0 0 14px rgba(255,255,255,.8))
         drop-shadow(0 0 26px rgba(255,255,255,.5))
         brightness(1.2);
  /* Elipse y no círculo: en radial-gradient un `circle` sólo acepta radios
     absolutos, y con porcentaje la regla entera queda inválida (se iluminaba
     la ilustración completa). La elipse sí los admite y encima escala con la
     caja; como la imagen es ~1.7 veces más ancha que alta, 18%×31% da un
     foco prácticamente redondo a cualquier tamaño.
     La máscara no lleva transición: tiene que pegarse al cursor para que se
     lea como una linterna. Lo que se funde es la aparición de la capa. */
  -webkit-mask-image:radial-gradient(ellipse 18% 31% at var(--lx) var(--ly),
    #000 0%,rgba(0,0,0,.55) 45%,transparent 74%);
  mask-image:radial-gradient(ellipse 18% 31% at var(--lx) var(--ly),
    #000 0%,rgba(0,0,0,.55) 45%,transparent 74%);
  transition:opacity .3s var(--ease);
}
/* Lavado por debajo de la ilustración: aclara el área donde cae la luz.
   Sin esto el efecto casi no se percibe, porque un halo blanco sobre un
   lienzo casi blanco tiene muy poco contraste; el lavado es el que hace
   evidente que ahí está pegando la luz. */
.ilus-foco{
  position:absolute;inset:0;pointer-events:none;opacity:0;z-index:0;
  background:radial-gradient(ellipse 24% 40% at var(--lx) var(--ly),
    #fff 0%,rgba(255,255,255,.7) 40%,transparent 74%);
  transition:opacity .3s var(--ease);
}
.ilus-luz img{position:relative;z-index:1}
.ilus-luz.luz-activa .ilus-brillo,
.ilus-luz.luz-activa .ilus-foco,
.ilus-luz:focus-within .ilus-brillo,
.ilus-luz:focus-within .ilus-foco{opacity:1}

/* En la página de GxBridgeIA la ilustración es el asunto de la portada, así
   que se sale de su columna. La sección recorta el desborde. */
.ilus-grande{width:122%;margin-inline:-11%}

@media(max-width:1080px){.ilus-grande{width:100%;margin-inline:0}}
@media(hover:none){.ilus-brillo,.ilus-foco{display:none}}
@media(prefers-reduced-motion:reduce){.ilus-brillo{transition:none}}

.media-slot{
  border-radius:var(--r-lg);border:1.5px dashed var(--linea-fuerte);background:var(--blanco);
  display:grid;place-items:center;text-align:center;padding:26px;color:var(--tenue);
  font-size:.85rem;line-height:1.5;min-height:220px;
}
.prod-thumb{
  aspect-ratio:4/3;border-radius:var(--r-md);overflow:hidden;margin-bottom:22px;
  background:var(--lienzo);border:1px solid var(--linea);
}
.prod-thumb img{width:100%;height:100%;object-fit:contain}

/* ══════════ MAPA FEDERAL ══════════
   Geometría real (Natural Earth 10m, dominio público) proyectada en cónica
   conforme de Lambert con paralelos estándar en -30° y -50°, la que usan los
   mapas oficiales argentinos; Mercator alargaba demasiado la Patagonia.
   Los trazados los genera el script del proyecto: acá sólo se los viste con
   el lenguaje de la marca. */
.mapa-federal{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:48px;align-items:start}
.mapa-lienzo{position:relative;margin:0}
.mapa-svg{width:100%;height:auto;display:block}

.mapa-provincias path{
  fill:none;stroke:url(#tkg-mapa);stroke-width:.85;
  stroke-linejoin:round;stroke-linecap:round;
}
.mapa-guias line{stroke:var(--linea-fuerte);stroke-width:.8}
.mapa-pines circle{fill:var(--blanco);stroke-width:2.4}
.mapa-pines .norte{stroke:var(--naranja)}
.mapa-pines .sur{stroke:var(--azul)}

/* Las etiquetas son HTML y no <text> del SVG: dentro del SVG la tipografía
   se escala con el dibujo y quedaba en 7px. Posicionadas por porcentaje
   sobre el mismo viewBox caen en el mismo punto, con el tipo a tamaño real. */
.mp-etiqueta{
  position:absolute;transform:translateY(-50%);
  font-size:.8rem;font-weight:500;color:var(--tinta);white-space:nowrap;
  background:var(--blanco);border:1px solid var(--naranja);
  border-radius:var(--r-pill);padding:5px 13px;
}
.mp-etiqueta.sur{border-color:var(--azul)}
.mp-etiqueta.der{transform:translate(-100%,-50%)}

/* ── Listado de clientes por jurisdicción ── */
.mapa-listas{columns:2;column-gap:40px}
.mapa-grupo{break-inside:avoid;margin-bottom:28px}
.mapa-grupo h3{
  font-size:1.02rem;color:var(--naranja);
  padding-bottom:8px;border-bottom:1px solid var(--linea);margin-bottom:11px;
}
.mapa-grupo.sur h3{color:var(--azul)}
.mapa-grupo li{
  position:relative;padding-left:15px;font-size:.92rem;color:var(--texto);
  line-height:1.5;margin-bottom:5px;
}
.mapa-grupo li::before{
  content:"";position:absolute;left:0;top:.62em;width:5px;height:5px;
  border-radius:50%;background:var(--naranja);
}
.mapa-grupo.sur li::before{background:var(--azul)}

/* ── Enfoque al apuntar ──
   El atributo data-prov enlaza el trazado de la provincia, su punto, su
   etiqueta y su grupo del listado. Al enfocar uno se enciende el conjunto
   y todo lo demás cede, sin importar desde qué punta se entre. */
.mapa-federal{--t-foco:.28s var(--ease)}
.mapa-provincias g,.mp-guia,.mp-pin,.mp-etiqueta,.mapa-grupo{
  transition:opacity var(--t-foco),color var(--t-foco),
             background var(--t-foco),border-color var(--t-foco);
}
.mapa-provincias path{transition:stroke-width var(--t-foco)}

.mapa-federal.hay-foco .mapa-provincias g,
.mapa-federal.hay-foco .mp-guia,
.mapa-federal.hay-foco .mp-pin,
.mapa-federal.hay-foco .mp-etiqueta,
.mapa-federal.hay-foco .mapa-grupo{opacity:.28}

.mapa-federal.hay-foco .foco{opacity:1}
.mapa-federal.hay-foco .mp-pin.foco{r:8}
/* La provincia enfocada se rellena con su propio degradado al 10%: con sólo
   engrosar el trazo el realce casi no se leía. */
.mapa-federal.hay-foco .mapa-provincias g.foco path{
  stroke-width:2;fill:url(#tkg-mapa);fill-opacity:.1;
}

.mp-etiqueta{cursor:pointer;font:inherit;font-size:.8rem;font-weight:500}
.mp-etiqueta.foco{background:var(--naranja);border-color:var(--naranja);color:#fff}
.mp-etiqueta.sur.foco{background:var(--azul);border-color:var(--azul)}
.mapa-grupo{cursor:default;border-radius:var(--r-sm)}
.mapa-federal.hay-foco .mapa-grupo.foco{opacity:1}

@media(prefers-reduced-motion:reduce){
  .mapa-provincias g,.mp-guia,.mp-pin,.mp-etiqueta,.mapa-grupo,
  .mapa-provincias path{transition:none}
}

@media(max-width:1080px){
  .mapa-federal{grid-template-columns:1fr;gap:44px}
  .mapa-lienzo{max-width:600px;margin-inline:auto}
}
@media(max-width:560px){
  .mapa-listas{columns:1}
  .mp-etiqueta{font-size:.7rem;padding:4px 9px}
}

/* ══════════ CARRUSEL DE FOTOS ══════════
   Las fotos vienen con encuadres distintos, así que el contenedor fija la
   proporción y `cover` recorta: todas ocupan exactamente el mismo marco.
   Las diapositivas se apilan en una única celda de grilla (no en posición
   absoluta) para que el alto lo siga marcando la foto y no haya que fijarlo
   a mano. */
/* ══════════ TARJETA QUE SE LLENA AL APUNTARLA ══════════
   Toda la tarjeta es el enlace, con un disco en la esquina que al apuntarla se
   agranda hasta cubrirla y deja el texto en blanco. Crece por escala y no por
   alto y ancho: escalar es lo único que el navegador puede animar sin recalcular
   la caja, y de ahí que el barrido se sienta continuo. El disco es redondo
   siempre; al pasarse del borde deja de verse porque la tarjeta recorta. */
.card-expande{
  position:relative;overflow:hidden;display:block;
  color:inherit;text-decoration:none;isolation:isolate;
}
.card-relleno{
  position:absolute;right:26px;bottom:26px;width:46px;height:46px;
  border-radius:50%;background:var(--navy);z-index:0;
  transform:scale(0);transform-origin:center;
  transition:transform 1.05s cubic-bezier(.4,0,.2,1);
}
.card-expande:hover .card-relleno,
.card-expande:focus-visible .card-relleno{
  /* 26 veces alcanza para cubrir la tarjeta más ancha desde su esquina. */
  transform:scale(26);
}
/* El botón de la esquina: es lo que anticipa de dónde va a salir el relleno. */
.card-boton{
  position:absolute;right:26px;bottom:26px;width:46px;height:46px;z-index:2;
  display:grid;place-items:center;border-radius:50%;
  border:1px solid var(--linea-fuerte);color:var(--tinta);
  transition:border-color .4s var(--ease),color .4s var(--ease),transform .4s var(--ease);
}
.card-boton .ico{width:1.1rem;height:1.1rem}
.card-expande:hover .card-boton{border-color:rgba(255,255,255,.55);color:#fff;transform:translateX(3px)}
.card-cuerpo{position:relative;z-index:1;display:block;padding-bottom:34px}

/* Sobre el relleno, el texto pasa a blanco. La transición es más corta que la
   del disco para que el texto no quede gris sobre navy a mitad del barrido. */
.card-expande h3,.card-expande p,.card-expande .kicker,.card-expande .card-ico{
  transition:color .45s var(--ease),background .45s var(--ease),border-color .45s var(--ease);
}
.card-expande:hover h3{color:#fff}
.card-expande:hover p{color:rgba(255,255,255,.82)}
.card-expande:hover .kicker{color:rgba(255,255,255,.6)}
.card-expande:hover .card-ico{background:rgba(255,255,255,.12)}
.card-expande:hover .tag{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.24);color:#fff}
.card-expande .tag{transition:background .45s var(--ease),border-color .45s var(--ease),color .45s var(--ease)}

/* El párrafo que aparece. Ocupa su lugar desde el principio —por eso reserva
   altura— para que al revelarse no empuje el resto de la tarjeta. */
.card-revela{
  opacity:0;transform:translateY(6px);
  transition:opacity .5s var(--ease) .12s,transform .5s var(--ease) .12s;
}
.card-expande:hover .card-revela{opacity:1;transform:none}

@media(prefers-reduced-motion:reduce){
  .card-relleno{transition:none}
  .card-revela{transition:none;opacity:1;transform:none}
}

/* ══════════ RETÍCULA DE PIEZAS (hero de Compañía) ══════════
   Las piezas se dibujan acá en lugar de recortarse de la lámina: siendo
   vectores, lo que se anima es cada parte —el trazo del cable, los rayos del
   asterisco, cada cuadrante— y no una imagen entera. Eso permite que la
   respuesta al cursor sea movimiento y no un resplandor encima.

   Las coordenadas salen de medir la lámina del manual: su grilla cae en
   múltiplos de 1/6, de ahí el lienzo de 600 con celdas de 100. */
.reticula{position:relative;display:grid;place-items:center;width:100%}
.reticula-caja{position:relative;width:100%;max-width:560px;margin-bottom:3%}
.ret{display:block;width:100%;height:auto;overflow:visible}
.ret g,.ret circle,.ret rect,.ret path,.ret image,.ret use{
  transform-box:fill-box;transform-origin:center;
}
.ret-grid path{fill:none;stroke:var(--linea-fuerte);stroke-width:1}

/* ── El cable ──
   Se dibuja de abajo hacia arriba: el trazo avanza por el recorrido, que es lo
   que se lee como que sube. Con pathLength="1" el largo está normalizado, así
   que el desfase va de 1 a 0 sin tener que medirlo. Despacio: 11 s de subida.
   El trazo queda dibujado en reposo; el ciclo corre sólo con el cursor encima. */
.rz-cable{
  fill:none;stroke:url(#ret-cable);stroke-width:4;stroke-linecap:round;
  stroke-dasharray:1;stroke-dashoffset:0;
}
.reticula:hover .rz-cable{animation:rzCableSube 11s linear infinite}
@keyframes rzCableSube{
  0%   {stroke-dashoffset:1}
  70%  {stroke-dashoffset:0}
  100% {stroke-dashoffset:-1}
}

/* ── Cruz: los ejes crecen desde el centro y el punto late ── */
.rz-cruz-fina path{fill:none;stroke:rgba(238,76,1,.34);stroke-width:1}
.rz-cruz-eje{fill:none;stroke:var(--tinta);stroke-width:1.6}
.rz-cruz-ejeh{animation:rzEjeH 6.4s ease-in-out infinite}
.rz-cruz-ejev{animation:rzEjeV 6.4s ease-in-out infinite .3s}
.rz-cruz-punto{fill:var(--naranja);animation:rzLate 3.4s ease-in-out infinite}
@keyframes rzEjeH{0%,100%{transform:scaleX(.72)}50%{transform:scaleX(1)}}
@keyframes rzEjeV{0%,100%{transform:scaleY(.72)}50%{transform:scaleY(1)}}
@keyframes rzLate{0%,100%{transform:scale(1)}50%{transform:scale(1.3)}}

/* ── Tile de la flecha: el trazo se dibuja y la punta lo sigue ── */
.rz-flecha rect{fill:var(--tile)}
.rz-flecha-trazo path{
  fill:none;stroke:var(--tinta);stroke-width:2;pathLength:1;
  stroke-dasharray:1;stroke-dashoffset:0;
  animation:rzTraza 7s ease-in-out infinite;
}
.rz-flecha-trazo path:last-child{animation-delay:.55s}
.rz-flecha-pie{fill:var(--naranja)}
@keyframes rzTraza{0%{stroke-dashoffset:1}34%,72%{stroke-dashoffset:0}100%{stroke-dashoffset:1}}

/* ── Serie de puntos: entran de a uno ── */
.rz-serie circle{fill:var(--naranja);animation:rzEntra 4.6s ease-in-out infinite}
.rz-serie circle:nth-child(2){animation-delay:.18s}
.rz-serie circle:nth-child(3){animation-delay:.36s}
.rz-serie circle:nth-child(4){animation-delay:.54s}
.rz-serie circle:nth-child(5){animation-delay:.72s}
@keyframes rzEntra{0%,100%{transform:scale(.5);opacity:.35}45%{transform:scale(1);opacity:1}}

/* ── El símbolo salta sobre la línea en la que se apoya ── */
.rz-simbolo{color:var(--azul);transform-origin:bottom center;animation:rzSalta 3s cubic-bezier(.3,0,.5,1) infinite}
.rz-simbolo-puntos circle{fill:var(--naranja)}
@keyframes rzSalta{
  0%,100%{transform:translateY(0) scale(1,1)}
  6%     {transform:translateY(0) scale(1.06,.94)}
  40%    {transform:translateY(-30%) scale(1,1)}
  74%    {transform:translateY(0) scale(1.08,.92)}
  86%    {transform:translateY(-4%) scale(.99,1.01)}
}

/* ── Anillo: los puntos giran alrededor del centro de la figura ── */
.rz-anillo{animation:rzGira 26s linear infinite}
.rz-anillo circle{fill:var(--naranja)}

/* ── Los cuadrados de Productos ──
   Misma mecánica que en esa página: una sola forma por capa que viaja entre dos
   estados, no dos dibujos cruzándose. Van de apilados en isometría a inscriptos
   uno en otro, y cada capa declara sus dos estados en variables.

   El orden del transform importa: la escala va antes del giro en la lista, así
   el achatado de la isometría ocurre sobre el eje vertical de la pantalla. Al
   revés, el cuadrado saldría como un paralelogramo inclinado. */
.rz-zona{fill:transparent;pointer-events:all}
.rz-cuadros rect:not(.rz-zona){
  /* Trazo plano y algo más grueso: con non-scaling-stroke, al achatarse el
     rombo en la isometría la línea se renderizaba entrecortada. */
  fill:none;stroke:#EE4C01;stroke-width:2.4;
  transition:transform .6s cubic-bezier(.68,0,.24,1),stroke-width .25s ease;
  /* El cursor no lo reciben las piezas —se mueven— sino la zona fija. */
  pointer-events:none;
  /* En reposo quedan en la posición de partida: apiladas. Es el mismo estado
     que el 0% del keyframe, así que al arrancar el movimiento no hay salto. */
  transform:translate(var(--ax,0px),var(--ay,0px)) scale(var(--as,1),var(--asy,1)) rotate(var(--ar,45deg));
  transition:transform .6s cubic-bezier(.68,0,.24,1);
}
/* El reordenamiento ocurre sólo con el cursor encima. Al retirarlo la
   animación desaparece y la transición lleva la pieza de vuelta a la pila
   desde donde haya quedado, en lugar de saltar. */
.rz-cuadros.activo rect:not(.rz-zona),
.rz-cuadros:hover rect:not(.rz-zona){
  animation:rzMorfo 5.2s cubic-bezier(.68,0,.24,1) infinite both;
}
.rz-cuadros.activo rect:nth-child(3),.rz-cuadros:hover rect:nth-child(3){animation-delay:.08s}
.rz-cuadros.activo rect:nth-child(4),.rz-cuadros:hover rect:nth-child(4){animation-delay:.16s}
.rz-cuadros.activo rect:nth-child(5),.rz-cuadros:hover rect:nth-child(5){animation-delay:.24s}
@keyframes rzMorfo{
  0%,18%  {transform:translate(var(--ax,0px),var(--ay,0px)) scale(var(--as,1),var(--asy,1)) rotate(var(--ar,45deg))}
  46%,76% {transform:translate(var(--bx,0px),var(--by,0px)) scale(var(--bs,1),var(--bs,1)) rotate(var(--br,45deg))}
  100%    {transform:translate(var(--ax,0px),var(--ay,0px)) scale(var(--as,1),var(--asy,1)) rotate(var(--ar,45deg))}
}
/* Los cuadrados nacen achatados a la mitad: eso es la isometría. */
.rz-cuadros rect:not(.rz-zona){--asy:.5}

/* ── Disco: el anillo punteado gira ── */
.rz-disco-relleno{fill:#D9DBE0}
.rz-disco-borde{fill:none;stroke:rgba(13,15,26,.4);stroke-width:1.2;stroke-dasharray:3 5;
  animation:rzGira 20s linear infinite reverse}

/* ── Tile del asterisco: los rayos giran ── */
.rz-aster rect{fill:var(--azul)}
.rz-aster-rayos{animation:rzGira 34s linear infinite}
.rz-aster-rayos path{fill:none;stroke:#fff;stroke-width:1.4}
.rz-aster-centro{fill:var(--naranja)}

/* ── Tile de la flecha de puntos: avanzan ── */
.rz-avance rect{fill:var(--tile)}
.rz-avance-puntos{animation:rzAvanza 4.8s ease-in-out infinite}
.rz-avance-puntos circle{fill:var(--naranja)}
@keyframes rzAvanza{0%,100%{transform:translateX(-4px)}50%{transform:translateX(4px)}}

/* ── Retícula fina de abajo ── */
.rz-mini-puntos circle{fill:var(--naranja);animation:rzEntra 5.4s ease-in-out infinite}
.rz-mini-puntos circle:nth-child(2){animation-delay:.35s}
.rz-mini-puntos circle:nth-child(3){animation-delay:.7s}
.rz-mini-puntos circle:nth-child(4){animation-delay:1.05s}
.rz-mini-puntos circle:nth-child(5){animation-delay:1.4s}

/* ── La K rota de a un cuarto, con pausa en cada apoyo ── */
.rz-ka{animation:rzRota 13s cubic-bezier(.62,0,.3,1) infinite}
@keyframes rzRota{
  0%,20%  {transform:rotate(0deg)}
  25%,45% {transform:rotate(90deg)}
  50%,70% {transform:rotate(180deg)}
  75%,95% {transform:rotate(270deg)}
  100%    {transform:rotate(360deg)}
}
@keyframes rzGira{to{transform:rotate(360deg)}}

/* ══ Respuesta al cursor: movimiento, no resplandor ══
   Cada pieza hace algo propio y verificable. Nada de sombras ni brillos: lo
   que cambia es la posición, el tamaño o el recorrido de sus partes. */
.rz{transition:transform .5s var(--ease)}
/* La cruz estira sus ejes hasta el borde de la celda */
.rz-cruz:hover .rz-cruz-ejeh{animation:none;transform:scaleX(1.32)}
.rz-cruz:hover .rz-cruz-ejev{animation:none;transform:scaleY(1.24)}
.rz-cruz:hover .rz-cruz-punto{animation-duration:.9s}
/* La flecha recorre su tile en diagonal */
.rz-flecha:hover .rz-flecha-trazo{transform:translate(7px,-7px)}
.rz-flecha-trazo{transition:transform .5s var(--ease)}
/* Los cinco puntos se encienden más seguido y se separan */
.rz-serie:hover circle{animation-duration:1.5s}
.rz-serie:hover{transform:scaleX(1.14)}
/* El símbolo salta más seguido */
.rz-simbolo:hover{animation-duration:1.4s}
/* El anillo se abre */
.rz-anillo:hover{transform:scale(1.22)}
/* El disco late */
.rz-disco:hover .rz-disco-relleno{transform:scale(1.3)}
.rz-disco-relleno{transition:transform .5s var(--ease)}
/* Los rayos del asterisco se alargan */
.rz-aster:hover .rz-aster-rayos{transform:scale(1.24)}
.rz-aster-rayos{transition:transform .5s var(--ease)}
/* La flecha de puntos cruza el tile */
.rz-avance:hover .rz-avance-puntos{animation-duration:1.2s}
/* La K adelanta un cuarto de vuelta y se queda ahí */
.rz-ka:hover{animation-play-state:paused;transform:rotate(90deg)}
/* La retícula de abajo enciende sus puntos más rápido */
.rz-mini:hover circle{animation-duration:1.6s}

@media(prefers-reduced-motion:reduce){
  .ret *{animation:none!important;transition:none!important}
  .rz-flecha-trazo path{stroke-dashoffset:0}
}

/* ══════════ MAPAS DE SEDE ══════════
   El iframe va sin bordes propios: el marco lo da la tarjeta, para que el mapa
   entre en el sistema en lugar de parecer pegado encima. */
.mapa-sede{
  border:1px solid var(--linea);border-radius:var(--r-lg);overflow:hidden;
  background:var(--blanco);box-shadow:var(--sombra-sm);
  transition:box-shadow .3s var(--ease),border-color .3s var(--ease);
}
.mapa-sede:hover{box-shadow:var(--sombra-md);border-color:var(--linea-fuerte)}
.mapa-sede iframe{
  display:block;width:100%;height:280px;border:0;
  /* El mapa arranca algo desaturado y toma color al apuntarlo: así no compite
     con el contenido de la página cuando no es el foco. */
  filter:saturate(.82);transition:filter .35s var(--ease);
}
.mapa-sede:hover iframe{filter:saturate(1)}
.mapa-sede-pie{
  display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:18px 22px;border-top:1px solid var(--linea);flex-wrap:wrap;
}
.mapa-sede-pie b{display:block;font-size:1rem;color:var(--tinta)}
.mapa-sede-pie span{font-size:.9rem;color:var(--tenue)}
.mapa-sede-pie .arrow-link{margin:0}

/* ══════════ SEDES ══════════
   Cada tarjeta se presenta con la silueta de su provincia recortada del mapa
   federal de más arriba: el mismo path y las mismas coordenadas, así que el
   degradado (userSpaceOnUse sobre 1100) le devuelve el color exacto que la
   provincia tiene allá. El trazo se dibuja al entrar en pantalla y el relleno
   entra al apuntar la tarjeta. */
.sedes{display:grid;grid-template-columns:repeat(3,1fr);gap:26px;align-items:stretch}
/* Sin recuadro: las tres piezas se apoyan directo sobre el fondo de la página.
   Lo único que queda encerrado es el mapa, y sólo por sus esquinas: cualquier
   borde alrededor del conjunto volvía a leerse como tarjeta. */
.sede{display:flex;flex-direction:column;margin:0;background:none;border:0}

.sede-cabeza{display:flex;align-items:center;gap:18px;padding:0 2px 18px}
.sede-silueta{flex:0 0 auto;height:96px;width:auto;overflow:visible}
.sede-forma{
  fill:url(#tkg-sede);fill-opacity:0;
  stroke:url(#tkg-sede);stroke-width:var(--sw,3);stroke-linejoin:miter;
  /* pathLength="1" normaliza el recorrido: el mismo dasharray sirve para las
     dos siluetas sin medir cuánto mide cada contorno. */
  stroke-dasharray:1;stroke-dashoffset:0;
  transition:fill-opacity .5s var(--ease);
}
.js .sede-forma{stroke-dashoffset:1}
.js .reveal.shown .sede-forma{stroke-dashoffset:0;transition:stroke-dashoffset 1.5s var(--ease) .15s,fill-opacity .5s var(--ease)}
.sede:hover .sede-forma{fill-opacity:.12}

.sede-punto{transition:opacity .4s var(--ease) .9s}
.js .sede-punto{opacity:0}
.js .reveal.shown .sede-punto{opacity:1}
.sede-nucleo{fill:var(--azul)}
.sede-eco{fill:var(--azul);transform-origin:0 0;animation:sedeEco 2.8s var(--ease) infinite}
.sede:hover .sede-eco{animation-duration:1.5s}
@keyframes sedeEco{
  0%{transform:scale(1);opacity:.45}
  70%{transform:scale(3.6);opacity:0}
  100%{transform:scale(3.6);opacity:0}
}

/* El símbolo de marca ocupa el lugar de la silueta en la tarjeta del equipo,
   que es la que queda justo entre las dos provincias. */
.sede-marca{height:68px;color:var(--azul)}
.sede-marca use{fill:var(--azul)}

.sede-rotulo{min-width:0}
.sede-rotulo h3{font-size:1.25rem;font-weight:500;line-height:1.15;margin:.2em 0 .26em}
.sede-rotulo>span:last-child{display:block;font-size:.86rem;color:var(--tenue)}

.sede-mapa{margin-top:auto;border-radius:var(--r-md);overflow:hidden}
.sede-mapa iframe{
  display:block;width:100%;height:252px;border:0;
  /* Arranca en blanco y negro y toma color al apuntarlo: así el color queda
     reservado para la silueta de marca de arriba y para el mapa que se está
     mirando, no para los tres a la vez. */
  filter:grayscale(1) contrast(1.04);
  transition:filter .55s var(--ease);
}
.sede:hover .sede-mapa iframe{filter:grayscale(0) contrast(1)}
.sede-figura .sede-mapa{display:grid;place-items:center;height:252px}
.sede-figura .morfo svg{max-width:200px}
/* El gráfico acompaña el adelgazamiento del resto de la pieza. */
.sede-figura .morfo-figura{stroke-width:1.3}
.sede-figura .morfo-guia{stroke-width:.9}
.sede-ir{margin:14px 0 0;padding:0 2px}

@media (max-width:900px){
  .sedes{grid-template-columns:1fr}
  .sede-silueta{height:84px}
}
@media (prefers-reduced-motion:reduce){
  .sede-eco{animation:none;opacity:0}
  .sede-forma{stroke-dashoffset:0}
}

/* ══════════ CINTA DE FOTOS ══════════
   Reemplaza al carrusel de cruces por opacidad: con seis fotos, el movimiento
   continuo muestra todas sin obligar a esperar turnos ni a tocar puntitos.
   La pista lleva dos copias del grupo y se desplaza exactamente el 50%: al
   terminar, la segunda copia está donde arrancó la primera y el bucle no tiene
   costura. Por eso el ancho es max-content y no un porcentaje. */
.fototira{
  position:relative;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
}
.fototira-pista{
  display:flex;width:max-content;
  animation:fototiraCorre 52s linear infinite;will-change:transform;
}
@keyframes fototiraCorre{to{transform:translateX(-50%)}}
/* Al pasar el cursor la cinta se detiene: es la manera de poder mirar una foto
   sin perseguirla. */
.fototira:hover .fototira-pista{animation-play-state:paused}
.fototira-grupo{display:flex;gap:20px;padding:0 10px}
.fototira-item{
  margin:0;flex:none;width:clamp(260px,30vw,420px);
  border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--linea);
  background:var(--blanco);box-shadow:var(--sombra-sm);
  transition:transform .4s var(--ease),box-shadow .4s var(--ease);
}
.fototira-item img{
  display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover;
  transition:scale .6s var(--ease);
}
/* La foto apuntada se adelanta y su imagen se acerca un poco: el gesto dice
   cuál se está mirando. */
/* Las fotos panorámicas no entran en 3:2 sin dejar gente afuera: llevan una
   caja proporcionalmente más ancha y exactamente la misma altura que el resto,
   así la cinta sigue pareja y no se recorta a nadie. */
.fototira-item.panoramica{width:clamp(328px,37.9vw,530px)}
.fototira-item.panoramica img{aspect-ratio:1515/800}

.fototira-item:hover{transform:translateY(-6px);box-shadow:var(--sombra-md)}
.fototira-item:hover img{scale:1.06}

@media(prefers-reduced-motion:reduce){
  .fototira-pista{animation:none;flex-wrap:wrap;justify-content:center;width:100%}
  .fototira-grupo:last-child{display:none}
  .fototira{-webkit-mask-image:none;mask-image:none}
  .fototira-grupo{flex-wrap:wrap;justify-content:center}
}

@media(prefers-reduced-motion:reduce){
}

.todo{
  display:inline-block;background:rgba(238,76,1,.08);color:#A33500;
  border:1px dashed rgba(238,76,1,.4);border-radius:4px;padding:1px 8px;
  font-size:.82em;font-weight:600;
}

/* ══════════ FORMULARIO ══════════ */
.form-card{
  position:relative;
  background:var(--blanco);border:1px solid var(--linea);border-radius:var(--r-xl);
  padding:44px;box-shadow:var(--sombra-md);
}
.field{margin-bottom:20px}
.field label{display:block;font-size:.87rem;font-weight:600;margin-bottom:8px;color:var(--tinta)}
.field input,.field select,.field textarea{
  width:100%;padding:14px 16px;border:1.5px solid var(--linea);border-radius:var(--r-sm);
  font:inherit;font-size:.96rem;background:var(--lienzo);color:var(--tinta);
  transition:border-color .2s,box-shadow .2s,background .2s;
}
.field input::placeholder,.field textarea::placeholder{color:var(--tenue)}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--azul);background:var(--blanco);
  box-shadow:0 0 0 4px rgba(24,62,235,.1);
}
.field textarea{min-height:130px;resize:vertical}
.field input[type=file]{padding:12px 14px;background:var(--blanco);cursor:pointer}
.form-note{font-size:.83rem;color:var(--tenue);margin-top:16px;text-align:center}
.form-status{margin-top:16px;text-align:center;font-size:.9rem;font-weight:600}
.form-status.ok{color:#0B7A3B}
.form-status.err{color:#B42318}
.form-hp{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* Datos de contacto con icono */
.contacto-lista{margin-top:28px;display:flex;flex-direction:column;gap:18px}
.contacto-lista li{display:flex;align-items:center;gap:14px;font-size:.98rem;color:var(--texto)}
.contacto-lista .ico{width:1.5rem;height:1.5rem}
.contacto-lista b{color:var(--tinta);font-weight:600}

/* ══════════ CTA FINAL ══════════ */
.cta-final{text-align:center}
.cta-final .actions{justify-content:center}

/* ══════════ FOOTER ══════════ */
.footer{background:var(--navy);color:#fff;padding-top:84px;position:relative;overflow:hidden}
.footer::before{
  content:"";position:absolute;top:-30%;left:-6%;width:620px;height:620px;pointer-events:none;
  background:radial-gradient(circle,rgba(24,62,235,.38) 0%,transparent 66%);
}
.footer .container{position:relative}
.foot-grid{display:grid;grid-template-columns:2.1fr 1fr 1fr 1fr;gap:48px;padding-bottom:60px}
.foot-brand p{color:var(--sobre-oscuro-70);font-size:.94rem;margin-top:20px;max-width:32ch;line-height:1.62}
/* Certificado IRAM en el pie. La imagen ya trae su plancha blanca —así se
   veía en el sitio anterior sobre el navy—, así que acá sólo se le redondean
   las esquinas y se le da el ancho. Enlaza al PDF, y por eso reacciona al
   apuntarlo en vez de quedar como una estampa muerta. */
.foot-cert{display:inline-block;margin-top:26px;border-radius:var(--r-sm);overflow:hidden;line-height:0}
.foot-cert img{width:260px;height:auto;display:block;transition:transform .3s var(--ease)}
.foot-cert:hover img{transform:scale(1.03)}
.foot-cert:focus-visible{outline:2px solid #6E86FF;outline-offset:3px}
@media (max-width:700px){.foot-cert img{width:220px}}

.foot-col h4{
  font-size:.73rem;font-weight:700;letter-spacing:.15em;text-transform:uppercase;
  color:var(--sobre-oscuro-45);margin-bottom:18px;font-family:var(--texto-font);
}
.foot-col a{display:block;padding:7px 0;font-size:.95rem;color:var(--sobre-oscuro-70);transition:color .18s}
.foot-col a:hover{color:#fff}
.foot-bottom{
  border-top:1px solid rgba(255,255,255,.13);padding:28px 0;display:flex;
  justify-content:space-between;gap:18px;flex-wrap:wrap;font-size:.87rem;color:var(--sobre-oscuro-45);
}

/* ══════════ SCROLL REVEAL ══════════
   Sólo se oculta si el JS está vivo (clase .js en <html>). Sin JS el
   contenido queda visible: nunca una página en blanco. */
.reveal{transition:opacity .7s var(--ease),transform .7s var(--ease)}
.js .reveal{opacity:0;transform:translateY(24px)}
.js .reveal.shown{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
  .js .reveal{opacity:1;transform:none;transition:none}
}

/* ══════════ RESPONSIVE ══════════ */
@media(max-width:1080px){
  .nav-menu>a:not(.nav-cta),.nav-drop>button{padding:10px 11px;font-size:.92rem}
  .g4,.grid-reticula.g4{grid-template-columns:repeat(2,1fr)}
  .steps.four{grid-template-columns:repeat(2,1fr)}
  .flow{grid-template-columns:repeat(2,1fr)}
  .hero-grid{grid-template-columns:1fr;gap:56px}
  .orbe{max-width:400px}
  .eco-explorer{grid-template-columns:minmax(0,1fr) minmax(0,320px);gap:36px}
  .eco-stage{max-width:470px}
  .eco-pill{font-size:.73rem;padding:8px 12px}
  .dark-band{padding:52px 40px}
}
@media(max-width:900px){
  .burger{display:block}
  .nav-menu{
    position:fixed;top:78px;left:0;right:0;flex-direction:column;align-items:stretch;gap:2px;
    background:var(--blanco);padding:18px;border-bottom:1px solid var(--linea);
    box-shadow:var(--sombra-lg);display:none;max-height:calc(100vh - 78px);overflow-y:auto;
  }
  .nav-menu.open{display:flex}
  .nav-menu>a:not(.nav-cta),.nav-drop>button{padding:14px;font-size:1rem;width:100%}
  .nav-drop{width:100%}
  .dropdown{
    position:static;opacity:1;visibility:visible;transform:none;box-shadow:none;
    border:none;min-width:0;padding:0 0 0 12px;display:none;
  }
  .nav-drop.open .dropdown{display:block}
  .caret{margin-left:auto}
  /* El CTA vive dentro del menú: en móvil va al final, a todo el ancho.
     Antes quedaba fuera de la vista y no había forma de llegar a contacto. */
  .nav-cta{width:100%;justify-content:center;margin:12px 0 0;padding:14px 20px;font-size:1rem}
  section{padding:76px 0}
  .g3,.grid-reticula.g3{grid-template-columns:repeat(2,1fr)}
  .foot-grid{grid-template-columns:1fr 1fr;gap:36px}
  .eco-explorer{grid-template-columns:1fr;gap:40px}
  .eco-stage{--rx:29%;--ry:30%;max-width:440px;aspect-ratio:.96}
  .eco-panel{max-width:520px;margin:0 auto}
  .form-card{padding:32px 26px}
}
@media(max-width:640px){
  .container{padding:0 20px}
  .g2,.g3,.g4,.grid-reticula.g2,.grid-reticula.g3,.grid-reticula.g4,
  .steps,.steps.four,.flow{grid-template-columns:1fr}
  .stats-grid{grid-template-columns:1fr 1fr;gap:32px 20px}
  .foot-grid{grid-template-columns:1fr}
  .layer{flex-direction:column;align-items:flex-start;gap:14px}
  .layer .tags{margin-left:0}
  .layer-label{min-width:0}
  .hero{padding:56px 0 64px}
  .dark-band{padding:38px 26px;border-radius:var(--r-lg)}
  .kpi-row{gap:26px}
  .actions .btn{width:100%}
  .card,.grid-reticula>*{padding:28px 24px}
  /* Apilados, la flecha pasa a apuntar hacia abajo */
  .paso-flecha{right:50%;top:auto;bottom:-18px;translate:50% 0;rotate:90deg}
  .orbe-nucleo{width:54%}
  /* En el timeline el riel pasa a la izquierda y todo se alinea a un lado */
  .vtimeline::before,.vtimeline::after{left:9px;translate:none}
  .vt-item{width:100%;left:0!important;text-align:left!important;padding:0 0 32px 40px}
  .vt-item:nth-child(odd) .vt-node,.vt-item:nth-child(even) .vt-node{left:0;right:auto}
  .vt-item:nth-child(odd):hover .vt-card,.vt-item:nth-child(even):hover .vt-card{transform:translateX(4px)}
  .js .vt-item:nth-child(odd),.js .vt-item:nth-child(even){transform:translateY(22px)}
  .js .vt-item.shown{transform:none}
  .vt-card{padding:22px}
}
@media(max-width:480px){
  .eco-stage{--rx:28%;--ry:29%;max-width:340px;aspect-ratio:.94}
  .eco-pill{font-size:.66rem;padding:6px 10px;gap:6px}
  .eco-pill .lbl-full{display:none}
  .eco-pill .lbl-short{display:inline}
}
@media(prefers-reduced-motion:reduce){
  .eco-ring,.eco-link,.orbe-anillo,.eco-logo{animation:none!important}
  .js .vtimeline::before{scale:1 1;transition:none}
  .js .vt-item{opacity:1;transform:none!important;transition:none}
  .vtimeline.shown::after{animation:none;opacity:0}
}
