/* Plus Jakarta Sans es fuente variable: un woff2 cubre todos los pesos */
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/PlusJakartaSans-latin.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

:root {
  --papel: #e9e9e7;
  --tinta: #111111;
  --tinta-suave: #2b2b2b;
  --gris: #6b6b68;
  --linea: rgba(17, 17, 17, 0.22);
  --negro: #101010;
  --papel-oscuro: #26262a;
  --verde: #90b058;
  --verde-tinta: #5f7a33;

  --panel-pad: clamp(1.5rem, 4vw, 4rem);
  --nav-h: 5rem;

  /* tamaños atados a ancho Y alto de viewport: nada crece más de lo que cabe en 100svh */
  --f-hero: clamp(2.2rem, min(5.2vw, 9vh), 5.2rem);
  --f-display: clamp(3rem, min(9vw, 15vh), 8.1rem);
  --f-titulo: clamp(1.6rem, min(2.9vw, 4.2vh), 2.6rem);
  --f-lead: clamp(1.1rem, 1.6vw, 1.5rem);
  --f-body: clamp(0.95rem, 1.02vw, 1.05rem);
  --f-kicker: 0.68rem;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

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

/* desktop: la HOME es SOLO lateral; cualquier desborde vertical de un panel no genera scroll.
   OJO 1: solo en html — si body también se pone hidden, el body pasa a ser su propio
   scroll container y window.scrollTo/scrollX dejan de funcionar (se rompe todo el sitio).
   OJO 2: solo con :has(.hero) — las subpáginas son verticales y necesitan su scroll. */
@media (min-width: 1024px) {
  html:has(.hero) { overflow-y: hidden; }
}

/* la barra de scroll nativa se esconde: el indicador del sitio es la línea verde
   de abajo (.scroll-progress), que está en las tres páginas. Se hace en html y en
   body porque según la página el contenedor de scroll es uno u otro. */
html, body { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar, body::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* el puntero es SOLO el circulito verde: se esconde el cursor nativo */
@media (hover: hover) and (min-width: 1024px) {
  * { cursor: none !important; }
}

body {
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  background: var(--papel);
  color: var(--tinta);
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--verde); color: #fff; }

a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }

h1, h2, h3 { font-weight: 400; line-height: 1.02; letter-spacing: -0.02em; }

/* lo destacado se lee más oscuro que el cuerpo, no solo más grueso */
strong { font-weight: 700; color: var(--tinta); }

/* párrafos de cuerpo justificados (Aníbal, 31-jul). Con hyphens:auto, si no el justify
   abre ríos blancos. Las 3 columnas de los casos quedan FUERA a propósito: miden 178px
   (~24 caracteres por línea) y a ese ancho el justify parte casi cada palabra. */
.nosotros__text p,
.servicio p,
.factor-block p,
.sub-two-col p {
  text-align: justify;
  hyphens: auto;
}

.kicker {
  font-size: var(--f-kicker);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--verde-tinta);
  font-weight: 600;
  display: inline-block;
}

.display {
  font-size: var(--f-display);
  text-transform: uppercase;
  letter-spacing: -0.03em;
  line-height: 0.92;
}

/* ---------- cursor ---------- */
.cursor-dot {
  position: fixed;
  top: 0; left: 0;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--verde);
  pointer-events: none;
  z-index: 9999;
  transform: translate(-50%, -50%);
  transition: width 0.25s var(--ease), height 0.25s var(--ease), background 0.25s var(--ease);
  mix-blend-mode: normal;
}
/* sobre texto/links el punto crece y se pone blanco con blend difference:
   muestra el color inverso de lo que tenga debajo (verde -> violeta, papel -> tinta) */
.cursor-dot.is-hover { width: 46px; height: 46px; background: #fff; mix-blend-mode: difference; }
@media (hover: none) { .cursor-dot { display: none; } }

/* ---------- header ---------- */
/* z-index 300: el header crea el stacking context del toggle, así la X queda
   por ENCIMA del overlay del menú (z 200). El brand se oculta con el menú abierto. */
.site-header {
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--panel-pad);
  z-index: 300;
  color: var(--tinta);
  pointer-events: none;
}
.site-header .brand, .site-header .menu-toggle { pointer-events: auto; }
body.menu-is-open .site-header .brand { opacity: 0; pointer-events: none; }
.brand { display: flex; align-items: center; transition: opacity 0.5s var(--ease); }
/* en contacto el logo del header se desvanece y reaparece sobre la foto de la sección */
body.at-contacto .site-header .brand { opacity: 0; pointer-events: none; }
.brand__logo { height: 34px; width: auto; transform-origin: left top; will-change: transform; }
/* el toggle vive fijo sobre TODO (incluido el overlay) para poder morfar dots -> X */
.menu-toggle {
  position: fixed;
  top: calc((var(--nav-h) - 34px) / 2);
  right: var(--panel-pad);
  z-index: 300;
  width: 34px; height: 34px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--verde);
}
.menu-toggle span {
  width: 100%; height: 100%;
  background: currentColor;
  border-radius: 50%;
  transition: transform 0.45s var(--ease), border-radius 0.45s var(--ease);
}
.menu-toggle:hover span:nth-child(1) { transform: translate(-2px, -2px); }
.menu-toggle:hover span:nth-child(4) { transform: translate(2px, 2px); }
/* abierto: los 4 puntos vuelan al centro y se estiran formando la X */
body.menu-is-open .menu-toggle span { border-radius: 2px; }
body.menu-is-open .menu-toggle span:nth-child(1) { transform: translate(9.75px, 9.75px) rotate(45deg) scale(1.7, 0.24); }
body.menu-is-open .menu-toggle span:nth-child(2) { transform: translate(-9.75px, 9.75px) rotate(-45deg) scale(1.7, 0.24); }
body.menu-is-open .menu-toggle span:nth-child(3) { transform: translate(9.75px, -9.75px) rotate(-45deg) scale(1.7, 0.24); }
body.menu-is-open .menu-toggle span:nth-child(4) { transform: translate(-9.75px, -9.75px) rotate(45deg) scale(1.7, 0.24); }

