/* ==========================================================================
   FaroRed — portada
   Paleta y tipografías tomadas de la Guía visual FaroRed v2.
   ========================================================================== */

@font-face{
  font-family:'Nunito'; font-style:normal; font-weight:800; font-display:swap;
  src:url(../assets/fonts/nunito-800.woff2) format('woff2');
}
@font-face{
  font-family:'Nunito'; font-style:normal; font-weight:900; font-display:swap;
  src:url(../assets/fonts/nunito-900.woff2) format('woff2');
}
@font-face{
  font-family:'IBM Plex Sans'; font-style:normal; font-weight:400; font-display:swap;
  src:url(../assets/fonts/plex-400.woff2) format('woff2');
}
@font-face{
  font-family:'IBM Plex Sans'; font-style:normal; font-weight:500; font-display:swap;
  src:url(../assets/fonts/plex-500.woff2) format('woff2');
}

@property --k{
  syntax:'<number>'; inherits:false; initial-value:0;
}

:root{
  /* Marca (Guía visual v2) */
  --navy:#03416C;
  --navy-deep:#02304F;
  --coral:#F85A4E;
  --cream:#F6F4EE;
  --mist:#B7CBDB;
  --ink:#14293A;
  --green:#1F8A5B;
  /* Verde de botón: #1F8A5B da 4,33:1 con blanco (bajo AA).
     Oscurecido a 5,92:1 para texto pequeño. */
  --green-btn:#17724B;

  /* Fondo de la portada */
  --void:#02080F;
  --void-2:#04121F;

  --display:'Nunito','Trebuchet MS',system-ui,sans-serif;
  --text:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;

  --anchor-x:50%;
  --anchor-y:44%;
  --beacon-w:clamp(54px,6.5vmin,80px);
}

*,*::before,*::after{box-sizing:border-box}

html,body{height:100%}
body{
  margin:0;
  background:var(--void);
  color:var(--cream);
  font-family:var(--text);
  font-size:16px;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}

/* --------------------------------------------------------------- escena --- */

/* El mapa ocupa toda la ventana y crece con ella */
.scene{
  position:fixed; inset:0; z-index:0;
  overflow:hidden;
  background:#05080c;
}

/* Leaflet map container */
/* Leaflet trae background (#ddd) en el contenedor. Sobre un fondo nocturno eso
   se ve como una mancha blanca mientras cargan los tiles o donde no alcanzan.
   Se pinta del mismo tono que la escena. */
#map{
  position:absolute; inset:0;
  width:100%; height:100%;
  z-index:1;
  background:#05080c;
}

/* Los tiles base quedan de noche: no gris opaco, casi apagados, para que la
   luz del faro sea lo único que los revele. */
.map-tiles{
  /* Se veía prácticamente negro (luminancia 17-47/255): se perdía el mapa,
     que es la mitad del concepto. Sube a un punto medio donde se distinguen
     las calles sin perder el aire nocturno. */
  filter:brightness(.34) contrast(1.02) saturate(.42) hue-rotate(200deg);
  opacity:.88;
}

/* Capa iluminada de la ciudad: se dibuja sobre el mapa y solo se ve donde
   pasa el haz. Por eso la luz "alumbra" de verdad y no solo tiñe. */
#city-layer{
  position:absolute; inset:0;
  width:100%; height:100%;
  z-index:2;
  pointer-events:none;
  /* Las calles toman color de luz de sodio al quedar bajo el haz. Sin
     brightness alto: la ciudad se ve iluminada, no quemada. */
  filter:sepia(.62) saturate(2.6) hue-rotate(-16deg) brightness(.72) contrast(1.2);
}

/* Luces independientes del haz: vehículos, faroles y alertas. Se dibujan
   siempre, pero su brillo sube cuando el haz pasa por encima. */
#lights-layer{
  position:absolute; inset:0;
  width:100%; height:100%;
  z-index:3;
  pointer-events:none;
}

/* Haz volumétrico */
#beam-overlay{
  position:absolute; inset:0;
  width:100%; height:100%;
  z-index:4;
  pointer-events:none;
}

