/* ═══════════════════════════════════════════════════════════════════════
   SECCIONES DE LA HOME
   Solo se carga en la home. Lo comun (header, footer, hero, tarjetas de
   las paginas internas) vive en estructura.css.
   ═══════════════════════════════════════════════════════════════════════ */

/* Ancla de los triangulos: fija y del tamaño del viewport, asi la escena
   los reparte por toda la pagina en vez de existir una por seccion. */
.ancla-3d--fija {
  position: fixed;
  inset: 0;
  z-index: 0;
}
.gama-nulo .ancla-3d--fija,
.reduce-movimiento .ancla-3d--fija { display: none; }


/* ═══════════════════════ 01 · MANIFIESTO ═════════════════════════════ */

.manifiesto {
  position: relative;
  overflow: hidden;
  background: var(--azul-marca); /* el mismo azul del preloader */
}


/* Menos elementos, mas personalidad: el texto a la izquierda y el resto
   libre para la medusa, que nunca nada por encima de el (medusa.js lo
   mide: data-medusa-evita). */
.manifiesto__interior {
  position: relative;
  display: flex;
  align-items: center;
  min-height: min(90vh, 52rem);
}

.manifiesto__texto {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-6);
}

.manifiesto__titulo {
  font-size: clamp(1.9rem, 3.6vw, 3.5rem);
  line-height: 1.05;
  text-wrap: balance;
}
.manifiesto__frase { display: block; }
.manifiesto__frase + .manifiesto__frase { margin-top: 0.35em; }

/* Titular que se decodifica (ui/manifiesto.js). Las dos frases van
   invisibles en la misma celda y reservan el alto: nada salta. */
.codigo { display: grid; }
.codigo__fantasma, .codigo__visible { grid-area: 1 / 1; }
.codigo__fantasma { visibility: hidden; }
.codigo__visible b { font-weight: inherit; color: var(--acento); }
.codigo__visible i { font-style: normal; color: var(--acento-brillo); opacity: 0.8; }
.codigo__visible--fin {
  text-shadow: 0 0 0.5em color-mix(in srgb, var(--acento) 45%, transparent);
  transition: text-shadow 900ms ease;
}

.manifiesto__bajada {
  position: relative;
  isolation: isolate;          /* la red de lineas va detras del texto */
  max-width: var(--ancho-texto);
  font-size: clamp(1.05rem, 1.3vw, 1.25rem);
  line-height: 1.95;           /* aire entre renglones para las conexiones */
  color: var(--texto);
}

/* Bajada que se conecta (ui/manifiesto.js). Cada palabra clave lleva su
   texto real invisible debajo (reserva el ancho) y encima la capa que se
   decodifica: el parrafo nunca se reacomoda. */
.bajada__palabra {
  display: inline-grid;
  white-space: nowrap;
  transition: color 500ms ease, opacity 500ms ease;
}
.bajada__palabra > * { grid-area: 1 / 1; }
.bajada__fantasma { color: transparent; }  /* lo lee el lector de pantalla */
.bajada__palabra i { font-style: normal; color: var(--acento-brillo); }
.bajada__palabra.es-nodo,
.bajada__palabra.es-resultado { color: var(--acento); font-weight: inherit; }
.bajada__palabra.es-resultado { text-shadow: 0 0 0.6em color-mix(in srgb, var(--acento) 50%, transparent); }
.bajada__palabra.es-origen { opacity: 0.45; }

.bajada__red {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: -1;
}
.bajada__trazo {
  fill: none;
  stroke: var(--acento);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.75;
}
.bajada__trazo--puente { stroke-dasharray: 2 5; opacity: 0.9; }
.bajada__nudo { fill: var(--acento); transform-box: fill-box; transform-origin: center; }
.bajada__pulso {
  fill: var(--verde-200);
  filter: drop-shadow(0 0 4px var(--acento-brillo));
}

/* Desktop: el texto ocupa poco mas de la mitad y la medusa pasea por la
   derecha. Mobile: el texto arriba y debajo un espacio para la medusa. */
@media (min-width: 900px) {
  .manifiesto__texto { max-width: min(44rem, 58%); }
}
@media (max-width: 899px) {
  .manifiesto__interior {
    align-items: flex-start;
    min-height: 0;
    padding-bottom: 65svh;
  }
}


/* ═════════════════════ 02 · TRABAJO SELECCIONADO ═════════════════════ */

.trabajo {
  position: relative;
  overflow: hidden;
}

.trabajo__interior {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-6);
}
.trabajo__bajada {
  font-size: clamp(1.05rem, 1.3vw, 1.25rem);
  line-height: 1.55;
  color: var(--texto);
}
.trabajo__enlace { margin-top: var(--esp-4); }

/* ── El logo como fuente de energia (fuente/js/ui/energia.js) ────────
   Base oscura que no compite con el texto; encima, destellos por letra,
   un pulso que recorre los contornos y rayos chicos. Todo detras del
   texto. */