/* ---------- horizontal track ---------- */
.h-scroll {
  display: flex;
  height: 100vh;
  height: 100svh;
}
.panel {
  flex: 0 0 100vw;
  min-width: 0;
  height: 100vh;
  height: 100svh;
  position: relative;
  padding: var(--nav-h) var(--panel-pad) var(--panel-pad);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.panel--wide { flex-basis: 128vw; }
.panel--wider { flex-basis: 170vw; }
.panel--dark { flex-basis: 150vw; background: var(--negro); color: var(--papel); }
/* panel "pineado": ocupa una sola pantalla como cualquier otro. Antes era más ancho
   (180vw / 210vw) y el scroll extra alimentaba la animación letra por letra; se sacó
   porque obligaba a seguir empujando pal lado para ver la info (Aníbal, 31-jul). */
.panel--pin { padding: 0; display: block; }
.pin {
  width: 100vw;
  height: 100%;
  padding: var(--nav-h) var(--panel-pad) var(--panel-pad);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ---------- reveal ---------- */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
.reveal.d1 { transition-delay: 0.08s; }
.reveal.d2 { transition-delay: 0.16s; }
.reveal.d3 { transition-delay: 0.24s; }
.reveal.d4 { transition-delay: 0.32s; }
/* entrada más marcada para el manifiesto */
.manifiesto__line.reveal { transform: translateY(64px); transition: opacity 1.1s var(--ease), transform 1.1s var(--ease); }
.manifiesto__line.reveal.is-in { transform: none; }
.manifiesto__line.reveal.d2 { transition-delay: 0.22s; }

/* ---------- arrows / lines ---------- */
.rule {
  height: 1px;
  background: var(--linea);
  width: 100%;
}
.arrow-line {
  display: flex;
  align-items: center;
  gap: 1rem;
  width: 100%;
  max-width: 640px;
  color: var(--gris);
}
.arrow-line .rule { flex: 1; }
.arrow-hint {
  font-size: 0.68rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  white-space: nowrap;
  font-weight: 600;
  line-height: 1;
}
/* la línea de la flecha vive en el centro exacto del viewBox (13px de alto, y=6.5),
   así queda a la misma altura que .rule, que el flex centra igual */
.arrow-tip { width: 46px; height: 13px; flex: 0 0 auto; overflow: visible; }
.arrow-tip__line { stroke: var(--linea); stroke-width: 1; }
.arrow-tip__head { fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }
.arrow-ico { font-size: 1.6rem; line-height: 1; transition: transform 0.4s var(--ease), color 0.4s var(--ease); }
a:hover .arrow-ico { transform: translateX(6px); color: var(--verde-tinta); }

.btn-round {
  width: 92px; height: 92px;
  border: 1px solid var(--tinta);
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 1.5rem;
  transition: background 0.4s var(--ease), color 0.4s var(--ease), transform 0.4s var(--ease);
}
.btn-round:hover { background: var(--verde); border-color: var(--verde); color: #fff; transform: scale(1.06); }

.link-inline {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: clamp(1.05rem, 1.35vw, 1.3rem);
  font-weight: 500;
  border-bottom: 1px solid var(--linea);
  padding-bottom: 5px;
  transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}
.link-inline:hover { color: var(--verde-tinta); border-color: var(--verde-tinta); }

/* ============ HERO ============ */
.hero { padding-right: 0; }
.hero__inner {
  display: grid;
  /* la foto ocupa exactamente la mitad de la pantalla */
  grid-template-columns: 1fr 50vw;
  align-items: stretch;
  gap: 0;
  height: 100%;
}
.hero__text {
  align-self: center;
  padding-right: var(--panel-pad);
  max-width: 60vw;
}
.hero__title {
  font-size: var(--f-hero);
  line-height: 1.04;
  letter-spacing: -0.025em;
  font-weight: 400;
}
.hero__title .fuerte { font-weight: 700; }
.hero__line-a, .hero__line-b { display: block; }
/* el sizer (palabra más larga, invisible) reserva el ancho; la palabra visible
   va encima. Así el salto de línea no se mueve al cambiar la palabra, y el punto
   queda pegado al final del slot reservado. */
.rotador-wrap { position: relative; display: inline-block; white-space: nowrap; vertical-align: baseline; }
.rotador-sizer { visibility: hidden; font-weight: 700; }
.rotador-abs { position: absolute; left: 0; top: 0; white-space: nowrap; opacity: 0; transform: translateY(0.5em); }
.rotador-abs.reveal-word { opacity: 1; transform: none; transition: opacity 0.55s var(--ease), transform 0.55s var(--ease); }
.hero__title .rotador { color: var(--verde); font-weight: 700; }
.rotador-punto { color: var(--tinta); font-weight: 700; }
/* el pie del hero (línea + tagline) entra DESPUÉS del título */
.hero__foot--delayed.reveal { transition-delay: 1.9s; }
.hero__foot--delayed.reveal .arrow-line,
.hero__foot--delayed.reveal .hero__tag { }
.hero__foot {
  align-self: center;
  padding-right: var(--panel-pad);
  margin-top: 2.5rem;
}
.hero__tag {
  font-size: var(--f-body);
  color: var(--gris);
  max-width: 42ch;
  margin-top: 1.4rem;
}
.hero__media {
  position: relative;
  overflow: hidden;
  background: var(--negro);
}
/* carrusel: las 3 fotos apiladas, cambia la activa al ritmo de la palabra rotatoria */
.hero__media img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.6s linear; /* entra exactamente con la palabra verde */
}
.hero__media img.is-active { opacity: 1; }

/* letra por letra */
.swirl { word-break: normal; overflow-wrap: normal; }
.swirl-word { display: inline; white-space: nowrap; }
.swirl span {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.5em) rotate(8deg);
}
.swirl.play span {
  animation: swirlIn 0.6s var(--ease) forwards;
}
@keyframes swirlIn {
  to { opacity: 1; transform: none; }
}

/* rotador de palabra (estado inicial + reveal definidos junto a .rotador-abs arriba) */
/* la palabra cruza en fase con el carrusel del hero: 0.6s de salida + 0.6s de entrada = 1.2s */
.rotador__word { display: inline-block; }
.rotador__word.out { animation: wordOut 0.6s linear forwards; }
.rotador__word.in { animation: wordIn 0.6s linear forwards; }
@keyframes wordOut { to { opacity: 0; transform: translateY(-0.35em); } }
@keyframes wordIn { from { opacity: 0; transform: translateY(0.35em); } to { opacity: 1; transform: none; } }

/* ============ NOSOTROS (collage) ============ */
.nosotros__inner { display: grid; grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr); gap: clamp(2rem, 4vw, 4.5rem); align-items: center; height: 100%; }
.nosotros__text { max-width: 40ch; }
.nosotros__text h2 { font-size: var(--f-titulo); margin: 0 0 1.5rem; }
.nosotros__h2 .nos-b { color: var(--verde-tinta); }
.nosotros__text .kicker { margin-bottom: 0.8rem; }
.nosotros__text p { color: var(--tinta-suave); font-size: var(--f-body); margin-bottom: 1rem; }
.nosotros__text p.nosotros__credito {
  color: var(--verde-tinta);
  font-weight: 800;
  margin-top: 1.6rem;
  letter-spacing: 0.04em;
  font-size: 1.3rem;
  text-transform: uppercase;
  line-height: 1.15;
  white-space: nowrap;
}
/* el "Carbono Neutral" conserva su pop: entra escalado, no deslizado */
.nosotros__credito.reveal { transform: scale(0.6); }
.nosotros__credito.reveal.is-in {
  transform: scale(1);
  transition: transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.25s linear;
}
/* video institucional (reemplaza al collage) */
.nosotros__media { position: relative; }
.nosotros__video { position: relative; aspect-ratio: 16 / 9; background: var(--negro); box-shadow: 0 18px 50px rgba(0, 0, 0, 0.16); }
.nosotros__video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* capa sobre el iframe: deja pasar el scroll de la página (Vimeo se lo tragaba)
   y sostiene el botón de play propio; el primer click reproduce y la retira */