/* El faro se ancla por su farol: el símbolo se desplaza para que el centro
   de la linterna (49,8% x 30,1% del PNG) caiga sobre el origen del haz. */
/* Origen de la luz del faro. Antes era marca.png —el mismo faro que el logo
   del header—, así que el símbolo aparecía dos veces y la vista saltaba
   entre ambos. Ahora es una fuente de luz dibujada: un núcleo cálido con
   anillos que laten hacia afuera. Se centra en el punto exacto desde donde
   sale el haz. */
.beacon{
  position:absolute;
  left:var(--anchor-x);
  top:var(--anchor-y);
  width:var(--beacon-w);
  height:var(--beacon-w);
  z-index:12;
  transform:translate(-50%,-50%);
  display:grid;
  place-items:center;
  pointer-events:none;
}

/* núcleo: el punto de luz, con su halo */
.beacon-core{
  grid-area:1/1;
  width:11px; height:11px;
  border-radius:50%;
  background:radial-gradient(circle at 50% 50%,
    #FFFDF6 0%, #FFE9B8 42%, rgba(255,201,120,.55) 62%, rgba(255,190,100,0) 78%);
  box-shadow:
    0 0 12px 4px rgba(255,238,196,.85),
    0 0 38px 14px rgba(255,199,116,.42),
    0 0 84px 34px rgba(255,172,84,.18);
}

/* anillos que se expanden, como una señal */
.beacon-ring{
  grid-area:1/1;
  width:11px; height:11px;
  border-radius:50%;
  border:1.5px solid rgba(255,224,166,.9);
  animation:beacon-pulse 3.6s cubic-bezier(.22,.61,.36,1) infinite;
}
.beacon-ring--2{ animation-delay:1.8s }

@keyframes beacon-pulse{
  0%   { transform:scale(1);   opacity:.85 }
  65%  { opacity:.20 }
  100% { transform:scale(12);  opacity:0 }
}

@media (prefers-reduced-motion:reduce){
  .beacon-ring{ animation:none; opacity:.35 }
}

/* Viñeteado: apenas insinúa el borde. Antes llegaba a .92 de negro y dejaba
   las orillas muertas, así que el mapa parecía no llegar a los bordes. */
.scene::after{
  content:'';
  position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    radial-gradient(135% 105% at 50% 46%,
      rgba(5,8,12,0) 60%, rgba(5,8,12,.14) 82%, rgba(5,8,12,.26) 100%),
    linear-gradient(180deg, rgba(5,8,12,.28) 0%, rgba(5,8,12,.08) 14%, rgba(5,8,12,0) 28%),
    linear-gradient(0deg,  rgba(5,8,12,.34) 0%, rgba(5,8,12,.15) 16%, rgba(5,8,12,0) 46%);
}

/* ------------------------------------------------- atribución de OSM --- */
/* La atribución de OpenStreetMap NO se puede quitar: es una condición de la
   licencia ODbL bajo la que se distribuyen los datos, y su política de uso de
   tiles exige mostrarla de forma clara. Ocultarla es motivo de bloqueo del
   dominio. Lo que sí se puede es integrarla al tono de la escena en vez del
   recuadro blanco por defecto, manteniéndola siempre legible.

   Va con doble clase a propósito: en el <head>, site.css se carga ANTES que
   el CSS de Leaflet, así que con la misma especificidad ganaba Leaflet y el
   recuadro blanco se imponía. */
.leaflet-container .leaflet-control-attribution{
  background:rgba(5,8,12,.68);
  color:rgba(246,244,238,.70);
  font-family:var(--text);
  font-size:10px;
  line-height:1.35;
  padding:2px 7px;
  border-radius:4px 0 0 0;
  -webkit-backdrop-filter:blur(4px);
  backdrop-filter:blur(4px);
}
.leaflet-container .leaflet-control-attribution a{
  color:rgba(246,244,238,.85);
  text-decoration:none;
}
.leaflet-container .leaflet-control-attribution a:hover,
.leaflet-container .leaflet-control-attribution a:focus-visible{ text-decoration:underline }

/* -------------------------------------------------------------- slogans --- */

.slogans{position:absolute; inset:0; pointer-events:none; z-index:8}

.slogan{
  position:absolute;
  left:0; top:0;
  /* --x / --y los calcula hero.js con map.latLngToContainerPoint(), así cada
     texto queda anclado a su punto real del plano y se reposiciona al
     redimensionar o al mover el mapa. */
  --x:0px; --y:0px;
  /* --k lo calcula hero.js: 0 sin luz, 1 con el haz encima. --out marca los
     puntos que quedaron fuera de la pantalla. */
  --k:0; --out:0;
  margin:0;
  font-family:var(--display);
  font-weight:800;
  font-size:clamp(15px,1.5vw,23px);
  line-height:1.15;
  letter-spacing:-.01em;
  max-width:clamp(150px,17vw,236px);
  color:var(--cream);
  text-align:left;
  text-wrap:balance;
  will-change:opacity,transform;
  /* Sólo existe cuando la luz pasa por su punto. Sin luz, invisible. */
  opacity:calc(var(--k) * (1 - var(--out)));
  text-shadow:
    0 0 calc(var(--k) * 34px) rgba(248,90,78,calc(var(--k) * .50)),
    0 0 calc(var(--k) * 12px) rgba(255,240,230,calc(var(--k) * .55)),
    0 0 calc(var(--k) * 3px)  rgba(255,240,230,calc(var(--k) * .35));
  transform:
    translate3d(var(--x),var(--y),0)
    scale(calc(.955 + .045 * var(--k)));
}
/* El punto del mapa queda en el origen; el texto se abre hacia el interior
   de la pantalla para no salirse ni tapar la marca. */
.slogan[data-side="left"]{transform:
    translate3d(var(--x),var(--y),0)
    translate(14px,-50%)
    scale(calc(.955 + .045 * var(--k)));
  text-align:left;}
.slogan[data-side="right"]{transform:
    translate3d(var(--x),var(--y),0)
    translate(calc(-100% - 14px),-50%)
    scale(calc(.955 + .045 * var(--k)));
  text-align:right;}
/* punto guía: se enciende con el texto */
.slogan[data-side="right"]::before{left:100%}

/* --------------------------------------------------------------- header --- */

.site{
  position:fixed; inset:0 0 auto 0; z-index:30;
  display:flex; align-items:center; justify-content:space-between;
  gap:24px;
  padding:clamp(16px,2.4vw,30px) clamp(18px,4vw,60px);
}
.brand{display:block; line-height:0}
.brand img{
  width:clamp(178px,19vw,268px);
  height:auto;
  display:block;
}
.site-nav a{
  font-weight:500;
  font-size:15px;
  color:var(--mist);
  text-decoration:none;
  padding:9px 16px;
  border-radius:999px;
  border:1px solid rgba(183,203,219,.20);
  background:rgba(4,18,31,.45);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  transition:color .18s ease, border-color .18s ease, background-color .18s ease;
}
.site-nav a:hover,.site-nav a:focus-visible{
  color:var(--cream);
  border-color:rgba(183,203,219,.42);
  background:rgba(4,18,31,.72);
}

/* ----------------------------------------------------------------- hero --- */

.hero{
  position:relative; z-index:20;
  min-height:100svh;
  display:grid;
  align-content:end;
  padding:0 clamp(18px,4vw,60px) clamp(122px,15vh,168px);
  /* Es una capa de texto transparente que cubre toda la pantalla por encima
     de la escena. Sin esto se come los clics de lo que queda debajo, como el
     enlace de la atribución de OpenStreetMap. */
  pointer-events:none;
}
.hero-copy{max-width:min(760px,64ch)}

.kicker{
  margin:0 0 12px;
  font-family:var(--display);
  font-weight:800;
  font-size:clamp(13px,1.05vw,16px);
  letter-spacing:.14em;
  text-transform:uppercase;
  /* Azul claro de la paleta (--mist), el mismo de la bajada. El azul Faro
     (#03416C) NO sirve acá: es un navy oscuro, pensado para fondos claros —
     como texto sobre el mapa nocturno mide 1,2:1, o sea invisible. */
  color:var(--mist);
}

/* El haz cruza por detrás del titular: el texto se protege solo. */
.hero h1,.hero .sub,.kicker{
  text-shadow:0 2px 20px rgba(10,10,12,.80), 0 1px 3px rgba(10,10,12,.65);
}

.hero h1{
  margin:0;
  font-family:var(--display);
  font-weight:900;
  font-size:clamp(34px,5.1vw,68px);
  line-height:1.02;
  letter-spacing:-.026em;
  /* Coral de marca. Es texto grande (34-68px, en negrita), así que le basta
     el mínimo de 3:1 para texto grande — medido 3,29:1 con el fondo ya
     aclarado. Si se aclara más el mapa, este color deja de funcionar. */
  color:var(--coral);
}
.hero .sub{
  margin:20px 0 0;
  max-width:56ch;
  font-size:clamp(15px,1.25vw,19px);
  line-height:1.55;
  color:var(--mist); /* 11,8:1 sobre el fondo */
}

/* ------------------------------------------------------- botones flotantes - */

.dock{
  position:fixed; z-index:40;
  left:50%;
  bottom:calc(18px + env(safe-area-inset-bottom,0px));
  transform:translateX(-50%);
  display:flex; gap:10px;
  padding:9px;
  border-radius:999px;
  background:rgba(4,18,31,.60);
  border:1px solid rgba(183,203,219,.16);
  box-shadow:0 20px 55px rgba(0,0,0,.58), inset 0 1px 0 rgba(255,255,255,.05);
  backdrop-filter:blur(16px) saturate(1.35);
  -webkit-backdrop-filter:blur(16px) saturate(1.35);
}

.btn{
  display:inline-flex; align-items:center; gap:9px;
  padding:13px 22px;
  border-radius:999px;
  font-family:var(--display);
  font-weight:800;
  font-size:16px;
  line-height:1;
  text-decoration:none;
  white-space:nowrap;
  transition:transform .16s cubic-bezier(.2,.7,.2,1), box-shadow .16s ease, background-color .16s ease;
}
.btn svg{width:19px; height:19px; flex:none}
.btn:active{transform:translateY(1px) scale(.985)}

/* Coral Alerta con tinta: 4,66:1 (AA). Blanco sobre coral daría 3,2:1. */
.btn-coral{
  background:var(--coral);
  color:var(--ink);
  box-shadow:0 10px 26px rgba(248,90,78,.34);
}
.btn-coral:hover,.btn-coral:focus-visible{
  background:#ff6b5f;
  box-shadow:0 14px 34px rgba(248,90,78,.48);
}

.btn-wa{
  background:var(--green-btn);
  color:#FFFFFF; /* 5,92:1 */
  box-shadow:0 10px 26px rgba(23,114,75,.34);
}
.btn-wa:hover,.btn-wa:focus-visible{
  background:#1b8b5c;
  box-shadow:0 14px 34px rgba(23,114,75,.50);
}

:focus-visible{outline:2px solid var(--mist); outline-offset:3px; border-radius:6px}
.dock :focus-visible{outline-color:var(--cream)}

/* ------------------------------------------------------------ responsive --- */

@media (max-width:760px){
  :root{
    --anchor-y:30%;
    --beacon-w:clamp(44px,11vw,56px);
  }
  .site-nav{display:none}
  .hero{padding-bottom:clamp(104px,17vh,132px)}
  .hero .sub{font-size:15px; margin-top:14px}
  .btn{padding:12px 18px; font-size:15px}
  .dock{gap:8px; padding:7px}
  /* Los slogans van en dos columnas al borde. Si el texto es más ancho que
     esto, la columna izquierda y la derecha se tocan. */
  .slogan{max-width:132px; font-size:14px}
}

@media (max-width:420px){
  .slogan{max-width:118px; font-size:13px}
}

@media (max-height:560px) and (orientation:landscape){
  :root{--anchor-y:38%}
  .hero h1{font-size:clamp(28px,5vw,44px)}
  .hero .sub{display:none}
}

/* Movimiento reducido: escena fija, sin barrido. */
@media (prefers-reduced-motion:reduce){
  .btn{transition:none}
}