.energia {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-inline: var(--margen-lateral);
  pointer-events: none;
}
.energia__logo {
  position: relative;
  width: min(100%, 78rem);
  height: auto;
  overflow: visible;
}
.energia__base {
  fill: color-mix(in srgb, var(--verde-700) 42%, var(--azul-900));
  stroke: color-mix(in srgb, var(--verde-700) 42%, var(--azul-900));
  stroke-width: 10;
  stroke-linejoin: round;
}
.energia__flash {
  fill: color-mix(in srgb, var(--verde-500) 55%, var(--azul-900));
  stroke: color-mix(in srgb, var(--verde-500) 55%, var(--azul-900));
  stroke-width: 10;
  stroke-linejoin: round;
}
.energia__flash > g { opacity: 0; }
.energia__contorno {
  fill: none;
  stroke: var(--verde-400);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  stroke-linejoin: round;
  stroke-linecap: round;
  stroke-dasharray: 0.22 0.78;
  filter: drop-shadow(0 0 4px var(--verde-400));
}
.energia__contorno > g { opacity: 0; }
.energia__rayos {
  fill: var(--verde-500);
  opacity: 0.55;
}
/* Resplandor ambiental: luz verde y azul muy sutil detras del logo. */
.energia__resplandor {
  position: absolute;
  inset: 10% 0 10% 25%;
  background:
    radial-gradient(ellipse 45% 55% at 62% 50%, color-mix(in srgb, var(--verde-500) 22%, transparent), transparent 70%),
    radial-gradient(ellipse 55% 65% at 40% 55%, color-mix(in srgb, var(--azul-500) 30%, transparent), transparent 72%);
  opacity: 0.45;
  filter: blur(20px);
}

@media (max-width: 899px) {
  .energia { align-items: flex-end; padding-bottom: var(--esp-16); }
  .energia__logo { width: 100%; opacity: 0.8; }
}

/* ══════════════════════ 03-05 · PROYECTOS ════════════════════════════ */

.proyecto {
  position: relative;
  background: var(--azul-900);
  overflow: hidden;
}

.proyecto__interior {
  display: grid;
  gap: var(--esp-12);
  align-items: center;
}

@media (min-width: 900px) {
  .proyecto__interior { grid-template-columns: 1.25fr 1fr; gap: var(--esp-16); }

  /* El layout alterna: un bloque con el mockup a la izquierda, el
     siguiente al reves. El build decide el lado segun la posicion. */
  .proyecto[data-lado="derecha"] .proyecto__marco { order: 2; }
  .proyecto[data-lado="derecha"] .proyecto__texto { order: 1; }
}

/* Fondo del bloque: poster o video, siempre muy atenuado y con un velo
   encima. Es ambientacion; el protagonista es el mockup. */
.proyecto__fondo {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.proyecto__fondo::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Dos capas: un tinte azul que trae el video a la paleta, y un degradado
     que lo apaga del lado DONDE VA EL TEXTO. Con lado="izquierda" el mockup
     esta a la izquierda y el texto a la derecha, asi que se oscurece la
     derecha; con lado="derecha" es al reves. */
  background:
    linear-gradient(90deg,
      color-mix(in srgb, var(--azul-900) 30%, transparent) 0%,
      color-mix(in srgb, var(--azul-900) 62%, transparent) 48%,
      color-mix(in srgb, var(--azul-900) 90%, transparent) 100%),
    color-mix(in srgb, var(--azul-600) 32%, transparent);
}
.proyecto[data-lado="derecha"] .proyecto__fondo::after {
  background:
    linear-gradient(270deg,
      color-mix(in srgb, var(--azul-900) 30%, transparent) 0%,
      color-mix(in srgb, var(--azul-900) 62%, transparent) 48%,
      color-mix(in srgb, var(--azul-900) 90%, transparent) 100%),
    color-mix(in srgb, var(--azul-600) 32%, transparent);
}

/* En pantallas angostas el bloque se apila: el mockup arriba y el texto
   abajo. El velo tiene que oscurecer abajo, no a un costado. */
@media (max-width: 899px) {
  .proyecto__fondo::after,
  .proyecto[data-lado="derecha"] .proyecto__fondo::after {
    background:
      linear-gradient(180deg,
        color-mix(in srgb, var(--azul-900) 45%, transparent) 0%,
        color-mix(in srgb, var(--azul-900) 78%, transparent) 42%,
        color-mix(in srgb, var(--azul-900) 94%, transparent) 100%),
      color-mix(in srgb, var(--azul-600) 32%, transparent);
  }
}

/* Y arriba y abajo se funde con el fondo de la seccion, para que el corte
   entre bloques no sea una linea dura. */
.proyecto__fondo::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg,
    var(--azul-900) 0%,
    transparent 18%,
    transparent 82%,
    var(--azul-900) 100%);
}

.proyecto__video,
.proyecto__fondo > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* El poster del <video> se ve aunque no haya src: es el respaldo en
     celulares y mientras el video no cargo. */
  opacity: 0.9;
  filter: saturate(0.8) contrast(1.05);
}

@supports not (color: color-mix(in srgb, red 50%, transparent)) {
  .proyecto__fondo::after {
    background: linear-gradient(90deg, rgba(11,15,56,0.3), rgba(11,15,56,0.9));
  }
  .proyecto[data-lado="derecha"] .proyecto__fondo::after {
    background: linear-gradient(270deg, rgba(11,15,56,0.3), rgba(11,15,56,0.9));
  }
}

/* Marco del mockup. */
.proyecto__marco {
  position: relative;
  border: 1px solid var(--borde);
  border-radius: 6px;
  overflow: hidden;
  background: var(--azul-800);
  box-shadow: 0 30px 80px -40px rgba(0, 0, 0, 0.8);
}
.proyecto__captura {
  width: 100%;
  height: auto;
  display: block;
  transition: transform 1.4s var(--curva-salida), filter 1.4s ease;
}