.nosotros__video-shield {
  position: absolute;
  inset: 0;
  background: transparent;
  border: 0;
  padding: 0;
  z-index: 1;
  display: grid;
  place-items: center;
}
/* al reproducir el escudo se retira de la franja inferior para dejar libres los
   controles de Vimeo, pero sigue cubriendo el resto: sin él, el iframe se traga
   la rueda del mouse y la página no scrollea con el cursor sobre el video */
.nosotros__video-shield.is-playing { bottom: 58px; background: transparent; }
.nosotros__video-shield.is-playing .nosotros__play { opacity: 0; pointer-events: none; }
.nosotros__play { transition: transform 0.35s var(--ease), background 0.35s var(--ease), opacity 0.3s var(--ease); }
.nosotros__play {
  width: clamp(56px, 5vw, 76px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(233, 233, 231, 0.92);
  display: grid;
  place-items: center;
  transition: transform 0.35s var(--ease), background 0.35s var(--ease);
}
.nosotros__play svg { width: 46%; height: 46%; fill: var(--negro); margin-left: 6%; }
.nosotros__video-shield:hover .nosotros__play { transform: scale(1.08); background: var(--verde); }
.nosotros__video-shield:hover .nosotros__play svg { fill: #fff; }
/* "dale play" en diagonal sobre la esquina superior izquierda del video,
   con flecha doodle (mismo espíritu que la línea de factor) apuntando al video */
.nosotros__play-hint {
  position: absolute;
  top: -4.2rem;
  left: -1.2rem;
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  transform: rotate(-7deg);
  z-index: 2;
  pointer-events: none;
}
.nosotros__play-hint span {
  font-size: var(--f-kicker);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--verde-tinta);
  font-weight: 600;
  white-space: nowrap;
}
.nosotros__play-hint svg {
  width: 84px;
  height: 66px;
  stroke: var(--verde-tinta);
  stroke-width: 1.5;
  stroke-linecap: round;
  margin-top: 0.8rem;
  flex: 0 0 auto;
}
.collage { position: relative; height: 74vh; }
.collage img { position: absolute; object-fit: cover; filter: grayscale(0.15) contrast(1.02); box-shadow: 0 18px 50px rgba(0,0,0,0.16); }
.collage__a { width: 46%; height: 62%; top: 0; left: 0; z-index: 1; }
.collage__b { width: 42%; height: 54%; top: 20%; right: 0; z-index: 3; }
.collage__c { width: 40%; height: 42%; bottom: 0; left: 22%; z-index: 2; }

/* ============ SERVICIOS ============ */
.servicios__head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: clamp(1.5rem, 3.5vh, 2.8rem); gap: 2rem; flex-wrap: wrap; }
.servicios__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border: 1px solid var(--linea);
}
.servicio {
  padding: clamp(1.5rem, 1.8vw, 2.2rem);
  border-right: 1px solid var(--linea);
  display: flex;
  flex-direction: column;
  transition: background 0.45s var(--ease);
}
.servicio:last-child { border-right: none; }
.servicio h3, .servicio p { transition: color 0.45s var(--ease); }
.servicio:hover { background: var(--verde); }
.servicio:hover h3 { color: #fff; }
.servicio:hover p { color: rgba(255, 255, 255, 0.92); }
.servicio__media { height: clamp(180px, 30vh, 300px); overflow: hidden; margin-bottom: clamp(1.2rem, 2.5vh, 1.8rem); background: #dcdcd8; }
.servicio__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s var(--ease), opacity 0.6s var(--ease); }
.servicio:hover .servicio__media img { transform: scale(1.05); }
/* fade-in al cargar la imagen: evita el "pop" brusco */
img.img-fade { opacity: 0; }
img.img-fade.is-loaded { opacity: 1; }
.servicio h3 { font-size: clamp(1.35rem, 2.4vh, 1.6rem); margin-bottom: clamp(0.7rem, 1.4vh, 1rem); }
.servicio p { color: var(--tinta-suave); font-size: clamp(0.92rem, 1.6vh, 1rem); line-height: 1.55; }

/* ============ CLIENTES ============ */
.clientes__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  align-items: center;
  column-gap: clamp(2rem, 4vw, 3.5rem);
  height: 100%;
}
.clientes__text { max-width: 100%; }
.clientes__display { font-size: clamp(3rem, min(7.5vw, 13vh), 7.5rem); margin-bottom: clamp(1rem, 2.5vh, 1.8rem); }
.clientes__sub { font-size: var(--f-lead); line-height: 1.3; color: var(--tinta-suave); max-width: 30ch; }
.clientes__link { margin-top: clamp(1.5rem, 3vh, 2.5rem); }
/* dos cintas infinitas sincronizadas, 3 logos visibles por fila, fade en los bordes */
.clientes__carousel {
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 4vh, 3rem);
  width: 100%;
  min-width: 0;
}
.logo-row {
  overflow: hidden;
  min-width: 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  cursor: grab;
  touch-action: pan-y;      /* el arrastre horizontal es nuestro; el scroll vertical sigue siendo del dedo */
  user-select: none;
  -webkit-user-select: none;
}
.logo-row.is-grabbing { cursor: grabbing; }
.logo-row__track {
  display: flex;
  width: max-content;
  will-change: transform;
}
/* el giro lo mueve main.js con rAF, no una animación CSS: así se puede agarrar,
   soltar con inercia y volver solo a la deriva. Sin JS la cinta queda quieta y
   legible, que es un fallback aceptable. */
