/* Oceans & Rivers — hoja de estilos del sitio.

   Los tokens de color y la tipografía salen del manual de identidad
   (páginas 11 y 12). Los tres valores de marca son #0a224f, #479591 y
   #3981b2; el resto son neutros de soporte.

   El sitio se pinta siempre en claro: el original no tenía modo oscuro y
   el manual fija los colores de marca. */

:root{
  --navy:#0a224f;
  --navy-2:#0e2c63;
  --teal:#479591;
  --teal-dark:#357672;
  --blue:#3981b2;
  --sky:#7fcbe8;
  --bg:#f5f9fb;
  --card:#ffffff;
  --ink:#0a224f;
  --muted:#526078;
  --line:#e3ebf0;
  --radius:6px;
  --alto-cabecera:74px;
  color-scheme:light;
}

/* ---------- pantallas grandes (2K, 4K, 5K, 6K) ----------
   El sitio está diseñado para verse a 1920x1080 (Full HD). En pantallas más
   grandes todo seguía al mismo tamaño y la portada quedaba pequeña en medio
   de mucho vacío. Aquí la página entera se agranda en proporción, para que se
   vea como en Full HD: a 2560 px de ancho, un 33 % más; a 3840 px, el doble.

   Va por escalones, y cada uno exige ancho Y alto (el alto útil de un
   navegador en Full HD ronda los 950 px): así un monitor ultrapanorámico
   (3440x1440) no se agranda tanto que la portada deje de caber. Por debajo
   de 2160 px de ancho no cambia nada. */
@media (min-width:2160px) and (min-height:1069px){:root{--zoom:1.125;}}
@media (min-width:2400px) and (min-height:1188px){:root{--zoom:1.25;}}
@media (min-width:2560px) and (min-height:1267px){:root{--zoom:1.3333;}}
@media (min-width:2880px) and (min-height:1425px){:root{--zoom:1.5;}}
@media (min-width:3200px) and (min-height:1583px){:root{--zoom:1.6667;}}
@media (min-width:3520px) and (min-height:1742px){:root{--zoom:1.8333;}}
@media (min-width:3840px) and (min-height:1900px){:root{--zoom:2;}}
@media (min-width:4480px) and (min-height:2217px){:root{--zoom:2.3333;}}
@media (min-width:5120px) and (min-height:2533px){:root{--zoom:2.6667;}}
@media (min-width:5760px) and (min-height:2850px){:root{--zoom:3;}}
@media (min-width:6016px) and (min-height:2977px){:root{--zoom:3.1333;}}
body{zoom:var(--zoom,1);}

*{box-sizing:border-box;}
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--alto-cabecera) * var(--zoom,1));}
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:'Poppins',system-ui,-apple-system,sans-serif;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;display:block;}
a{color:inherit;}
:focus-visible{outline:3px solid var(--teal);outline-offset:3px;border-radius:3px;}

.wrap{max-width:1180px;margin:0 auto;padding:0 28px;}
/* ---------- tipografía (manual de identidad, p. 12) ----------
   Bebas Neue    tipografía principal, SIEMPRE en mayúsculas, para los
                 títulos principales.
   Poppins Bold  subtítulos, SIEMPRE en mayúsculas.
   Poppins Reg.  cuerpo de texto.
   Solo se cargan los dos pesos que nombra el manual: 400 y 700. */

h1,h2,h3,h4,.display,
.brand span,.foot-brand span,
.acc-num,.hero-stats b,.case-stat b{
  font-family:'Bebas Neue',Impact,sans-serif;
  /* Bebas Neue tiene un único peso. Sin esto, el navegador sintetiza la
     negrita de h1-h4 y de las <b>, y engorda los trazos de la tipografía
     de marca. */
  font-weight:400;
  letter-spacing:.5px;line-height:1.02;margin:0;
  text-transform:uppercase;
}

/* Subtítulos. Van después del bloque anterior para que ganen sobre él
   cuando el subtítulo es además un encabezado, como el h5 del pie. */
.subtitulo,footer h5,.acc-head b,.pillar-card b,.team-info b,
.tag,.case-tag,.ficha dt,.field label{
  font-family:'Poppins',system-ui,sans-serif;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.4px;
}
.eyebrow-line{width:56px;height:4px;background:var(--teal);border-radius:2px;margin:14px 0 22px;}

/* Enlace de salto: solo visible al tabular. */
.salto-contenido{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--teal);color:#fff;padding:12px 20px;border-radius:0 0 8px 0;
  text-decoration:none;font-size:14px;font-weight:700;
}
.salto-contenido:focus{left:0;}