/* ── Carga de la captura ──────────────────────────────────────────────
   Solo existe si carga-captura.js marco el marco con .con-carga. */
.proyecto__carga { display: none; }

.con-carga .proyecto__carga {
  display: grid;
  place-items: center;
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--azul-900);
  clip-path: inset(0 0 0 0);
  transition: clip-path 0.9s cubic-bezier(0.76, 0, 0.24, 1);
}

/* El liquido verde: sube segun el porcentaje (--carga, de 0 a 1). */
.proyecto__carga-relleno {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--verde-600), var(--acento) 70%, var(--verde-400));
  transform-origin: bottom;
  transform: scaleY(var(--carga, 0));
  box-shadow: 0 -2px 24px var(--acento-brillo);
}

.proyecto__carga-pct {
  position: relative;
  font-family: var(--fuente-titulo);
  font-weight: 900;
  font-size: clamp(2.5rem, 6vw, 5rem);
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--texto);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 4px 30px rgba(6, 9, 35, 0.45);
}

/* Mientras carga, la captura espera un poco agrandada y desaturada. */
.con-carga:not(.es-cargado) .proyecto__captura {
  transform: scale(1.08);
  filter: saturate(0.2) brightness(0.7);
}

/* Al 100% la pantalla verde se va hacia arriba y descubre la captura. */
.con-carga.es-cargado .proyecto__carga { clip-path: inset(0 0 100% 0); }

/* Mientras no haya captura, un hueco con la proporcion correcta para que
   el layout no salte cuando lleguen las imagenes reales. */
.proyecto__vacio {
  aspect-ratio: 16 / 10;
  background:
    repeating-linear-gradient(45deg,
      transparent 0 14px,
      color-mix(in srgb, var(--azul-400) 12%, transparent) 14px 28px);
}

.proyecto__texto {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-4);
}
.proyecto__nombre { font-size: var(--t-sub); }
.proyecto__tags {
  display: block;
  line-height: 1.9;
  color: var(--texto-tenue);
}
.proyecto__boton { margin-top: var(--esp-4); }
.proyecto__boton[disabled] { opacity: 0.45; cursor: not-allowed; }


/* ═══════════════════════ 06 · CAPACIDADES ════════════════════════════ */

/* Azul VIXOZ plano (antes se veia el plasma animado). */
.capacidades { background: var(--azul-marca); }
/* Sin el velo oscuro de estructura.css: era para leer sobre el plasma. */
.capacidades::before { content: none; }

.capacidades__interior {
  display: grid;
  gap: var(--esp-12);
  align-items: center;
}
@media (min-width: 1000px) {
  .capacidades__interior { grid-template-columns: 0.85fr 1.15fr; gap: var(--esp-16); }
}

.capacidades__texto {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-6);
}

/* Tarjeta del servicio elegido. Todas en la misma celda de la grilla: el
   alto es el de la mas larga y no salta nada al cambiar. */
.servicios__tarjetas {
  position: relative;
  display: grid;
  width: 100%;
  max-width: 30rem;
}
/* Barrita verde al pie de la tarjeta: se llena mientras se muestra cada
   servicio y al llenarse pasa al siguiente (la anima grafo.js). */
.servicios__progreso {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--acento);
  box-shadow: 0 0 8px var(--acento);
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}
.servicio {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  gap: var(--esp-3);
  padding: var(--esp-6);
  border: 1px solid var(--borde);
  border-radius: 14px;
  background: color-mix(in srgb, var(--azul-900) 82%, transparent);
  backdrop-filter: blur(10px);
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity 0.35s ease, transform 0.35s ease, visibility 0s linear 0.35s;
}
.servicio.es-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.35s ease, transform 0.35s ease, visibility 0s;
}
.servicio--pista {
  align-self: start;
  border-style: dashed;
  background: transparent;
  backdrop-filter: none;
  color: var(--acento);
  font-size: var(--t-chico);
}
.servicio__nombre {
  font-family: var(--fuente-titulo);
  font-weight: 900;
  font-stretch: var(--ancho-titulo);
  font-size: clamp(1.3rem, 1.8vw, 1.6rem);
  text-transform: uppercase;
  line-height: 1.1;
}
.servicio__texto {
  font-size: clamp(1rem, 1.15vw, 1.125rem);
  line-height: 1.55;
}
.servicio__herramientas {
  margin-top: var(--esp-2);
  padding-top: var(--esp-4);
  border-top: 1px solid var(--borde);
  color: var(--texto-tenue);
  font-size: var(--t-chico);
}

/* El contenedor tiene la misma proporcion que el viewBox del SVG, asi los
   nodos HTML (posicionados en %) caen justo sobre los extremos de las
   lineas SVG. */
.grafo {
  position: relative;
  width: 100%;
  aspect-ratio: 1000 / 620;
}

.grafo__lienzo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.grafo__linea {
  fill: none;
  stroke: var(--acento);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.45;
  transition: stroke var(--dur-rapida) ease,
              opacity var(--dur-rapida) ease,
              stroke-width var(--dur-rapida) ease;
}
/* Cuando hay un nodo activo, todo lo que no le pertenece se apaga. */
.grafo--activo .grafo__linea { opacity: 0.14; }
.grafo__linea.es-activa {
  stroke: var(--acento);
  stroke-width: 2.4;
  opacity: 1;
}

.grafo__nodos { position: absolute; inset: 0; }