/* ancho fijo por logo (var seteada en JS = 1/3 del ancho de la fila) => 3 a la vista.
   NO usar % aquí: el track es max-content y crearía un bucle de medición. */
.logo-row .logo {
  flex: 0 0 var(--logo-w, 15vw);
  display: grid;
  place-items: center;
  min-height: clamp(70px, 12vh, 110px);
  padding: 0 clamp(0.75rem, 1.5vw, 1.75rem);
}
/* el lienzo del logo (todos son 200x140) manda la altura de la fila.
   Con height fijo + max-height:100%, Chrome no resolvía el porcentaje contra el
   área de grid: la imagen quedaba 5px más alta que la caja y el overflow:hidden
   de .logo-row se los comía por ABAJO (Chrome ancla el desborde al inicio, no
   centrado). Ese era el corte en Soprole, Sistema B, Colunga, UNAB y DC. */
.logo-row .logo img {
  width: 100%;
  height: auto;
  pointer-events: none;     /* que el arrastre no empiece un drag&drop de la imagen */
}

/* ============ FACTOR DE CAMBIO teaser ============ */
.factor { overflow: hidden; }
.factor__inner { position: relative; height: 100%; display: block; }
.factor__doodle { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; overflow: visible; }
.factor__doodle-path {
  fill: none;
  stroke: var(--verde);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.5;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  pathLength: 1;
}
.factor.is-drawn .factor__doodle-path {
  animation: drawDoodle 2.4s var(--ease) forwards;
}
@keyframes drawDoodle { to { stroke-dashoffset: 0; } }
.factor-block { position: absolute; max-width: 340px; z-index: 2; }
.factor-block .dot { width: 12px; height: 12px; border-radius: 50%; background: var(--verde-tinta); margin-bottom: 1.1rem; }
.factor-block h3 { font-size: 1.9rem; margin-bottom: 0.8rem; }
/* logos de los canales integrados a la frase, alineados a la altura de la tipografía */
.factor-block__canales { display: flex; align-items: center; gap: 0.45em; flex-wrap: wrap; }
.factor-block__canales img { height: 1.25em; width: auto; display: inline-block; }
.factor-block p { color: var(--tinta-suave); font-size: 0.98rem; }
/* posiciones calibradas para panel de 100vw (compresión 24-jul): sin traslapes en 13" */
.factor-block--a { top: 14%; left: 0; }
.factor-block--b { top: 48%; left: 56%; max-width: 320px; }
.factor__img { position: absolute; overflow: hidden; z-index: 1; box-shadow: 0 18px 50px rgba(0,0,0,0.16); }
.factor__img img { width: 100%; height: 100%; object-fit: cover; }
.factor__img--1 { width: 345px; height: 230px; top: 6%; right: 8%; }
.factor__img--2 { width: 240px; height: 280px; bottom: 18%; left: 30%; }
/* RRSS de Factor de Cambio bajo el CTA (Fede, 5-ago). El CTA va alineado a la
   derecha, así que los iconos se alinean con él y no al borde izquierdo del bloque. */