/* ---------- botones ---------- */
.btn{
  display:inline-flex;align-items:center;gap:8px;
  padding:14px 26px;border-radius:999px;
  font-family:'Poppins',system-ui,sans-serif;font-weight:700;font-size:15px;
  border:2px solid transparent;cursor:pointer;
  text-decoration:none;transition:transform .18s ease, background .18s ease, color .18s ease;
}
.btn:hover{transform:translateY(-2px);}
.btn-primary{background:var(--teal);color:#fff;}
.btn-primary:hover{background:var(--teal-dark);}
.btn-outline{border-color:rgba(255,255,255,.55);color:#fff;}
.btn-outline:hover{background:rgba(255,255,255,.12);}
.btn-outline-navy{border-color:var(--navy);color:var(--navy);}
.btn-outline-navy:hover{background:var(--navy);color:#fff;}

/* ---------- cabecera ---------- */
/* Solo la cabecera del sitio va fija. Antes esta regla apuntaba a cualquier
   <header>, así que la cabecera de las páginas interiores (.page-head, que
   también es un <header>) se quedaba fija encima del contenido y lo tapaba. */
.cabecera{
  position:fixed;top:0;left:0;right:0;z-index:50;
  background:rgba(255,255,255,.92);backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
}
.header-in{
  max-width:1180px;margin:0 auto;padding:0 28px;
  height:var(--alto-cabecera);display:flex;align-items:center;justify-content:space-between;
}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none;color:var(--navy);}
/* La gota es alta y estrecha: a 38 px medía más del doble que las letras del
   nombre y la punta y la base sobresalían mucho. A esta altura acompaña al
   nombre, un poco más alta que las mayúsculas y centrada con ellas (el
   margen de -2 px la sube 1 px: la base de la gota pesa más que la punta). */
.brand img{height:30px;width:auto;margin-top:-2px;}
.brand span{font-family:'Bebas Neue',Impact,sans-serif;font-size:20px;letter-spacing:1px;color:var(--navy);}
nav.mainnav{display:flex;align-items:center;gap:34px;}
nav.mainnav a{
  text-decoration:none;color:var(--navy);font-size:14.5px;font-weight:400;
  position:relative;padding:6px 0;
}
nav.mainnav a:hover{color:var(--teal);}
nav.mainnav a[aria-current="page"]{color:var(--teal);}
.navlinks{display:flex;gap:34px;align-items:center;}
.burger{display:none;background:none;border:none;cursor:pointer;padding:6px;}
.burger span{display:block;width:24px;height:2px;background:var(--navy);margin:5px 0;}

/* ---------- hero ----------
   La pieza de portada trae el titular y la bajada quemados dentro, así que
   se sirve como <img> a ancho completo y NUNCA recortada: si se usara de
   fondo con cover, en pantallas estrechas el recorte partiría el titular.
   El texto en vivo va oculto para lectores de pantalla y buscadores, y
   reaparece por debajo de 900 px, donde el de la imagen ya no se lee. */
.hero{
  position:relative;
  background:var(--navy);
  color:#fff;
  padding-top:var(--alto-cabecera);
  /* Sin esto, .hero hereda el padding vertical de `section` -hasta 92 px- y,
     como el fondo es azul, queda una franja de color vacía bajo la barra de
     botones y cifras. La portada cierra con esa barra, que ya trae su propio
     respiro (30/34 px). */
  padding-bottom:0;
}
/* Franja de contacto en el verde oscuro de la marca: sobre el azul del hero
   se perdía. Con el verde normal (#479591) el blanco no llega al contraste
   que pide un texto de 13 px; con este sí (5:1). */
.topbar{
  font-size:13px;color:#fff;
  background:linear-gradient(90deg,#2f6b67,var(--teal-dark) 50%,#2f6b67);
  box-shadow:inset 0 -1px 0 rgba(255,255,255,.12),0 6px 18px -10px rgba(10,34,79,.6);
  padding:10px 0;position:relative;z-index:1;
}
.topbar .wrap{display:flex;gap:26px;flex-wrap:wrap;overflow-wrap:anywhere;}
.topbar a{text-decoration:none;color:inherit;}
.topbar a:hover{text-decoration:underline;text-underline-offset:3px;}

.hero-imagen{width:100%;height:auto;display:block;}

/* ---------- hero con video de presentación ----------
   Cuando la portada tiene video, el hero se parte en dos: el mensaje a la
   izquierda y el reel a la derecha, en una tarjeta. Es el patrón de las webs
   corporativas con video institucional. El video no es un fondo -es un reel
   de motion graphics con sus propios rótulos y fondo casi blanco-, así que va
   enmarcado y entero, nunca recortado ni con texto encima: vista previa muda
   en bucle, y "Ver con sonido" lo abre grande. Sin video, nada de esto aplica
   y la portada es la de la imagen. */
.hero.con-video{
  overflow:hidden;
  background:
    radial-gradient(55% 65% at 76% 48%, rgba(71,149,145,.30), transparent 70%),
    radial-gradient(45% 55% at 8% 100%, rgba(57,129,178,.20), transparent 70%),
    var(--navy);
}
.hero-escena{position:relative;}
/* Curvas de nivel: el lenguaje de los planos topográficos, que es el oficio
   de la casa. Se desvanecen hacia la izquierda para no ensuciar el texto. */
.hero-escena::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:url("../img/fondos/curvas-nivel.b026d88b5153.svg") no-repeat 100% 50% / auto 125%;
  -webkit-mask-image:linear-gradient(90deg,transparent 5%,#000 55%);
          mask-image:linear-gradient(90deg,transparent 5%,#000 55%);
}
.hero-escena-in{
  position:relative;max-width:1280px;
  display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);
  align-items:center;gap:clamp(40px,5vw,76px);
  /* Llena la primera pantalla bajo la cabecera y la franja de contacto. */
  /* Las unidades de alto de pantalla se dividen por el zoom de las pantallas
     grandes: el navegador también las multiplica, y sin esto la portada
     medía el doble del alto de la pantalla en 4K. */
  min-height:calc(100vh / var(--zoom,1) - var(--alto-cabecera) - 41px);
  min-height:calc(100svh / var(--zoom,1) - var(--alto-cabecera) - 41px);
  padding-top:clamp(40px,7vh / var(--zoom,1),80px);padding-bottom:clamp(48px,8vh / var(--zoom,1),88px);
}
.hero-eyebrow{
  display:inline-flex;align-items:center;gap:12px;
  font-size:12px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--sky);
}
.hero-eyebrow::before{content:"";width:30px;height:2px;border-radius:2px;background:var(--teal);}
.hero-titular{margin-top:18px;font-size:clamp(42px,4.7vw,70px);line-height:.96;color:#fff;}
.hero-titular span{display:block;}
.hero-titular .acento{color:var(--sky);}
.hero-bajada{margin-top:22px;max-width:470px;font-size:16px;line-height:1.7;color:rgba(255,255,255,.76);}
.hero-mensaje .hero-actions{margin-top:34px;}
.hero-mensaje .hero-stats{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:22px;
  margin-top:38px;padding-top:26px;border-top:1px solid rgba(255,255,255,.12);
}
.hero-mensaje .hero-stats div{padding-right:0;}
.hero-mensaje .hero-stats b{font-size:36px;}
.hero-mensaje .hero-stats span{display:block;font-size:12.5px;line-height:1.4;margin-top:2px;}

/* La tarjeta del reel. */
.hero-reel{position:relative;margin:0;isolation:isolate;}
/* Marco desplazado: da profundidad sin añadir otro color. */
.hero-reel::before{
  content:"";position:absolute;inset:0;z-index:-1;
  transform:translate(22px,22px);
  border:1px solid rgba(127,203,232,.32);border-radius:22px;
}
/* Halo turquesa detrás de la tarjeta. */
.hero-reel::after{
  content:"";position:absolute;inset:-14% -12%;z-index:-2;
  background:radial-gradient(closest-side,rgba(71,149,145,.42),transparent);
}
.hero-reel-marco{
  position:relative;aspect-ratio:16/9;border-radius:18px;overflow:hidden;
  /* Mientras carga, el mismo degradado gris del primer fotograma del reel
     (medido sobre el archivo): el video entra sin que se note el cambio. */
  background:radial-gradient(ellipse at center,#f9f9f9 0%,#dddddd 45%,#b8b8b8 100%);
  box-shadow:0 0 0 1px rgba(255,255,255,.14),0 40px 90px -30px rgba(0,0,0,.6);
}
.hero-video{position:absolute;inset:0;width:100%;height:100%;display:block;object-fit:cover;}
/* Fundido de entrada cuando ya hay fotograma. Solo con JS: sin él, se ve
   desde el principio. */
.js .hero-video{opacity:0;transition:opacity .8s ease;}
.js .hero-video.lista{opacity:1;}
.hero-reel-barra{position:absolute;left:0;right:0;bottom:0;height:3px;background:rgba(10,34,79,.2);}
.hero-reel-barra span{
  display:block;height:100%;transform-origin:0 50%;transform:scaleX(0);
  background:linear-gradient(90deg,var(--teal),var(--sky));
}
.hero-reel-controles{
  /* Pausa abajo a la izquierda y "Ver con sonido" arriba a la derecha: el
     centro del cuadro queda libre, que es donde el reel pone sus rótulos, y
     ninguno de los dos cae en la esquina inferior derecha de la pantalla,
     donde está fijado WhatsApp (en tablet coincidían). */
  position:absolute;inset:14px 14px 16px;pointer-events:none;
  display:flex;flex-direction:column;justify-content:space-between;align-items:flex-start;
}
.hero-reel-controles > *{pointer-events:auto;}
/* Pausa: un video de 48 s en bucle que arranca solo necesita una forma de
   pararlo (WCAG 2.2.2). */
.hero-video-control,.hero-reel-sonido{
  height:40px;border:1px solid rgba(255,255,255,.35);color:#fff;cursor:pointer;
  background:rgba(10,34,79,.62);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  transition:background .2s ease, transform .2s ease;
}
.hero-video-control:hover,.hero-video-control:focus-visible,
.hero-reel-sonido:hover,.hero-reel-sonido:focus-visible{background:rgba(10,34,79,.9);}
.hero-video-control{width:40px;padding:0;border-radius:50%;display:grid;place-items:center;}
.hero-video-control svg{width:14px;height:14px;fill:currentColor;}
.hero-video-control .ico-play,
.hero-video-control.pausado .ico-pausa{display:none;}
.hero-video-control.pausado .ico-play{display:block;}
.hero-reel-sonido{
  order:-1;align-self:flex-end;display:inline-flex;align-items:center;gap:8px;
  padding:0 16px 0 13px;border-radius:999px;
  font:700 13px 'Poppins',system-ui,sans-serif;
}
.hero-reel-sonido:hover{transform:translateY(-1px);}
.hero-reel-sonido svg{width:16px;height:16px;fill:currentColor;}
/* display:grid y flex pisarían el `hidden` del HTML, que el JS quita al
   arrancar. */
.hero-video-control[hidden],.hero-reel-sonido[hidden]{display:none;}

/* Entrada: el mensaje sube por partes y la tarjeta detrás. `backwards` y no
   `both`: si la animación no llegara a correr, todo queda visible igual. */
.js .hero-mensaje > *,.js .hero-reel{animation:hero-entra .8s cubic-bezier(.2,.7,.2,1) backwards;}
.js .hero-mensaje > :nth-child(2){animation-delay:.07s;}
.js .hero-mensaje > :nth-child(3){animation-delay:.14s;}
.js .hero-mensaje > :nth-child(4){animation-delay:.21s;}
.js .hero-mensaje > :nth-child(5){animation-delay:.28s;}
.js .hero-reel{animation-duration:1s;animation-delay:.18s;}
@keyframes hero-entra{from{opacity:0;transform:translateY(18px);}to{opacity:1;transform:none;}}

/* Ventana con el reel completo y con sonido. */
.reel-dialogo{
  width:min(1120px,92vw);max-width:none;padding:0;border:0;overflow:visible;
  background:transparent;
}
.reel-dialogo::backdrop{
  background:rgba(6,18,43,.84);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
}
.reel-dialogo[open]{animation:hero-entra .35s ease backwards;}
.reel-completo{
  display:block;width:100%;aspect-ratio:16/9;border-radius:16px;background:#000;
  box-shadow:0 50px 120px -20px rgba(0,0,0,.7);
}
.reel-cerrar{
  position:absolute;top:-54px;right:0;width:42px;height:42px;padding:0;border-radius:50%;
  display:grid;place-items:center;cursor:pointer;
  border:1px solid rgba(255,255,255,.4);background:transparent;color:#fff;
}
.reel-cerrar:hover,.reel-cerrar:focus-visible{background:rgba(255,255,255,.12);}
.reel-cerrar svg{width:14px;height:14px;}

@media (max-width:1023px){
  .hero-escena-in{
    grid-template-columns:minmax(0,1fr);min-height:0;gap:36px;
    padding-top:clamp(32px,5vh,56px);
  }
  .hero-titular{font-size:clamp(40px,7.4vw,62px);}
  .hero-bajada{max-width:560px;}
  .hero-reel::before{transform:translate(14px,14px);}
}
@media (max-width:560px){
  /* En celular, sin textos: el dueño del proyecto pidió quitarlos. El h1 se
     queda en el HTML para buscadores y lectores de pantalla. El reel pasa
     delante, y los botones y las cifras quedan debajo. */
  .hero-escena-in{gap:30px;padding-top:24px;padding-bottom:40px;}
  .hero-reel{order:-1;}
  .hero-eyebrow,.hero-bajada{display:none;}
  .hero-titular{
    position:absolute;width:1px;height:1px;margin:0;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;
  }
  .hero-mensaje .hero-actions{margin-top:0;}
  .hero-mensaje .hero-stats{margin-top:28px;}
  .hero-mensaje .hero-stats b{font-size:30px;}
  .hero-reel::before{transform:translate(10px,10px);border-radius:18px;}
  .hero-reel-marco{border-radius:14px;}
  .hero-reel-controles{inset:10px 10px 12px;}
  /* A 320 px de ancho, unos controles de 40 px tapaban los rótulos del reel. */
  .hero-video-control,.hero-reel-sonido{height:32px;}
  .hero-video-control{width:32px;}
  .hero-video-control svg{width:11px;height:11px;}
  .hero-reel-sonido{gap:6px;padding:0 12px 0 10px;font-size:11.5px;}
  .hero-reel-sonido svg{width:14px;height:14px;}
}
@media (prefers-reduced-motion:reduce){
  .js .hero-video{transition:none;}
  .js .hero-mensaje > *,.js .hero-reel,.reel-dialogo[open]{animation:none;}
}

/* Texto en vivo: fuera de la vista, pero en el HTML. */
.hero-texto{
  position:absolute;width:1px;height:1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;
}

.hero-barra{background:var(--navy);padding:30px 0 34px;}
.hero-barra-in{display:flex;align-items:center;justify-content:space-between;gap:40px;flex-wrap:wrap;}
.hero-actions{display:flex;gap:16px;flex-wrap:wrap;}
.hero-stats{display:flex;gap:0;flex-wrap:wrap;}
.hero-stats div{padding-right:46px;}
.hero-stats div:last-child{padding-right:0;}
.hero-stats b{font-size:34px;display:block;color:var(--sky);}
.hero-stats span{font-size:13px;color:rgba(255,255,255,.75);}

@media (max-width:900px){
  /* El titular quemado en la pieza sería ilegible a este ancho, así que la
     imagen se recorta hacia la derecha, donde no lleva texto. El texto quemado
     termina en el 51,5 % del ancho, medido sobre el propio archivo, así que un
     recorte pegado a la derecha necesita ser al menos 1,17 veces más alto que
     ancho para no tocarlo. Con 3:4 (1,33) queda margen de sobra.

     El anclaje no es 100% sino 96%: pegado del todo a la derecha, el recorte
     deja la gota del logotipo descentrada hacia la izquierda -su eje está en
     el 75,7 % del ancho y el centro de la ventana caía en el 78,6 %-. Con 96 %
     la ventana empieza en el 55 % y su centro queda en el 76,3 %, encima de la
     gota, sin llegar a destapar el titular. */
  .hero-imagen{width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;object-position:96% center;}
  .hero-texto{
    position:static;width:auto;height:auto;
    overflow:visible;clip:auto;white-space:normal;
    padding-top:22px;padding-bottom:2px;
  }
  .hero-texto h1{font-size:clamp(32px,8.4vw,52px);color:#fff;}
  .hero-texto p{font-size:15px;color:rgba(255,255,255,.85);margin-top:12px;line-height:1.55;}
  .hero-barra-in{flex-direction:column;align-items:stretch;gap:26px;}
  .hero-actions{gap:12px;}
  .hero-actions .btn{flex:1;justify-content:center;}
  .hero-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;}
  .hero-stats div{padding-right:0;}
  .hero-stats b{font-size:28px;}
  .hero-stats span{font-size:12px;line-height:1.35;display:block;}
}

/* ---------- secciones ---------- */
section{padding:clamp(56px,6.5vw,92px) 0;position:relative;}
/* La última sección antes del pie no necesita su aire inferior completo:
   el pie ya aporta el suyo propio (48px), y sumar los dos dejaba hasta
   140px de blanco vacío antes del primer contenido del footer. */
main > section:last-of-type{padding-bottom:clamp(32px,4vw,48px);}
.section-head{max-width:640px;margin-bottom:40px;}
.section-head h2{font-size:clamp(32px,4.6vw,52px);color:var(--ink);}
.section-head p{color:var(--muted);font-size:16px;line-height:1.7;margin-top:16px;}
/* Dos secciones seguidas sobre el mismo fondo no necesitan el aire de las
   dos: sumaban 184 px del mismo color y se leían como un hueco vacío. */
.seccion-continua{padding-top:0;}

.tag{
  display:inline-block;font-size:12.5px;color:var(--teal);
  background:rgba(71,149,145,.1);padding:6px 14px;border-radius:999px;letter-spacing:.3px;
}

/* ---------- nosotros ---------- */
#nosotros{background:var(--card);}
.about-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:70px;align-items:start;}
.about-grid p{color:var(--muted);line-height:1.8;font-size:16.5px;margin-top:18px;}
.pillars{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
.pillar-card{background:var(--bg);border:1px solid var(--line);border-radius:var(--radius);padding:24px 22px;}
.pillar-card b{display:block;color:var(--teal);font-size:12.5px;letter-spacing:.4px;text-transform:uppercase;margin-bottom:8px;}
.pillar-card span{font-size:15.5px;font-weight:400;color:var(--ink);line-height:1.4;}

/* ---------- equipo ---------- */
.team-band{
  margin-top:72px;background:linear-gradient(120deg,var(--navy),var(--blue) 130%);
  border-radius:14px;padding:60px 50px;color:#fff;
}
.team-band h3{font-family:'Bebas Neue',Impact,sans-serif;font-size:34px;text-align:center;margin-bottom:8px;}
.team-band > p{text-align:center;color:rgba(255,255,255,.75);max-width:520px;margin:0 auto 42px;font-size:15px;}
/* Todos en una fila y del mismo ancho. --n, el número de integrantes, lo pone
   la plantilla; caben como mucho cinco por fila. Con flex centrado, una fila
   incompleta -en tableta y móvil- queda en el centro y no pegada a la
   izquierda. */
.team-grid{
  --hueco:18px;--por-fila:min(var(--n,5),5);
  display:flex;flex-wrap:wrap;justify-content:center;gap:var(--hueco);
  list-style:none;padding:0;margin:0;
}
.team-card{
  flex:0 0 calc((100% - (var(--por-fila) - 1) * var(--hueco)) / var(--por-fila));
  display:flex;flex-direction:column;overflow:hidden;
  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);border-radius:12px;
  transition:transform .3s ease,border-color .3s ease,background .3s ease;
}
.team-card a{flex:1;display:flex;flex-direction:column;text-decoration:none;color:inherit;}
.team-card:hover{transform:translateY(-4px);border-color:rgba(127,203,232,.45);background:rgba(255,255,255,.09);}
/* Todos los retratos miden lo mismo (560x653) y vienen en blanco y negro
   sobre fondo negro, con el mismo encuadre. Al pasar por encima, la foto se
   acerca un poco y se enciende una línea bajo ella. */
.team-photo{position:relative;aspect-ratio:560/653;overflow:hidden;background:#060606;}
.team-photo img{width:100%;height:100%;object-fit:cover;filter:grayscale(100%);transition:transform .5s ease;}
.team-card:hover .team-photo img{transform:scale(1.04);}
.team-photo::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--teal);
  transform:scaleX(0);transform-origin:left;transition:transform .35s ease;
}
.team-card:hover .team-photo::after{transform:scaleX(1);}
.team-info{flex:1;padding:16px 12px 18px;text-align:center;}
.team-info b{display:block;font-size:14px;line-height:1.3;}
.team-info span{display:block;margin-top:6px;font-size:12.5px;line-height:1.4;color:var(--sky);}
@media (prefers-reduced-motion:reduce){
  .team-card,.team-photo img,.team-photo::after{transition:none;}
  .team-card:hover,.team-card:hover .team-photo img{transform:none;}
}

/* ---------- servicios ---------- */
/* La banda azul se ajusta a su contenido en vez de cortar a una altura fija,
   y la tarjeta del acordeón monta sobre ella, como en el original. */
.seccion-servicios{background:var(--bg);padding-top:0;}
.serv-cabecera{
  background:linear-gradient(180deg,var(--navy),var(--navy-2));
  padding:clamp(64px,7vw,96px) 0 clamp(96px,10vw,132px);
}
.serv-head{color:#fff;text-align:center;max-width:680px;margin:0 auto;}
.serv-head h2{font-size:clamp(32px,5vw,54px);color:#fff;margin-top:18px;}
.serv-head p{color:rgba(255,255,255,.75);margin-top:14px;font-size:15.5px;}
.tag-claro{background:rgba(255,255,255,.14);color:#fff;}
.accordion{
  background:var(--card);border-radius:14px;box-shadow:0 30px 60px -30px rgba(10,34,79,.35);
  border:1px solid var(--line);position:relative;z-index:1;
}
/* Solo en la portada la tarjeta monta sobre la banda azul. En /servicios/ el
   acordeón va bajo la cabecera de página y un margen negativo lo metería
   dentro de ella. */
.seccion-servicios .accordion{margin-top:clamp(-72px,-6vw,-48px);}
.acc-item{border-bottom:1px solid var(--line);}
.acc-item:last-child{border-bottom:none;}
.acc-head{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:26px 32px;cursor:pointer;background:none;border:none;width:100%;text-align:left;
  font-family:'Poppins',system-ui,sans-serif;
}
.acc-head b{font-size:15.5px;letter-spacing:.3px;color:var(--ink);text-transform:uppercase;}
.acc-num{font-family:'Bebas Neue',Impact,sans-serif;color:var(--teal);font-size:15px;margin-right:14px;}
.acc-plus{
  width:30px;height:30px;border-radius:50%;border:1.5px solid var(--teal);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--teal);
  font-size:18px;transition:transform .25s ease, background .2s ease;
}
.acc-item.open .acc-plus{background:var(--teal);color:#fff;transform:rotate(135deg);}
.acc-body{max-height:0;overflow:hidden;transition:max-height .35s ease;}
.acc-item.open .acc-body{max-height:900px;}
.acc-body-in{padding:0 32px 30px 76px;display:grid;grid-template-columns:1fr 1fr;gap:8px 30px;list-style:none;margin:0;}
.acc-body-in li{font-size:14.5px;color:var(--muted);padding:4px 0;border-bottom:1px dashed var(--line);}
.acc-enlace{padding:0 32px 30px 76px;}
.acc-enlace a{color:var(--teal);font-size:14px;font-weight:700;text-decoration:none;}
.acc-enlace a:hover{text-decoration:underline;}

/* Foto de cada servicio, a la derecha de sus sub-ítems. La lista conserva la
   sangría bajo el título; la foto se alinea con el botón de abrir. Entra con
   un fundido y un leve acercamiento al abrir el servicio. */
.acc-body-grid.con-imagen{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(260px,38%);gap:32px;
  padding:0 32px 32px 76px;align-items:stretch;
}
.acc-body-grid.con-imagen .acc-body-in{padding:0;align-content:start;}
.acc-body-grid.con-imagen .acc-enlace{padding:18px 0 0;}
.acc-foto{
  position:relative;margin:0;min-height:230px;border-radius:12px;overflow:hidden;
  background:var(--bg);box-shadow:0 20px 44px -26px rgba(10,34,79,.5);
}
.acc-foto img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transform:scale(1.06);
  transition:opacity .6s ease .1s,transform 1.4s cubic-bezier(.2,.8,.2,1);
}
.acc-item.open .acc-foto img{opacity:1;transform:none;}
/* Velo muy suave hacia la esquina y una barra verde de la marca. */
.acc-foto::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(200deg,transparent 55%,rgba(10,34,79,.35));
}
.acc-foto::before{
  content:"";position:absolute;left:0;bottom:0;z-index:1;width:64px;height:4px;
  background:var(--teal);border-radius:0 4px 0 0;
}
/* Sin JavaScript el acordeón queda abierto: el contenido nunca se esconde. */
.no-js .acc-body{max-height:none;}
.no-js .acc-foto img{opacity:1;transform:none;}

/* ---------- plataforma ---------- */
.platform{
  margin-top:56px;background:var(--card);border:1px solid var(--line);border-radius:14px;
  padding:50px;display:grid;grid-template-columns:1fr 1fr;gap:50px;align-items:center;
}
.platform .tag{margin-bottom:14px;}
.platform h3{font-family:'Bebas Neue',Impact,sans-serif;font-size:30px;color:var(--ink);}
.platform p{color:var(--muted);margin-top:14px;line-height:1.7;font-size:15px;}
.platform .nota{color:var(--teal);font-weight:400;font-size:14px;margin-top:8px;}
/* Sin imagen, el bloque vuelve a una sola columna en vez de dejar un hueco
   vacío donde iría la segunda. */
.platform.sin-imagen{grid-template-columns:1fr;}
/* Sin border-radius: el PNG viene con el fondo ya quitado, así que no
   hay un rectángulo opaco que recortar. */
.platform-imagen{width:100%;height:auto;display:block;}

/* ---------- clientes ---------- */
.seccion-clientes{background:var(--bg);}
.clients-frame{border-radius:14px;overflow:hidden;border:1px solid var(--line);box-shadow:0 30px 60px -35px rgba(10,34,79,.3);}
.clients-strip{display:flex;gap:40px;margin-top:34px;flex-wrap:wrap;color:var(--muted);font-size:13.5px;list-style:none;padding:0;}

/* ---------- casos ---------- */
.case-card{
  background:linear-gradient(120deg,var(--navy),#0c2c5c);
  border-radius:16px;padding:56px;color:#fff;
  display:grid;grid-template-columns:1fr auto;gap:40px;align-items:center;
}
/* Con foto del proyecto o logo del cliente se abre una tercera columna entre
   el texto y la cifra; sin ninguno de los dos, el grid se queda en dos como
   antes -así una tarjeta sin nada que mostrar ahí no hereda un hueco extra. */
.case-card.con-imagen{grid-template-columns:1fr auto auto;}
.case-imagen{
  width:100%;max-width:220px;height:140px;border-radius:12px;
  object-fit:cover;justify-self:center;
}
.case-logo{
  background:#fff;border-radius:14px;padding:20px 26px;
  display:flex;align-items:center;justify-content:center;
}
.case-logo img{max-height:64px;max-width:150px;width:auto;height:auto;display:block;}
.case-card h3{font-family:'Bebas Neue',Impact,sans-serif;font-size:38px;}
.case-card p{color:rgba(255,255,255,.78);margin-top:14px;max-width:480px;line-height:1.7;font-size:15px;}
.case-tag{font-size:12.5px;color:var(--sky);}
.case-stat{text-align:center;}
.case-stat b{font-family:'Bebas Neue',Impact,sans-serif;font-size:56px;color:var(--sky);display:block;}
.case-stat span{font-size:13px;color:rgba(255,255,255,.7);}

/* ---------- contacto ---------- */
.seccion-contacto{background:var(--card);}
/* minmax(0,…) y no 1.1fr .9fr a secas: una columna de rejilla no encoge por
   debajo del mínimo de su contenido, y el <textarea> pide ~300 px por su
   número de columnas de fábrica. En pantallas angostas eso hinchaba el panel
   por encima de la tarjeta, que lo recortaba: los bordes salían descuadrados. */
.contact-grid{
  display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);gap:0;
  background:var(--navy);border-radius:16px;overflow:hidden;
}
.contact-form{padding:56px;}
.contact-form h3{font-family:'Bebas Neue',Impact,sans-serif;color:#fff;font-size:30px;}
.contact-form > p{color:rgba(255,255,255,.65);margin-top:10px;font-size:14.5px;}
.form-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin-top:26px;}
.field{margin-top:16px;}
.form-row .field{margin-top:0;}
.field label{display:block;font-size:12.5px;color:var(--sky);margin-bottom:7px;letter-spacing:.3px;}
.field input, .field textarea{
  width:100%;min-width:0;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.18);
  border-radius:8px;padding:13px 14px;color:#fff;font-family:'Poppins',system-ui,sans-serif;font-size:14.5px;
}
.field input::placeholder, .field textarea::placeholder{color:rgba(255,255,255,.4);}
.field textarea{resize:vertical;min-height:110px;}
.contact-form button{margin-top:24px;width:100%;justify-content:center;}
.contact-info{background:var(--teal);padding:56px;color:#fff;}
.contact-info h4{font-family:'Bebas Neue',Impact,sans-serif;font-size:24px;margin-bottom:26px;}
.ci-item{display:flex;gap:14px;margin-bottom:24px;align-items:flex-start;}
/* min-width:0: sin esto la columna del texto no encoge por debajo de su
   palabra más larga y el correo se salía del bloque en celular. */
.ci-item > div{min-width:0;}
.ci-ico{
  width:38px;height:38px;border-radius:50%;background:rgba(255,255,255,.18);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:16px;
}
.ci-item b{display:block;font-size:14.5px;}
.ci-item span, .ci-item a{
  display:block;font-size:13.5px;line-height:1.5;color:rgba(255,255,255,.85);
  text-decoration:none;overflow-wrap:anywhere;
}
.ci-item a:hover{text-decoration:underline;text-underline-offset:3px;}
.form-note{font-size:12px;color:rgba(255,255,255,.5);margin-top:14px;}
.trampa{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;}

/* ---------- avisos ---------- */
.avisos{list-style:none;padding:0;margin:0 0 24px;}
.aviso{padding:14px 18px;border-radius:8px;font-size:14.5px;margin-bottom:10px;}
.aviso-success{background:rgba(71,149,145,.14);color:var(--teal-dark);border:1px solid rgba(71,149,145,.35);}
.aviso-error{background:rgba(190,60,60,.1);color:#a03030;border:1px solid rgba(190,60,60,.3);}

/* ---------- pie ---------- */
footer{background:var(--navy);color:rgba(255,255,255,.7);padding:48px 0 22px;}
.foot-grid{display:grid;grid-template-columns:1.3fr 1fr 1fr 1fr;gap:28px;}
.foot-brand{display:flex;align-items:center;gap:10px;margin-bottom:10px;}
.foot-brand img{height:28px;margin-top:-2px;filter:brightness(0) invert(1);}
.foot-brand span{font-family:'Bebas Neue',Impact,sans-serif;font-size:19px;color:#fff;letter-spacing:1px;}
footer p{font-size:13.5px;line-height:1.55;max-width:280px;}
footer h5{color:#fff;font-size:13px;letter-spacing:.4px;text-transform:uppercase;margin-bottom:11px;}
footer ul{list-style:none;padding:0;margin:0;}
/* El correo es una palabra indivisible de más de 200 px: sin esto, la
   columna del pie no puede encoger y desborda la pantalla del móvil. */
footer li{margin-bottom:6px;font-size:13.5px;overflow-wrap:anywhere;}
footer a{text-decoration:none;color:rgba(255,255,255,.7);}
footer a:hover{color:var(--sky);}
.foot-redes{display:flex;gap:14px;margin-top:10px;}
.foot-redes a{font-size:13px;color:var(--sky);}
.foot-bottom{
  border-top:1px solid rgba(255,255,255,.12);margin-top:26px;padding-top:16px;
  display:flex;justify-content:space-between;font-size:12.5px;color:rgba(255,255,255,.5);flex-wrap:wrap;gap:10px;
}

/* ---------- WhatsApp ---------- */
.whatsapp{
  position:fixed;right:22px;bottom:22px;z-index:60;
  width:56px;height:56px;border-radius:50%;background:#25d366;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 10px 26px -6px rgba(37,211,102,.6);
  transition:transform .2s ease;
}
.whatsapp:hover{transform:scale(1.07);}
.whatsapp svg{width:30px;height:30px;fill:#fff;}

/* ---------- aparición al hacer scroll ----------
   El estado oculto solo se aplica si hay JavaScript; sin él, el contenido
   se ve desde el principio en lugar de quedarse invisible para siempre. */
.js .reveal{opacity:0;transform:translateY(18px);transition:opacity .6s ease, transform .6s ease;}
.js .reveal.in{opacity:1;transform:none;}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  .js .reveal{opacity:1;transform:none;transition:none;}
  .btn:hover,.whatsapp:hover{transform:none;}
  .acc-body{transition:none;}
  .acc-foto img{transition:none;transform:none;}
}

@media (max-width:900px){
  .about-grid, .platform, .contact-grid, .case-card, .case-card.con-imagen{grid-template-columns:minmax(0,1fr);}
  .case-imagen{max-width:100%;justify-self:stretch;}
  .case-logo{justify-self:start;}
  .team-grid{--por-fila:min(var(--n,3),3);}
  .foot-grid{grid-template-columns:1fr 1fr;}
  .acc-body-in{grid-template-columns:1fr;}
  /* En tableta y móvil la foto va encima de la lista, a lo ancho. */
  .acc-body-grid.con-imagen{grid-template-columns:1fr;gap:22px;padding:0 24px 28px;}
  .acc-foto{order:-1;min-height:0;aspect-ratio:16/9;}
  /* Con la foto encima, un servicio largo pasa de los 900 px del tope y la
     última línea se cortaba. */
  .acc-item.open .acc-body{max-height:2000px;}
  /* El botón de la cabecera no cabe junto a la marca y la hamburguesa, y
     empujaba el contenido fuera del ancho de la pantalla. El menú ya lleva
     "Contacto", así que aquí sobra. */
  .header-in > .btn{display:none;}
  .navlinks{
    position:fixed;top:var(--alto-cabecera);left:0;right:0;background:#fff;flex-direction:column;
    padding:20px 28px;gap:18px;border-bottom:1px solid var(--line);transform:translateY(-130%);
    transition:transform .3s ease;
  }
  .navlinks.open{transform:translateY(0);}
  .burger{display:block;}
  /* La franja de contacto convertía la parte alta de la portada en un bloque
     azul de casi media pantalla. Aquí solo se compacta y se centra; en una
     tablet los tres datos caben de sobra en una línea. */
  .topbar{padding:7px 0;}
  .topbar .wrap{gap:18px;font-size:11.5px;justify-content:center;}
}
@media (max-width:560px){
  /* En celular el texto en vivo no se pinta. Sostenerlo obligaba a un bloque
     azul que se comía media pantalla y que el dueño del proyecto pidió quitar;
     así la portada del móvil queda como franja de contacto + fotografía, sin
     slab de color. En tablet sí se mantiene: ahí el bloque cabe sin dominar.
     Se vuelve al recorte de accesibilidad de la regla base, así que el h1 y la
     bajada siguen en el HTML y los leen buscadores y lectores de pantalla. */
  .hero-texto{
    position:absolute;width:1px;height:1px;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;
    padding-top:0;padding-bottom:0;
  }

  /* Ya en móvil: la dirección se oculta -no es accionable con el pulgar, y
     sigue en el pie, en la sección de contacto y en el HTML para los
     buscadores-, y la franja apura el margen lateral, porque con los 28 px de
     .wrap no cabía en una línea a 375 px, que es el iPhone SE actual. Así
     pasa de tres líneas a una. */
  .topbar .wrap{gap:14px;font-size:10.5px;padding-left:16px;padding-right:16px;}
  .topbar .wrap span{display:none;}

  /* El rótulo y su flecha son un solo nodo de texto, así que al no caber la
     flecha se iba a una segunda línea y descuadraba el botón. Con nowrap no se
     parte, y para que los dos botones quepan juntos en una línea se recorta el
     relleno lateral y un punto el cuerpo. */
  .hero-actions .btn{white-space:nowrap;padding:13px 18px;font-size:14px;}
  .foot-grid{grid-template-columns:1fr;}
  .form-row{grid-template-columns:minmax(0,1fr);}
  .team-grid{--por-fila:min(var(--n,2),2);--hueco:12px;}
  /* La banda pierde casi todo su margen interior: con los 50 px de escritorio
     las tarjetas se quedaban en ~106 px y los cargos se cortaban. */
  .team-band{padding:40px 16px;}
  .team-band > p{margin-bottom:28px;}
  .team-info{padding:12px 8px 14px;}
  .team-info b{font-size:13px;}
  .team-info span{font-size:12px;overflow-wrap:anywhere;}
  .case-card{padding:34px;}
  .case-logo{padding:14px 20px;}
  .case-logo img{max-height:48px;max-width:120px;}
  .contact-form, .contact-info{padding:34px;}
}

/* ---------- páginas interiores ----------
   La maqueta era de una sola página, así que estas cabeceras no salen de
   ella: reutilizan los mismos tokens y el degradado azul de la banda de
   equipo para no introducir lenguaje visual nuevo. */
.page-head{
  background:linear-gradient(160deg,var(--navy),var(--navy-2));
  color:#fff;padding:calc(var(--alto-cabecera) + 78px) 0 72px;
}
.page-head h1{font-size:clamp(34px,5.2vw,62px);color:#fff;}
.page-head p{color:rgba(255,255,255,.8);max-width:640px;margin-top:16px;line-height:1.7;font-size:16px;}
.page-head .tag{background:rgba(255,255,255,.12);color:#fff;}
.migas{font-size:13px;color:rgba(255,255,255,.6);margin-bottom:20px;}
.migas a{text-decoration:none;}
.migas a:hover{color:var(--sky);}

.seccion-interior{padding:clamp(48px,5vw,72px) 0 clamp(56px,6.5vw,92px);}
.detalle{display:grid;grid-template-columns:1.4fr .6fr;gap:60px;align-items:start;}
.detalle h2{font-size:28px;margin-bottom:16px;}
.detalle p{color:var(--muted);line-height:1.8;font-size:16px;}
.detalle-items{
  list-style:none;padding:0;margin:24px 0 0;
  display:grid;grid-template-columns:1fr 1fr;gap:8px 30px;
}
.detalle-items li{font-size:14.5px;color:var(--muted);padding:8px 0;border-bottom:1px dashed var(--line);}
.ficha{
  background:var(--card);border:1px solid var(--line);border-radius:14px;padding:28px;
  box-shadow:0 24px 50px -34px rgba(10,34,79,.35);
}
.ficha h3{font-size:20px;margin-bottom:16px;}
.ficha dl{margin:0;font-size:14px;}
.ficha dt{color:var(--teal);font-size:12.5px;margin-top:14px;}
.ficha dd{margin:4px 0 0;color:var(--muted);}
.ficha .btn{margin-top:24px;width:100%;justify-content:center;}

.tarjetas{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:24px;}
.tarjeta{
  background:var(--card);border:1px solid var(--line);border-radius:12px;padding:30px;
  display:flex;flex-direction:column;text-decoration:none;color:inherit;
  transition:transform .18s ease, box-shadow .18s ease;
}
.tarjeta:hover{transform:translateY(-3px);box-shadow:0 24px 44px -30px rgba(10,34,79,.4);}
.tarjeta .acc-num{display:block;margin-bottom:10px;font-size:16px;}
.tarjeta h2{font-size:22px;color:var(--ink);}
.tarjeta p{color:var(--muted);font-size:14.5px;line-height:1.7;margin-top:12px;}
.tarjeta .mas{margin-top:auto;padding-top:18px;color:var(--teal);font-weight:700;font-size:14px;}

.perfil{display:grid;grid-template-columns:340px 1fr;gap:50px;align-items:start;}
.perfil .team-photo{border-radius:12px;border:1px solid var(--line);}
.perfil .cargo{color:var(--teal);font-weight:700;font-size:15px;margin-top:6px;}
.perfil .pendiente{color:var(--muted);font-size:15px;margin-top:20px;line-height:1.8;}

.vacio{color:var(--muted);font-size:16px;}

@media (max-width:900px){
  .detalle, .perfil{grid-template-columns:1fr;gap:36px;}
  .detalle-items{grid-template-columns:1fr;}
  .perfil{max-width:420px;}
}

/* Errores de validación de un campo del formulario de contacto. */
.campo-error{color:#ffb4b4;font-size:12.5px;margin:6px 0 0;}
.contact-form .avisos{margin-top:18px;}
.contact-form .aviso-success{background:rgba(127,203,232,.16);color:#fff;border-color:rgba(127,203,232,.45);}
.contact-form .aviso-error{background:rgba(255,120,120,.14);color:#ffd7d7;border-color:rgba(255,120,120,.4);}

/* Entradilla de las páginas de detalle. */
.lead{font-size:18px;line-height:1.75;color:var(--ink);font-weight:400;}
.detalle .lead + p{margin-top:18px;}

/* Listas de "otros servicios" / "otros casos" / "resto del equipo". */
.ficha-lista{list-style:none;padding:0;margin:0;font-size:14.5px;}
.ficha-lista li{padding:9px 0;border-bottom:1px solid var(--line);color:var(--muted);}
.ficha-lista li:last-child{border-bottom:none;}
.ficha-lista a{text-decoration:none;color:var(--ink);font-weight:400;}
.ficha-lista a:hover{color:var(--teal);}

/* Sin cuerpo de texto, la ficha no debe quedar flotando junto a un hueco. */
.detalle-sin-cuerpo{grid-template-columns:1fr;max-width:560px;}

/* ---------- mapa de clientes ---------- */
/* El mapa a un lado y, al otro, el panel con los clientes de la región
   elegida. Sin JavaScript el panel lista todas las regiones seguidas; con él
   enseña una sola y las va recorriendo (mapa-clientes.js). */
.mapa-grid{display:grid;grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);gap:28px;align-items:stretch;}

.mapa-lienzo{
  position:relative;display:flex;flex-direction:column;justify-content:center;
  background:var(--card);border:1px solid var(--line);border-radius:18px;padding:28px 22px;
  box-shadow:0 24px 50px -34px rgba(10,34,79,.35);
}
/* Retícula de puntos muy tenue: da sensación de plano sin competir con el mapa. */
.mapa-lienzo::before{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background-image:radial-gradient(rgba(10,34,79,.09) 1px,transparent 1.4px);background-size:18px 18px;
  -webkit-mask-image:radial-gradient(ellipse at center,#000 25%,transparent 72%);
          mask-image:radial-gradient(ellipse at center,#000 25%,transparent 72%);
}
/* El trazado es muy vertical (542x792): a todo el ancho de la columna se
   iría a casi 900 px de alto, así que manda la altura y el ancho se ajusta. */
#mapa-peru{position:relative;display:block;margin:0 auto;height:auto;max-height:600px;width:auto;max-width:100%;overflow:visible;}

/* Regiones sin clientes: se dibujan, pero apagadas y sin interacción. */
#mapa-peru .region{fill:#dfe8ef;stroke:#fff;stroke-width:1.1;transition:fill .5s ease;}
#mapa-peru .region.con-clientes{fill:var(--blue);cursor:pointer;}
#mapa-peru .region.con-clientes:hover{fill:#5b9fcb;transition-duration:.15s;}
#mapa-peru .region.activa{fill:var(--teal);}
/* Sin anillo de foco: en un <path> el navegador dibuja un rectángulo alrededor
   de la región. Al teclado se le marca el contorno. */
#mapa-peru .region:focus{outline:none;}
#mapa-peru .region.con-clientes:focus-visible{stroke:var(--navy);stroke-width:3;}
#mapa-peru .lago{fill:#cfe6f2;stroke:#fff;stroke-width:1;pointer-events:none;}

/* Entrada: la primera vez que el mapa aparece en pantalla, las regiones con
   clientes se encienden una tras otra (el orden lo pone mapa-clientes.js). */
.mapa-grid.por-entrar #mapa-peru .region.con-clientes{fill:#dfe8ef;}
.mapa-grid.entrando #mapa-peru .region.con-clientes{transition-delay:calc(var(--orden,0) * 70ms);}

/* La región elegida, dibujada otra vez encima: algo levantada y con sombra. */
.mapa-realce{
  fill:var(--teal);stroke:#fff;stroke-width:1.6;stroke-linejoin:round;pointer-events:none;
  filter:url(#mapa-sombra);transform-box:fill-box;transform-origin:center;transform:scale(1.035);
  animation:mapa-realce .7s cubic-bezier(.2,.8,.2,1) both;
}
/* Cae sobre el mapa como un sello: entra grande y se asienta con un rebote. */
@keyframes mapa-realce{0%{opacity:0;transform:scale(1.3);}55%{opacity:1;transform:scale(.97);}100%{transform:scale(1.035);}}

/* El marcador viaja de una región a otra. */
.mapa-marcador{pointer-events:none;transition:transform .7s cubic-bezier(.65,0,.35,1);}
.mapa-marcador-punto{fill:#fff;stroke:var(--navy);stroke-width:2.5;}
.mapa-marcador-onda{
  fill:rgba(255,255,255,.35);stroke:#fff;stroke-width:1.5;
  transform-box:fill-box;transform-origin:center;
  animation:mapa-onda 2.2s cubic-bezier(.2,.6,.3,1) infinite;
}
@keyframes mapa-onda{from{transform:scale(.7);opacity:1;}to{transform:scale(3);opacity:0;}}
/* Onda de llegada: se abre una sola vez cuando el marcador toca la región. */
.mapa-marcador-llegada{
  fill:none;stroke:var(--sky);stroke-width:2;transform-box:fill-box;transform-origin:center;
  animation:mapa-llegada .9s ease-out .55s both;
}
@keyframes mapa-llegada{from{transform:scale(.4);opacity:.95;}to{transform:scale(5);opacity:0;}}
/* La ruta de la región anterior a la nueva: se dibuja mientras viaja el
   marcador y se desvanece. El largo del guion lo mide mapa-clientes.js. */
.mapa-ruta{
  fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round;pointer-events:none;
  opacity:0;animation:mapa-ruta 1.3s cubic-bezier(.65,0,.35,1) both;
}
@keyframes mapa-ruta{
  0%{stroke-dashoffset:var(--largo,0);opacity:.9;}
  55%{stroke-dashoffset:0;opacity:.9;}
  100%{stroke-dashoffset:0;opacity:0;}
}
.mapa-grid:not(.visto) .mapa-realce,
.mapa-grid:not(.visto) .mapa-ruta,
.mapa-grid:not(.visto) .mapa-marcador{visibility:hidden;}

/* Nombre de la región junto al puntero. */
.mapa-etiqueta{
  position:absolute;left:0;top:0;z-index:2;pointer-events:none;white-space:nowrap;
  transform:translate(-50%,calc(-100% - 14px));
  background:var(--navy);color:#fff;font-size:12.5px;font-weight:600;letter-spacing:.2px;
  padding:6px 10px;border-radius:8px;box-shadow:0 10px 24px -10px rgba(10,34,79,.5);
}
.mapa-etiqueta[hidden]{display:none;}

/* ---- el panel ---- */
.mapa-panel{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  border-radius:18px;padding:32px 32px 30px;color:#fff;
  background:
    radial-gradient(120% 70% at 100% 0%,rgba(71,149,145,.32),transparent 60%),
    linear-gradient(160deg,var(--navy),#0c2c5c);
  box-shadow:0 30px 60px -32px rgba(10,34,79,.6);
}
.mapa-panel-cabeza{display:flex;align-items:center;justify-content:space-between;gap:14px 18px;flex-wrap:wrap;}
.mapa-cifras{margin:0;font-size:12.5px;font-weight:600;letter-spacing:.7px;text-transform:uppercase;color:rgba(255,255,255,.68);}
.mapa-cifras b{color:#fff;font-size:15px;letter-spacing:0;}
.mapa-cifras span{margin:0 6px;color:var(--sky);}

.mapa-controles{display:flex;align-items:center;gap:6px;}
.mapa-controles button{
  width:36px;height:36px;border-radius:50%;padding:0;cursor:pointer;
  display:grid;place-items:center;color:#fff;background:transparent;
  border:1px solid rgba(255,255,255,.22);transition:background .2s ease,border-color .2s ease;
}
.mapa-controles button:hover{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.5);}
.mapa-controles button:focus-visible{outline:2px solid var(--sky);outline-offset:2px;}
.mapa-controles svg{width:14px;height:14px;fill:currentColor;}
.mapa-pausa{margin-left:6px;}
.mapa-controles[hidden],.mapa-controles button[hidden],.mapa-controles svg[hidden]{display:none;}
.mapa-contador{min-width:64px;text-align:center;font-size:13px;color:rgba(255,255,255,.55);font-variant-numeric:tabular-nums;}
.mapa-contador b{color:#fff;font-size:15px;}
.mapa-grid.interactivo .mapa-contador-actual{display:inline-block;animation:mapa-cifra .45s cubic-bezier(.2,.8,.2,1) both;}
@keyframes mapa-cifra{from{opacity:0;transform:translateY(calc(var(--sentido,1) * 70%));}}

/* La barra lleva el tiempo del recorrido: cuando se llena, mapa-clientes.js pasa a la
   región siguiente. Pausarla aquí pausa también el recorrido. */
.mapa-progreso{height:2px;margin:18px 0 26px;border-radius:2px;overflow:hidden;background:rgba(255,255,255,.12);}
.mapa-progreso span{display:block;height:100%;background:linear-gradient(90deg,var(--teal),var(--sky));transform:scaleX(0);transform-origin:left;}
.mapa-grid.en-recorrido .mapa-progreso span{animation:mapa-avance 2s linear forwards;}
.mapa-grid.detenido .mapa-progreso span{animation-play-state:paused;}
@keyframes mapa-avance{to{transform:scaleX(1);}}

/* Cuando mapa-clientes.js arranca (clase .interactivo), las fichas se apilan en la
   misma celda: el panel toma el alto de la más larga y no salta al cambiar
   de región. Depende de esa clase y no de .js a secas: si el script no llega
   a ejecutarse -con error, bloqueado o una copia vieja en caché- el panel se
   queda con la lista completa en vez de atascado en la primera región. */
.mapa-detalles{flex:1;}
.mapa-grid.interactivo .mapa-detalles{display:grid;}
/* El cambio de región. La ficha que se va sale hacia un lado, desenfocándose;
   la nueva entra por el otro (--sentido lo pone mapa-clientes.js: 1 al
   avanzar, -1 al retroceder). Dentro, el nombre sube tras una cortina, la
   línea de debajo se traza y los clientes llegan uno detrás de otro. */
.mapa-grid.interactivo .mapa-detalle{
  position:relative;isolation:isolate;grid-area:1/1;visibility:hidden;opacity:0;
  transform:translateX(calc(var(--sentido,1) * -40px));filter:blur(6px);
  transition:opacity .35s ease,transform .45s cubic-bezier(.4,0,.2,1),filter .35s ease,visibility 0s linear .45s;
}
.mapa-grid.interactivo .mapa-detalle.activo{
  visibility:visible;opacity:1;transform:none;filter:none;transition:none;
  animation:mapa-ficha-entra .6s cubic-bezier(.2,.8,.2,1) both;
}
.mapa-grid.arrancando .mapa-detalle{transition:none !important;}
@keyframes mapa-ficha-entra{from{opacity:0;transform:translateX(calc(var(--sentido,1) * 48px));filter:blur(6px);}}

.mapa-grid.interactivo .mapa-detalle.activo h3{animation:mapa-nombre .7s cubic-bezier(.2,.8,.2,1) .1s both;}
@keyframes mapa-nombre{
  from{opacity:0;transform:translateY(45%);clip-path:inset(-10% -5% 100% -5%);}
  to{clip-path:inset(-10% -5% -20% -5%);}
}
.mapa-grid.interactivo .mapa-detalle.activo .mapa-detalle-cabeza p{animation:mapa-sube .5s cubic-bezier(.2,.7,.2,1) .25s both;}
.mapa-grid.interactivo .mapa-detalle-cabeza{position:relative;border-bottom-color:transparent;}
.mapa-grid.interactivo .mapa-detalle-cabeza::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;transform-origin:left;
  background:linear-gradient(90deg,var(--sky),rgba(255,255,255,.12) 45%);
}
.mapa-grid.interactivo .mapa-detalle.activo .mapa-detalle-cabeza::after{animation:mapa-linea .8s cubic-bezier(.2,.8,.2,1) .15s both;}
.mapa-grid.interactivo .mapa-detalle.activo .mapa-clientes li{
  animation:mapa-tarjeta .55s cubic-bezier(.2,.8,.2,1) both;animation-delay:calc(200ms + var(--i,0) * 70ms);
}
@keyframes mapa-sube{from{opacity:0;transform:translateY(14px);}}
@keyframes mapa-linea{from{transform:scaleX(0);}}
@keyframes mapa-tarjeta{from{opacity:0;transform:translateY(18px) scale(.94);}}

/* Numeral de fondo: el orden de la región, grande y en contorno. Ocupa el
   aire que queda bajo las regiones con pocos clientes. Es decoración: el
   texto alternativo vacío lo calla para los lectores de pantalla. */
.mapa-grid.interactivo .mapa-detalle::after{
  content:attr(data-orden);content:attr(data-orden) / "";
  position:absolute;right:-8px;bottom:-34px;z-index:-1;pointer-events:none;
  font-family:'Bebas Neue',Impact,sans-serif;font-size:clamp(150px,16vw,230px);line-height:1;
  color:transparent;-webkit-text-stroke:1.5px rgba(255,255,255,.09);
}
.mapa-grid.interactivo .mapa-detalle.activo::after{animation:mapa-numeral .9s cubic-bezier(.2,.8,.2,1) .05s both;}
@keyframes mapa-numeral{from{opacity:0;transform:translateY(40px) scale(.92);}}

.mapa-detalle-cabeza{
  display:flex;align-items:baseline;justify-content:space-between;gap:10px 16px;flex-wrap:wrap;
  padding-bottom:18px;margin-bottom:20px;border-bottom:1px solid rgba(255,255,255,.12);
}
.mapa-detalle h3{margin:0;color:#fff;font-size:clamp(28px,2.9vw,40px);line-height:1.1;}
.mapa-detalle-cabeza p{margin:0;color:var(--sky);font-weight:700;font-size:12.5px;letter-spacing:.7px;text-transform:uppercase;white-space:nowrap;}

.mapa-clientes{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;align-content:start;}
.mapa-clientes li{
  display:flex;align-items:center;gap:12px;padding:9px 12px 9px 9px;border-radius:12px;
  background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.08);
  transition:background .2s ease,border-color .2s ease;
}
.mapa-clientes li:hover{background:rgba(255,255,255,.09);border-color:rgba(255,255,255,.18);}
/* Los logos llegan en tamaños y proporciones muy distintos: la caja blanca
   los iguala sin deformarlos. */
.mapa-logo{position:relative;flex:none;display:grid;place-items:center;width:60px;height:42px;border-radius:8px;background:#fff;overflow:hidden;}
/* Posicionado sobre la caja, que tiene alto fijo: como hijo de la rejilla, el
   height:100% no tenía contra qué resolverse, se quedaba en auto y el logo
   (casi todos son cuadrados) se salía por arriba y por abajo. */
.mapa-logo img{position:absolute;top:5px;left:5px;width:calc(100% - 10px);height:calc(100% - 10px);object-fit:contain;}
.mapa-logo-inicial{font-family:'Poppins',system-ui,sans-serif;font-weight:700;font-size:17px;color:var(--teal);}
.mapa-cliente-nombre{font-size:14px;line-height:1.35;color:rgba(255,255,255,.92);}

.mapa-nota{margin:22px 0 0;padding-top:16px;border-top:1px solid rgba(255,255,255,.12);font-size:13.5px;line-height:1.6;color:rgba(255,255,255,.65);}
.mapa-panel-vacio h3{color:#fff;font-size:26px;}
.mapa-panel-vacio p{color:rgba(255,255,255,.75);font-size:15px;line-height:1.7;margin-top:12px;}
.mapa-anuncio{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;}

/* Sin el script no hay recorrido: las fichas van seguidas, con scroll propio. */
.mapa-grid:not(.interactivo) .mapa-progreso{display:none;}
.mapa-grid:not(.interactivo) .mapa-detalles{max-height:560px;overflow-y:auto;padding-right:6px;margin-top:22px;}
.mapa-grid:not(.interactivo) .mapa-detalle + .mapa-detalle{margin-top:30px;}

/* Icono del cliente en la ficha de un caso: el logo cuando existe, o una
   inicial de relleno cuando no, para que la fila no cambie de alto. */
.logo-cliente{
  width:28px;height:28px;flex-shrink:0;border-radius:6px;
  object-fit:contain;background:#fff;border:1px solid var(--line);
}
.logo-cliente--sin{
  display:flex;align-items:center;justify-content:center;
  background:var(--bg);color:var(--teal);font-weight:700;font-size:13px;
  font-family:'Poppins',system-ui,sans-serif;
}

@media (prefers-reduced-motion:reduce){
  #mapa-peru .region,.mapa-marcador,.mapa-grid.interactivo .mapa-detalle{transition:none;}
  .mapa-realce,.mapa-marcador-onda,.mapa-marcador-llegada,
  .mapa-grid.interactivo .mapa-contador-actual,
  .mapa-grid.interactivo .mapa-detalle.activo,
  .mapa-grid.interactivo .mapa-detalle.activo::after,
  .mapa-grid.interactivo .mapa-detalle.activo h3,
  .mapa-grid.interactivo .mapa-detalle.activo .mapa-detalle-cabeza p,
  .mapa-grid.interactivo .mapa-detalle.activo .mapa-detalle-cabeza::after,
  .mapa-grid.interactivo .mapa-detalle.activo .mapa-clientes li{animation:none;}
  .mapa-ruta{display:none;}
}

@media (max-width:900px){
  .mapa-grid{grid-template-columns:minmax(0,1fr);gap:18px;}
  #mapa-peru{max-height:440px;}
  .mapa-panel{padding:26px 22px 24px;}
}
@media (max-width:560px){
  .mapa-lienzo{padding:18px 12px;}
  #mapa-peru{max-height:380px;}
  .mapa-progreso{margin:16px 0 22px;}
  /* Tarjetas en vertical, dos por fila: con una sola columna la región más
     larga dejaba un hueco enorme en las demás. */
  .mapa-clientes{gap:8px;}
  .mapa-clientes li{flex-direction:column;align-items:stretch;gap:8px;padding:8px 8px 10px;}
  .mapa-logo{width:100%;height:46px;}
  .mapa-cliente-nombre{font-size:13px;padding:0 2px;}
}

/* La fila de "Cliente" en la ficha de un caso, con el logo si existe. */
.ficha-cliente{display:flex;align-items:center;gap:10px;}