.grafo__ancla {
  position: absolute;
  transform: translate(-50%, -50%);
}

.grafo__nodo {
  display: flex;
  align-items: center;
  gap: var(--esp-3);
  padding: var(--esp-2);
  border-radius: 999px;
  white-space: nowrap;
  transition: opacity var(--dur-rapida) ease;
}
.grafo--activo .grafo__nodo { opacity: 0.35; }
.grafo--activo .grafo__nodo.es-activo,
.grafo--activo .grafo__nodo.es-vecino { opacity: 1; }

.grafo__punto {
  position: relative;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--acento);
  transition: transform var(--dur-rapida) var(--curva-salida);
}

/* El latido. Cada nodo arranca con un desfase distinto (lo pone el JS). */
.grafo__punto::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--acento);
  animation: latido 2.8s ease-out infinite;
  animation-delay: var(--retraso-latido, 0s);
}
@keyframes latido {
  0%   { transform: scale(1);   opacity: 0.55; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}

.grafo__nodo.es-activo .grafo__punto { transform: scale(1.3); }

.grafo__nombre {
  font-family: var(--fuente-titulo);
  font-weight: 800;
  font-size: clamp(0.7rem, 1.05vw, 0.9rem);
  letter-spacing: 0.01em;
  text-transform: uppercase;
  line-height: 1.15;
  text-align: left;
  white-space: normal;
  max-width: 7.5em;
}
.grafo__nodo.es-activo .grafo__nombre { color: var(--acento); }

@media (prefers-reduced-motion: reduce) {
  .grafo__punto::after { animation: none; opacity: 0; }
}

/* En pantallas chicas el grafo se estira un poco para que los nombres no
   se pisen entre si. */
@media (max-width: 640px) {
  .grafo { aspect-ratio: 1000 / 840; }
  .grafo__nombre { font-size: 0.66rem; max-width: 6em; }
  .grafo__punto { width: 12px; height: 12px; }
}


/* ═════════════════════ 07 · CÓMO TRABAJAMOS ══════════════════════════ */

.proceso { background: var(--azul-900); }

.proceso__titulo { text-align: right; margin-left: auto; }
.proceso__bajada { margin-left: auto; text-align: right; margin-top: var(--esp-6); }

.proceso__linea {
  position: relative;
  width: 100%;
  aspect-ratio: 1000 / 300;
  margin-top: var(--esp-16);
}

.proceso__lienzo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.proceso__curva {
  fill: none;
  stroke: var(--azul-200);
  stroke-width: 1.5;
  opacity: 0.5;
}

.proceso__flecha { fill: var(--acento); }

/* Un destello verde que viaja por la curva, de PENSAMOS a EVOLUCIONAMOS.
   El path usa pathLength="1": el dash ocupa el 9% del recorrido. */
.proceso__pulso {
  fill: none;
  stroke: var(--acento-brillo);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 0.09 0.91;
  stroke-dashoffset: 0.09;
  opacity: 0;
  filter: drop-shadow(0 0 6px var(--acento));
}
.proceso__linea.es-dibujado .proceso__pulso {
  opacity: 1;
  animation: proceso-pulso 4.5s cubic-bezier(0.45, 0, 0.25, 1) infinite;
}
@keyframes proceso-pulso {
  from { stroke-dashoffset: 0.09; }
  to   { stroke-dashoffset: -1; }
}

.proceso__pasos { position: absolute; inset: 0; }

/* El <li> es el punto exacto de la curva. El nombre flota encima. */
.proceso__paso {
  position: absolute;
  width: 0;
  height: 0;
}

/* Punto sobre la curva con un halo que late. */
.proceso__paso::before,
.proceso__paso::after {
  content: '';
  position: absolute;
  left: -6px;
  top: -6px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--acento);
}
.proceso__paso::after {
  animation: latido 2.4s ease-out infinite;
  animation-delay: calc(var(--i, 0) * 0.35s);
}

.proceso__nombre {
  position: absolute;
  bottom: 0.9em;
  left: 0;
  transform: translateX(-50%);
  font-family: var(--fuente-titulo);
  font-size: clamp(1rem, 1.9vw, 1.75rem);
  font-weight: 800;
  letter-spacing: 0.04em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--texto);
  /* Titila como un neon, cada uno a destiempo. */
  animation: proceso-titileo 5.2s steps(1, end) infinite;
  animation-delay: calc(var(--i, 0) * -1.3s);
  transition: color var(--dur-rapida) ease,
              text-shadow var(--dur-rapida) ease,
              transform 0.6s var(--curva-salida);
}

/* El primero y el ultimo no se centran sobre su punto: si no, se salen del
   contenedor. Se apoyan contra su borde. */
.proceso__paso:first-child .proceso__nombre { transform: translateX(-6px); transform-origin: left bottom; }
.proceso__paso:last-child  .proceso__nombre { transform: translateX(calc(-100% + 6px)); transform-origin: right bottom; }

@keyframes proceso-titileo {
  0%, 100% { opacity: 1; }
  41%      { opacity: 0.35; }
  42%      { opacity: 1; }
  44%      { opacity: 0.5; }
  45%      { opacity: 1; }
  78%      { opacity: 0.7; }
  79%      { opacity: 1; }
}