.rrss { display: flex; gap: 0.9rem; margin-top: 0.75rem; align-items: center; justify-content: flex-end; }
.rrss a { color: var(--gris); display: inline-flex; }
.rrss svg { width: 18px; height: 18px; transition: color 0.3s var(--ease), transform 0.3s var(--ease); }
.rrss a:hover { color: var(--verde-tinta); }
.rrss a:hover svg { transform: translateY(-2px); }
.factor__cta { position: absolute; bottom: 8%; right: 2%; z-index: 3; text-align: right; }
.factor__label { position: absolute; top: 0; left: 0; z-index: 2; }
.factor__label .kicker { color: var(--gris); }

/* ============ MANIFIESTO (texto cutout con la imagen adentro) ============
   Fondo negro; la imagen solo se ve DENTRO de las letras (máscara SVG:
   rect negro oculta la imagen, texto blanco la deja pasar). */
/* overflow clip (no hidden): hidden anularía el position:sticky del pin */
.manifiesto {
  padding: 0;
  position: relative;
  overflow: clip;
  background: var(--negro);
}
.manifiesto__pin { padding: 0; }
/* el velo entra al llegar a la lámina (antes lo movía el scroll horizontal).
   Gana sobre el atributo opacity="0" del rect: CSS pisa presentation attributes. */