/* El paso activo (lo rota proceso.js): verde, mas grande y con glow. */
.proceso__paso.es-activo .proceso__nombre {
  color: var(--acento);
  text-shadow: 0 0 18px var(--acento), 0 0 42px var(--acento-brillo);
  animation: none;
  transform: translateX(-50%) scale(1.18);
}
.proceso__paso.es-activo:first-child .proceso__nombre { transform: translateX(-6px) scale(1.18); }
.proceso__paso.es-activo:last-child  .proceso__nombre { transform: translateX(calc(-100% + 6px)) scale(1.18); }
.proceso__paso.es-activo::before { box-shadow: 0 0 14px 3px var(--acento-brillo); background: var(--acento-brillo); }

/* Mientras se mezclan las letras, cada glifo provisorio va en verde tenue. */
.proceso__glifo { color: var(--verde-300); opacity: 0.8; }

@media (max-width: 767px) {
  .proceso__titulo,
  .proceso__bajada { text-align: left; margin-left: 0; }
  /* El lienzo tiene la MISMA proporcion que el viewBox: asi los nombres
     (en % de la caja) caen justo sobre sus puntos de la curva. */
  .proceso__linea { aspect-ratio: 1000 / 300; margin-top: var(--esp-12); margin-bottom: var(--esp-12); }
  .proceso__nombre { font-size: 0.72rem; letter-spacing: 0.05em; }
  /* En angosto no entran lado a lado: como la curva sube hacia la
     derecha, cada nombre va ABAJO y a la derecha de su punto (lado libre
     de la curva), en escalera. El ultimo va arriba y a la izquierda. */
  .proceso__linea .proceso__paso .proceso__nombre {
    bottom: auto; top: 0.85em; left: 2px;
    transform: none; transform-origin: left top;
  }
  .proceso__linea .proceso__paso:last-child .proceso__nombre {
    top: auto; bottom: 0.85em; left: auto; right: -6px;
    transform-origin: right bottom;
  }
  .proceso__linea .proceso__paso.es-activo .proceso__nombre { transform: scale(1.12); }
}

@media (prefers-reduced-motion: reduce) {
  .proceso__nombre,
  .proceso__paso::after,
  .proceso__linea.es-dibujado .proceso__pulso { animation: none; }
  .proceso__pulso { display: none; }
}


/* ═══════════════════════════ 08 · ESTUDIO ════════════════════════════ */

.estudio {
  background: var(--azul-900);
  overflow: hidden;
}

.estudio__interior {
  display: flex;
  flex-direction: column;
  gap: var(--esp-12);
}
/* Desktop: texto a la izquierda, la sala de reuniones a la derecha. */
@media (min-width: 1024px) {
  .estudio__interior {
    display: grid;
    grid-template-columns: minmax(0, 30rem) minmax(0, 1fr);
    align-items: center;
    gap: var(--esp-12);
  }
}

/* ── La sala de reuniones en lineas (ui/reunion.js) ──────────────────── */
.reunion { width: 100%; }
.reunion__lienzo {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  fill: none;
  stroke: var(--acento);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--acento) 45%, transparent));
}
.reunion__lienzo .r-tapa { fill: var(--azul-900); }

/* Globos del debate: escondidos hasta que les toca. */
.r-globo__cuerpo {
  transform-box: fill-box;
  transform-origin: 15% 100%;
  opacity: 0;
  transform: scale(0.4) translateY(10px);
  transition: opacity 260ms ease, transform 520ms var(--curva-salida);
}
.r-globo.es-visible .r-globo__cuerpo { opacity: 1; transform: none; }

/* Vivo: cada cosa con su movimiento chico. */
.r-vapor, .r-reloj__minutos, .r-reloj__hora, .r-mano-arriba,
.r-presenta__brazo, .r-mano-senala, .r-espalda--asiente, .r-luz, .r-tendencia {
  transform-box: view-box;
}
.reunion--viva .r-vapor { animation: r-vapor 2.4s ease-in-out infinite; }
.reunion--viva .r-reloj__minutos { transform-origin: 830px 112px; animation: r-giro 12s linear infinite; }
.reunion--viva .r-reloj__hora { transform-origin: 830px 112px; animation: r-giro 144s linear infinite; }
.reunion--viva .r-mano-arriba { transform-origin: 666px 306px; animation: r-saluda 1.8s ease-in-out infinite; }
.reunion--viva .r-presenta__brazo { transform-origin: 303px 194px; animation: r-senala 3.2s ease-in-out infinite; }
.reunion--viva .r-mano-senala { transform-origin: 592px 480px; animation: r-senala 2.6s ease-in-out infinite reverse; }
.reunion--viva .r-espalda--asiente { transform-origin: 760px 470px; animation: r-asiente 2.2s ease-in-out infinite; }
.reunion--viva .r-luz { animation: r-luz 3.6s steps(1, end) infinite; }
.reunion--pausa * { animation-play-state: paused !important; }

@keyframes r-vapor {
  0%, 100% { transform: translateY(0); opacity: 0.9; }
  50%      { transform: translateY(-5px); opacity: 0.35; }
}
@keyframes r-giro    { to { transform: rotate(360deg); } }
@keyframes r-saluda  { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(9deg); } }
@keyframes r-senala  { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(-7deg); } }
@keyframes r-asiente { 0%, 100% { transform: rotate(0deg); } 30% { transform: rotate(-3deg); } 60% { transform: rotate(2deg); } }
@keyframes r-luz     { 0%, 100% { opacity: 1; } 47% { opacity: 0.3; } 49% { opacity: 1; } 52% { opacity: 0.5; } 54% { opacity: 1; } }

/* Movimiento reducido: el dibujo quieto, con un par de globos. */
.reunion--quieta .r-globo:nth-child(1) .r-globo__cuerpo,
.reunion--quieta .r-globo:nth-child(3) .r-globo__cuerpo { opacity: 1; transform: none; }

.estudio__texto {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-6);
  max-width: 34rem;
}

/* Roles del equipo: etiquetas finas con un triangulito verde, como los
   del resto del sitio. Datos: config.roles. */
.estudio__roles {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-2);
}
.estudio__roles li {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-2);
  padding: 0.5em 0.95em;
  border: 1px solid var(--borde-fuerte);
  border-radius: 999px;
  font-size: var(--t-etiqueta);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texto);
  transition: border-color var(--dur-rapida) ease, color var(--dur-rapida) ease;
}
.estudio__roles li::before {
  content: '';
  width: 0.55em;
  height: 0.6em;
  background: var(--acento);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.estudio__roles li:hover { border-color: var(--acento); color: var(--acento); }

/* ── El equipo: constelacion de mascotas 3D ──────────────────────────
   Desktop: cada persona va en su --x/--y (contenido/equipo.json) dentro
   de una caja ancha. Mobile: dos columnas. La escena 3D (equipo.js) mide
   cada .equipo__cara y dibuja la mascota encima; las lineas que las unen
   tambien son 3D. */
.equipo {
  --cara: clamp(6.5rem, 9vw, 8.5rem);
  --cara-grande: clamp(7.5rem, 11.5vw, 11rem);
  position: relative;
}

/* El ancla 3D desborda la caja: asi orejas, crestas y saltos no se
   recortan contra el borde. A la izquierda llega hasta el borde de la
   pantalla, porque las mascotas entran caminando desde ahi. */
.equipo__escena {
  position: absolute;
  inset: -4rem -2rem;
  left: calc(50% - 50vw);
  pointer-events: none;
}

.equipo__lista {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--esp-8) var(--esp-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.equipo__persona {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--esp-3);
  cursor: default;
}

.equipo__cara {
  position: relative;
  width: var(--cara);
  aspect-ratio: 1;
}
.equipo__persona--grande .equipo__cara { width: var(--cara-grande); }

.equipo__nombre {
  font-family: var(--fuente-titulo);
  font-weight: 900;
  font-stretch: var(--ancho-titulo);
  font-size: clamp(0.85rem, 1vw, 1rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: color 0.25s ease, transform 0.35s cubic-bezier(.3, 1.6, .5, 1);
}
/* Mientras caminan, el nombre espera: aparece cuando llega su mascota. */
.equipo--caminan .equipo__nombre { opacity: 0; transform: translateY(0.5em); }
.equipo--caminan .equipo__persona.ha-llegado .equipo__nombre {
  opacity: 1;
  transform: none;
  transition: opacity 0.4s ease 0.35s, transform 0.5s cubic-bezier(.3, 1.6, .5, 1) 0.35s, color 0.25s ease;
}
.equipo--caminan .equipo__persona.ha-llegado.es-activa .equipo__nombre { transform: translateY(3px); }
.equipo__persona.es-activa .equipo__nombre {
  color: var(--acento);
  transform: translateY(3px);
}

/* Sin WebGL: un circulo verde con la inicial en lugar de la mascota. */
.gama-nulo .equipo__cara::before {
  content: attr(data-inicial);
  position: absolute;
  inset: 12%;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--acento-suave);
  border: 1px solid var(--acento);
  color: var(--acento);
  font-family: var(--fuente-titulo);
  font-weight: 900;
  font-size: 2.2rem;
}

@media (min-width: 900px) {
  /* La ola sube hasta quedar al lado del titulo: la caja se mete debajo
     del texto (el arranque de la ola, abajo a la izquierda, no lo toca). */
  .equipo { height: clamp(34rem, 48vw, 44rem); margin-top: -12rem; }
  .equipo__lista { position: absolute; inset: 0; display: block; }
  .equipo__persona {
    position: absolute;
    left: var(--x);
    top: var(--y);
    /* El centro de la cara (no de la persona entera) cae en x/y. */
    transform: translate(-50%, calc(var(--cara) / -2));
  }
  .equipo__persona--grande { transform: translate(-50%, calc(var(--cara-grande) / -2)); }
}

/* ════════════════════════════ 09 · IDEAS ═════════════════════════════ */

.ideas { background: var(--azul-900); }

.ideas__interior {
  display: grid;
  gap: var(--esp-12);
  align-items: start;
}
@media (min-width: 900px) {
  .ideas__interior { grid-template-columns: 0.8fr 1.2fr; gap: var(--esp-16); }
}

.ideas__texto {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-6);
}

.ideas__cards {
  display: grid;
  gap: var(--esp-6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}

.idea-card a {
  display: flex;
  flex-direction: column;
  gap: var(--esp-4);
}

.idea-card__imagen {
  display: block;
  aspect-ratio: 4 / 3;
  border-radius: 4px;
  overflow: hidden;
  background: var(--azul-700);
}
.idea-card__imagen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-media) var(--curva-salida);
}
.idea-card a:hover .idea-card__imagen img { transform: scale(1.05); }

.idea-card__titulo {
  font-family: var(--fuente-titulo);
  font-weight: 800;
  font-size: var(--t-etiqueta);
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  transition: color var(--dur-rapida) ease;
}
.idea-card a:hover .idea-card__titulo { color: var(--acento); }