.manifiesto__velo { opacity: 0; transition: opacity 0.9s var(--ease); }
.manifiesto.is-lit .manifiesto__velo { opacity: 1; }
.manifiesto__svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.manifiesto__t {
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: min(5vw, 9vh);
  letter-spacing: -0.03em;
  font-weight: 700;
  fill: #fff; /* sin JS: las letras muestran la imagen completa */
}
/* con JS: cada letra parte apagada (negra en la máscara) y se enciende al aparecer */
.manifiesto__t tspan { fill: #000; transition: fill 0.22s linear; }
.manifiesto__t tspan.on { fill: #fff; }

/* ============ CONTACTO ============ */
/* overflow hidden: el half-bleed de la foto desbordaba ~28px y generaba scroll vertical */
.contacto { padding-right: 0; overflow: hidden; }
.contacto__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.72fr) minmax(340px, 1.05fr); height: 100%; align-items: center; column-gap: clamp(1.25rem, 2.5vw, 2.5rem); }
.contacto__form-wrap { max-width: 520px; }
.contacto__form-wrap > .kicker { margin-bottom: 1.4rem; color: var(--gris); font-size: 0.95rem; letter-spacing: 0.18em; }
.form-row { border-bottom: 1px solid var(--linea); }
.form-row input, .form-row select, .form-row textarea {
  width: 100%;
  border: none;
  background: none;
  font: inherit;
  font-size: 1rem;
  padding: clamp(0.7rem, 1.6vh, 1.1rem) 0;
  color: var(--tinta);
  outline: none;
}
.form-row textarea { resize: none; min-height: clamp(56px, 8vh, 90px); }
.form-row input::placeholder, .form-row textarea::placeholder { color: var(--gris); }
.form-row select { appearance: none; cursor: pointer; }
.form-row:focus-within { border-color: var(--verde-tinta); }
.form-submit {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%;
  background: none; border: none;
  font: inherit; font-size: 1.05rem;
  padding: clamp(0.9rem, 1.8vh, 1.3rem) 0;
  cursor: pointer;
  border-bottom: 1px solid var(--tinta);
  transition: color 0.3s var(--ease);
}
.form-submit:hover { color: var(--verde-tinta); }
.contacto__info { align-self: center; }
/* solo el logo: aparece (aterriza desde el header) al llegar a contacto */
.contacto__mini { width: 120px; margin-bottom: 1rem; }
.contacto__mini-logo { width: 100%; height: auto; opacity: 0; transition: opacity 0.6s var(--ease); }
body.at-contacto .contacto__mini-logo { opacity: 1; }
.contacto__addr { font-size: var(--f-body); color: var(--tinta-suave); margin-bottom: clamp(1.25rem, 3vh, 2.5rem); max-width: 20ch; }
.contacto__talk h3 { font-size: 1.5rem; margin-bottom: 0.8rem; }
.contacto__talk a { display: block; font-size: var(--f-body); color: var(--tinta-suave); }
.contacto__talk a:hover { color: var(--verde-tinta); }
.contacto__social { display: flex; gap: 1.2rem; margin-top: clamp(1rem, 2vh, 1.6rem); align-items: center; }
.contacto__social a { color: var(--gris); display: inline-flex; }
.contacto__social svg { width: 20px; height: 20px; transition: color 0.3s var(--ease), transform 0.3s var(--ease); }
.contacto__social a:hover { color: var(--verde-tinta); }
.contacto__social a:hover svg { transform: translateY(-2px); }
.contacto__copy { margin-top: clamp(1.25rem, 3vh, 2.5rem); font-size: 0.78rem; color: var(--gris); }
/* half-bleed: la foto escapa el padding vertical del panel y toca arriba y abajo.
   El margen negativo izquierdo acerca la foto al bloque de info (mitad del gap) */
.contacto__media {
  position: relative;
  align-self: stretch;
  margin-top: calc(-1 * var(--nav-h));
  margin-bottom: calc(-1 * var(--panel-pad));
  margin-left: calc(-0.5 * clamp(2.5rem, 5vw, 6rem));
  overflow: hidden;
  background: var(--negro);
}
.contacto__media img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 2s linear;
}
.contacto__media img.is-active { opacity: 1; }

/* ============ MENU OVERLAY ============ */
.menu-overlay {
  position: fixed;
  inset: 0;
  background: var(--papel-oscuro);
  color: var(--papel);
  z-index: 200;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s var(--ease), visibility 0.5s;
}
.menu-overlay.open { opacity: 1; visibility: visible; }
.menu-logo {
  position: absolute;
  top: 0; left: 0;
  height: var(--nav-h);
  padding: 0 var(--panel-pad);
  display: flex; align-items: center;
  z-index: 2;
}
.menu-logo img { height: 40px; width: auto; }
.menu-left {
  position: relative;
  z-index: 1;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: clamp(1.5rem, 3.5vh, 2.5rem);
  padding: calc(var(--nav-h) + 0.75rem) var(--panel-pad) var(--panel-pad);
}
.menu-primary { display: flex; flex-direction: column; gap: 0.35rem; }
.menu-primary a {
  font-size: clamp(1.8rem, min(4vw, 8vh), 3.6rem);
  line-height: 1.12;
  width: fit-content;
  color: var(--papel);
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease), color 0.3s;
}
/* desorden intencional en la lista */
.menu-primary a:nth-child(2) { margin-left: 10vw; }
.menu-primary a:nth-child(3) { margin-left: 4vw; }
.menu-primary a:nth-child(4) { margin-left: 13vw; }
.menu-primary a:nth-child(5) { margin-left: 2vw; }
.menu-primary a:nth-child(6) { margin-left: 8vw; }
.menu-overlay.open .menu-primary a { opacity: 0.55; transform: none; }
.menu-overlay.open .menu-primary a:nth-child(1) { transition-delay: 0.1s; }
.menu-overlay.open .menu-primary a:nth-child(2) { transition-delay: 0.16s; }
.menu-overlay.open .menu-primary a:nth-child(3) { transition-delay: 0.22s; }
.menu-overlay.open .menu-primary a:nth-child(4) { transition-delay: 0.28s; }
.menu-overlay.open .menu-primary a:nth-child(5) { transition-delay: 0.34s; }
.menu-overlay.open .menu-primary a:nth-child(6) { transition-delay: 0.4s; }
.menu-primary a:hover { opacity: 1; color: var(--verde); }
.menu-social { display: flex; gap: 1.4rem; font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; }
.menu-social a { color: rgba(233,233,231,0.5); }
.menu-social a:hover { color: var(--verde); }
/* imagen full-bleed detrás del menú, las letras van encima (cambio 2ª llamada 24-jul);
   scrim oscuro para que la lista siga legible. Reemplazar por foto verde cuando llegue el Drive */
.menu-media { position: absolute; inset: 0; overflow: hidden; }
.menu-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgba(20, 22, 18, 0.88) 30%, rgba(20, 22, 18, 0.45) 100%);
}
.menu-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scale(1.06);
  transition: transform 1.2s var(--ease);
}
.menu-overlay.open .menu-media img { transform: scale(1); }

/* scroll progress */
.scroll-progress {
  position: fixed;
  bottom: 0; left: 0;
  height: 3px;
  width: 0;
  background: var(--verde);
  z-index: 150;
  transition: width 0.1s linear;
}

/* ============ SUBPÁGINAS ============ */
.sub-body { background: var(--papel); }
.sub-header {
  position: sticky;
  top: 0;
  height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--panel-pad);
  background: var(--papel);
  z-index: 100;
  border-bottom: 1px solid var(--linea);
}
.sub-header .brand { color: var(--tinta); }
.sub-header .brand small { color: var(--gris); }
.sub-menu { display: flex; gap: 2rem; font-size: 0.9rem; }
.sub-menu a:hover { color: var(--verde-tinta); }
.sub-hero { padding: clamp(4rem, 12vh, 9rem) var(--panel-pad) clamp(2rem, 5vh, 4rem); }
.sub-hero h1 { font-size: var(--f-display); text-transform: uppercase; letter-spacing: -0.03em; }
/* variante en una sola línea (más chica para que quepa y el acento no choque) */
.sub-hero h1.sub-hero__one { font-size: clamp(2.2rem, min(6.4vw, 11vh), 6rem); line-height: 1.1; white-space: nowrap; }
.sub-hero .kicker { margin-bottom: 1.5rem; }
.sub-section { padding: clamp(2rem, 5vh, 4rem) var(--panel-pad); max-width: 1400px; }
.sub-lead {
  font-size: var(--f-titulo);
  line-height: 1.2;
  max-width: 24ch;
  margin: 2rem 0 3rem;
  padding-top: 2rem;
  border-top: 1px solid var(--linea);
}
.sub-two-col { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 5rem); }
.sub-two-col p { font-size: var(--f-body); color: var(--tinta-suave); margin-bottom: 1.2rem; line-height: 1.6; }
.sub-media { margin: 3rem 0; aspect-ratio: 16/8; overflow: hidden; }
.sub-media img { width: 100%; height: 100%; object-fit: cover; }
.sub-cta {
  padding: clamp(3rem, 8vh, 6rem) var(--panel-pad);
  border-top: 1px solid var(--linea);
}
.sub-cta h2 { font-size: var(--f-titulo); margin-bottom: 1.5rem; }

/* casos: imagen half-bleed pegada al borde, alternando lado (1 izq, 2 der, 3 izq, 4 der) */
.caso {
  display: grid;
  grid-template-columns: 50% 50%;
  gap: 0;
  align-items: stretch; /* half-bleed: la foto va de línea divisoria a línea divisoria */
  padding: 0;
  border-top: 1px solid var(--linea);
  max-width: none;
}
.caso__body { padding: clamp(2.5rem, 6vh, 4.5rem) var(--panel-pad); }
.caso:nth-of-type(even) .caso__media { grid-column: 2; grid-row: 1; }
.caso:nth-of-type(even) .caso__body { grid-column: 1; grid-row: 1; }
.caso__media { height: 100%; min-height: min(70vh, 560px); overflow: hidden; margin: 0; }
/* la foto no se traslada al revelarse: rompería el half-bleed contra las divisorias */
.caso__media.reveal { transform: none; }
.caso__media img { width: 100%; height: 100%; object-fit: cover; }
/* el cliente se identifica por su LOGO, no por su nombre (Fede, 5-ago). Los tres logos
   tienen proporciones muy distintas (EJF 1.7:1, Capital Azul 3.3:1, Patagonia 1.4:1),
   así que la uniformidad se consigue con una caja común + contain, no con altura fija. */
.caso__brand { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.4rem; min-height: 130px; }
.caso__brand img { height: 110px; max-width: 250px; width: auto; object-fit: contain; object-position: left center; }
/* el de Patagonia es una marca compacta: a la altura común se lee más chico que los
   otros. Va atado al caso y no al nombre del archivo, para que sobreviva a que el
   cliente suba otro logo desde /admin y no se le pegue a los demás casos. */