/* ═══════════════════════════ 10 · CONTACTO ═══════════════════════════ */

.contacto__interior {
  display: grid;
  gap: var(--esp-12);
  align-items: center;
}
/* Dos columnas: texto y globo (el circulo "Hagámoslo realidad" se saco). */
@media (min-width: 900px) {
  .contacto__interior { grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr); gap: var(--esp-12); }
}

/* El circulo magnetico. El JS le escribe un transform; la transicion queda
   fuera a proposito, porque el movimiento ya viene suavizado por frame. */
.contacto__circulo {
  display: grid;
  place-items: center;
  width: clamp(12.5rem, 26vw, 18.5rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--acento);
  color: var(--azul-900);
  text-align: center;
  will-change: transform;
  position: relative;
  transition: background var(--dur-rapida) ease;
}

/* Ancla de la escena 3D: 2.2 veces el circulo, para que las capas tengan
   lugar cuando se abren en abanico (la proporcion vive en contacto.js). */
.contacto__escena {
  position: absolute;
  inset: -60%;
}

/* Con la escena montada, el disco de CSS se apaga y quedan las capas. */
.contacto__circulo.es-3d,
.contacto__circulo.es-3d:hover { background: transparent; }

.contacto__circulo-texto {
  position: relative;
  display: block;
  font-family: var(--fuente-titulo);
  font-weight: 900;
  font-size: clamp(0.95rem, 1.5vw, 1.15rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  will-change: transform;
}
.contacto__circulo-texto svg {
  display: inline-block;
  vertical-align: 1px;
  margin-left: 2px;
}

.contacto__circulo:hover { background: var(--verde-400); }

.contacto__texto {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-6);
}

.contacto__email a {
  font-family: var(--fuente-titulo);
  font-weight: 800;
  font-size: clamp(1.1rem, 2vw, 1.5rem);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  transition: color var(--dur-rapida) ease;
}
.contacto__email a:hover { color: var(--acento); }


/* ── Globo con las oficinas (escenas/globo.js) ──────────────────────── */

.contacto__globo {
  position: relative;
  width: 100%;
  max-width: 34rem;
  justify-self: center;
  aspect-ratio: 1;
}

.contacto__globo-escena {
  position: absolute;
  inset: 0;
}

/* Aro de la lente: cuando el globo se acerco y el mapa llena el circulo,
   le da un borde (el JS escribe --cerca, de 0 a 1). */
.contacto__globo::after {
  content: '';
  position: absolute;
  inset: 0.5%;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--acento) 45%, transparent);
  box-shadow: 0 0 2.5rem color-mix(in srgb, var(--acento) 22%, transparent),
              inset 0 0 2.5rem color-mix(in srgb, var(--azul-950) 70%, transparent);
  opacity: calc(var(--cerca, 0) * 1.4 - 0.4);
  pointer-events: none;
}

/* Sin WebGL no hay globo: no se reserva el lugar. */
.gama-nulo .contacto__globo { display: none; }

/* Nombre de cada ciudad. El JS lo lleva (transform) hasta el punto 3D;
   el texto se corre a un costado para no tapar la marca. */
.globo__lugar {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  font-family: var(--fuente-titulo);
  font-weight: 800;
  font-size: var(--t-etiqueta);
  letter-spacing: var(--tracking-etiqueta);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--texto);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-lenta) var(--curva-salida);
  will-change: transform;
}
.globo__lugar::before {
  content: '';
  width: var(--esp-6);
  height: 1px;
  background: var(--acento);
}

/* Buenos Aires sale hacia el este (sobre el mar) y Mendoza hacia el oeste
   (sobre la cordillera): asi ninguna pisa el arco que las une. */
.globo__lugar { margin: -0.6em 0 0 var(--esp-3); }
.globo__lugar--oeste {
  flex-direction: row-reverse;
  margin: -0.6em 0 0 0;
  translate: calc(-100% - var(--esp-3)) 0;
}

/* En pantallas angostas no hay lugar a los costados: Mendoza va arriba
   del punto y Buenos Aires abajo, centradas y sin la linea. */
@media (max-width: 599px) {
  .globo__lugar,
  .globo__lugar--oeste {
    flex-direction: row;
    margin: 0;
    translate: -50% calc(var(--esp-4) - 0.2em);
  }
  .globo__lugar--oeste { translate: -50% calc(-100% - var(--esp-4) + 0.2em); }
  .globo__lugar::before { display: none; }
}

.globo__lugar.es-visible { opacity: 1; }



/* ═════════════════════════════ CLIENTES ══════════════════════════════
   Todos los logos en blanco, iguales. Un haz verde barre la grilla y al
   pasar descubre cada marca en sus colores reales, sobre blanco (lo mismo
   con el mouse encima). La ultima celda invita a ser el proximo cliente.
   JS: ui/clientes.js (el haz y el tamaño optico de cada logo). */

.clientes { background: var(--azul-marca); }   /* azul VIXOZ */

.clientes__cabecera {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-bottom: var(--esp-12);
}

.clientes__escaner {
  position: relative;
  overflow-x: clip;   /* la estela del haz no se sale por los costados */
}

/* Grilla de lineas finas: cada celda dibuja borde derecho e inferior y la
   grilla pone el de arriba y el de la izquierda. */