.caso:nth-of-type(3) .caso__brand img { height: 130px; max-width: 300px; }
.caso__brand span { font-size: 1.15rem; color: var(--verde-tinta); font-weight: 700; letter-spacing: 0.04em; }
.caso__title { font-size: var(--f-titulo); margin-bottom: 2.2rem; max-width: 22ch; }
.caso__cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.2rem, 2.5vw, 2.5rem); }
.caso__col h4 { font-size: 0.75rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--verde-tinta); margin-bottom: 1rem; font-weight: 600; }
.caso__col p { font-size: 0.92rem; color: var(--tinta-suave); line-height: 1.55; }

/* ============ RESPONSIVE: stack vertical ============ */
@media (max-width: 1023px) {
  /* clip y no hidden: overflow-x hidden convierte al body en scroll container
     y rompe el position: sticky de los pins verticales */
  html, body { overflow-x: clip; }
  .cursor-dot { display: none; }
  .site-header { mix-blend-mode: normal; background: var(--papel); color: var(--tinta); border-bottom: 1px solid var(--linea); }
  .site-header .brand { color: var(--tinta); }
  .h-scroll { display: block; height: auto; }
  .panel, .panel--wide, .panel--wider, .panel--dark, .panel--pin {
    flex-basis: auto;
    width: 100%;
    height: auto;
    min-height: auto;
    padding: 4rem var(--panel-pad);
  }
  .panel--pin { display: flex; }
  .pin { position: static; width: auto; height: auto; padding: 0; }

  /* en mobile mandan los controles nativos (incluye pantalla completa): el escudo
     solo existe para que la rueda del mouse no se la trague el iframe, y eso es de desktop */
  .nosotros__video-shield { display: none; }
  .panel--dark { padding-block: 6rem; }
  /* primer panel arranca bajo el header fixed */
  .hero { padding-top: calc(var(--nav-h) + 2rem); }

  .hero__inner { grid-template-columns: 1fr; }
  .hero__text { max-width: 100%; padding-right: 0; }
  /* en mobile se avanza hacia abajo */
  .arrow-line .arrow-ico { transform: rotate(90deg); }
  .hero__media { height: 50vh; margin-top: 2.5rem; }
  .hero__foot { padding-right: 0; margin-top: 2rem; }

  .nosotros__inner { grid-template-columns: minmax(0, 1fr); gap: 2.5rem; } /* minmax(0): con 1fr el mínimo intrínseco del texto desbordaba 38px a 375px */
  .nosotros__play-hint { position: static; transform: rotate(-4deg); margin-bottom: 0.6rem; }

  .servicios__grid { grid-template-columns: 1fr; }
  .servicio { border-right: none; border-bottom: 1px solid var(--linea); min-height: auto; }
  .servicio:last-child { border-bottom: none; }

  .clientes__grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .clientes__carousel { height: clamp(240px, 60vw, 380px); }

  .manifiesto { min-height: 60vh; }
  /* en mobile el texto va en 4 líneas grandes (las arma el JS) */
  .manifiesto__t { font-size: 10.5vw; }

  .factor__inner { height: auto; }
  .factor__doodle { display: none; }
  .factor-block, .factor__img, .factor__cta, .factor__label { position: static; max-width: 100%; width: auto; }
  .factor__label { margin-bottom: 2rem; }
  .factor__img { height: 220px; margin: 1.5rem 0; box-shadow: none; }
  .factor-block { margin-bottom: 2.5rem; }
  .factor__cta { text-align: left; margin-top: 1rem; }
  .factor__cta .rrss { justify-content: flex-start; }

  .contacto__grid { grid-template-columns: 1fr; gap: 2.5rem; padding-block: 1rem; }
  /* en columna el half-bleed no aplica: sin márgenes negativos la foto no tapa el texto */
  .contacto__media { height: 45vh; margin: 0; }

  .sub-two-col { grid-template-columns: 1fr; }
  .caso { grid-template-columns: 1fr; gap: 0; padding: 3rem var(--panel-pad); }
  /* en columna se acaba el alternado: los cuatro casos quedan iguales, foto arriba
     y texto abajo. Sin este reset los pares conservaban su grid-column:2 / grid-row:1
     y seguían lado a lado dentro de una sola columna, apretujados. */
  .caso__media,
  .caso:nth-of-type(even) .caso__media { grid-column: 1; grid-row: 1; }
  .caso__body,
  .caso:nth-of-type(even) .caso__body { grid-column: 1; grid-row: 2; }
  .caso__media { height: 230px; min-height: 0; margin-bottom: 2rem; }
  .caso__brand { min-height: 92px; }
  .caso__brand img { height: 80px; max-width: 180px; }
  .caso:nth-of-type(3) .caso__brand img { height: 92px; max-width: 210px; }
  .caso__body { padding: 0; }
  .caso__cols { grid-template-columns: 1fr; gap: 2rem; }
  .sub-hero h1.sub-hero__one { white-space: normal; }
  .sub-menu { display: none; }

  .menu-left { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .swirl span { opacity: 1; transform: none; animation: none; }
  * { scroll-behavior: auto !important; }
}