.clientes__grilla {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border-top: 1px solid var(--borde);
  border-left: 1px solid var(--borde);
}
@media (min-width: 560px)  { .clientes__grilla { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 860px)  { .clientes__grilla { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1100px) { .clientes__grilla { grid-template-columns: repeat(5, 1fr); } }

.cliente {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 2 / 1;
  border-right: 1px solid var(--borde);
  border-bottom: 1px solid var(--borde);
  overflow: hidden;
  isolation: isolate;
}

/* Fondo blanco que se descubre de izquierda a derecha (como el haz). */
.cliente::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--blanco);
  /* scaleX y no clip-path: cerrado, el clip dejaba un hilo blanco de 1px. */
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 900ms var(--curva-suave);   /* sigue al laser */
}

/* Ancho optico: lo pone el JS segun la proporcion de cada logo, para que
   un logo largo y uno cuadrado pesen parecido. Sin JS, 50 %. */
.cliente__logo {
  display: grid;
  width: 50%;
  transition: transform 600ms var(--curva-salida);
}
.cliente__logo img {
  grid-area: 1 / 1;
  width: 100%;
  height: auto;
}
.cliente__blanco { transition: opacity 300ms ease; }
.cliente__color {
  clip-path: inset(0 100% 0 0);
  transition: clip-path 900ms var(--curva-suave);
}

.cliente__nombre {
  position: absolute;
  left: var(--esp-3);
  bottom: var(--esp-2);
  font-size: var(--t-etiqueta);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--azul-900);
  opacity: 0;
  transform: translateY(0.4em);
  transition: opacity 300ms ease, transform 400ms var(--curva-salida);
}

/* Descubierta: por el haz o por el mouse. */
.cliente.es-escaneada::before { transform: none; }
.cliente.es-escaneada .cliente__color { clip-path: inset(0 0 0 0); }
.cliente.es-escaneada .cliente__blanco { opacity: 0; }
.cliente.es-escaneada .cliente__nombre { opacity: 0.7; transform: none; }
@media (hover: hover) {
  .cliente:not(.cliente--cta):hover::before { transform: none; }
  .cliente:not(.cliente--cta):hover .cliente__color { clip-path: inset(0 0 0 0); }
  .cliente:not(.cliente--cta):hover .cliente__blanco { opacity: 0; }
  .cliente:not(.cliente--cta):hover .cliente__nombre { opacity: 0.7; transform: none; }
  .cliente:not(.cliente--cta):hover .cliente__logo { transform: scale(1.06); }
}

/* Logos con partes blancas: se descubren sobre azul noche, no blanco. */
.cliente--oscuro::before { background: var(--azul-950); }
.cliente--oscuro .cliente__nombre { color: var(--azul-200); }

/* La ultima celda: la que falta. Ocupa lo que sobra de la ultima fila
   (lo calcula ui/clientes.js: --cta-columnas); sin JS, dos columnas. */
.cliente--cta {
  grid-column: span var(--cta-columnas, 2);
  aspect-ratio: auto;
  background: var(--acento);
}
.cliente--cta::before { display: none; }
.cliente--cta a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-4);
  width: 100%;
  height: 100%;
  padding: var(--esp-6) var(--esp-8);
  font-family: var(--fuente-titulo);
  font-weight: 900;
  font-stretch: var(--ancho-titulo);
  font-size: var(--t-sub);
  line-height: 1;
  letter-spacing: var(--tracking-titulo);
  word-spacing: var(--espacio-palabras-titulo);
  text-transform: uppercase;
  color: var(--azul-900);
  text-decoration: none;
  transition: background-color 300ms ease;
}
.cliente--cta-chica { aspect-ratio: 16 / 10; }
.cliente--cta-chica a {
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--esp-2);
  padding: var(--esp-4) var(--esp-6);
  font-size: clamp(1.05rem, 1.6vw, 1.45rem);
}
.cliente__flecha {
  font-size: 1.4em;
  transition: transform 400ms var(--curva-salida);
}
.cliente--cta a:hover,
.cliente--cta a:focus-visible { background: var(--acento-brillo); }
.cliente--cta a:hover .cliente__flecha,
.cliente--cta a:focus-visible .cliente__flecha { transform: translateX(0.3em) rotate(-45deg); }

/* El laser: linea verde vertical del alto de UNA celda, con estela. El JS
   la lleva de logo en logo (top, height y --estela por cuadro). */
.clientes__haz {
  position: absolute;
  top: 0;
  left: 0;
  height: 0;
  width: 2px;
  z-index: 2;
  background: var(--acento-brillo);
  box-shadow: 0 0 12px 2px var(--acento), 0 0 34px 5px color-mix(in srgb, var(--acento) 40%, transparent);
  opacity: 0;
  pointer-events: none;
  will-change: transform;
}
.clientes__haz::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 100%;
  width: var(--estela, 0px);
  background: linear-gradient(to right, transparent, color-mix(in srgb, var(--acento) 30%, transparent));
}
.reduce-movimiento .clientes__haz { display: none; }


/* Contacto: el WhatsApp con su numero (reemplaza "Mas formas de contactarnos"). */
.contacto__whatsapp { font-size: clamp(0.95rem, 1.3vw, 1.1rem); letter-spacing: 0.08em; }
.contacto__whatsapp-icono { color: var(--acento); flex: none; }
.contacto__whatsapp:hover .contacto__whatsapp-icono { transform: scale(1.12); }
