/*
   Abraham Network — hoja de marca.
   Sistema visual: gama azul (mono), glassmorphism, degradados fríos y
   utilidades de movimiento. Complementa a Tailwind (config en base.html).

   Tipografías corporativas: son propietarias y NO se incluyen en el repo.
   Los sustitutos abiertos activos (Libre Franklin / Saira) se declaran en
   fonts.css. Para usar las fuentes de marca cuando dispongas de los
   archivos .woff2, colócalos en static/fonts/ y añade sus @font-face en
   fonts.css (no aquí). Plantilla de referencia — reemplaza NOMBRE-ARCHIVO
   por el fichero real antes de reactivar la regla:

     @font-face {
       font-family: "Franklin Gothic Heavy";   NOMBRE-ARCHIVO: FranklinGothic-Heavy.woff2   peso 900
       font-family: "Square721 BT";             NOMBRE-ARCHIVO: Square721-BoldExtended.woff2  peso 700
       font-family: "Segoe UI";                 NOMBRE-ARCHIVO: SegoeUI.woff2                 peso 400
     }

   Nota: el pipeline de estáticos con manifiesto (producción) analiza TODO
   el CSS —incluidos los comentarios— en busca de url(); por eso aquí no se
   deja ningún url() apuntando a ficheros ausentes. Declara el src real solo
   cuando el .woff2 exista en static/fonts/.
*/

:root {
  --brand: #0D6EFD;
  --brand-600: #0B57CC;
  --brand-700: #084299;
  --brand-900: #031A3D;
  --accent: #EC73FC;   /* Magenta/Pink de marca (contraste dinámico) */
  --indigo2: #3D5AFE;
  --ink: #0B1220;
}

/* Square 721 es una grotesca cuadrada/extendida; un leve tracking aproxima
   ese aire con el sustituto Saira. */
.font-display { letter-spacing: 0.012em; }
.font-heading { letter-spacing: -0.015em; }

/* ── Logo SVG inline (hereda color vía currentColor) ──────────────────── */
.an-logo { display: block; height: auto; }
.an-logo--horizontal { width: 100%; }
.an-logo--isotype { width: 100%; }

/* ── Degradados de marca (azul → índigo/violeta → magenta) ─────────────── */
.bg-brand-gradient {
  background-image: linear-gradient(120deg, #0D6EFD 0%, #3D5AFE 48%, #EC73FC 100%);
}
.bg-brand-gradient-soft {
  background-image: linear-gradient(120deg, #0B57CC 0%, #5A9CFE 50%, #F0ABFC 100%);
}
.text-brand-gradient {
  background-image: linear-gradient(110deg, #4D9BFF 0%, #8E7DFF 48%, #EC73FC 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* Degradado animado para fondos de héroe / CTA */
.bg-animated-gradient {
  background-image: linear-gradient(120deg, #084299, #0D6EFD, #3D5AFE, #EC73FC, #0D6EFD);
  background-size: 300% 300%;
  animation: gradient-x 12s ease infinite;
}
@keyframes gradient-x { 0%,100% { background-position: 0% 50% } 50% { background-position: 100% 50% } }

/* Fondo "mesh" oscuro para secciones inmersivas (héroe, CTA) */
.bg-hero-mesh {
  background-color: #050b1a;
  background-image:
    radial-gradient(60% 80% at 12% 8%, rgba(13,110,253,0.42) 0%, transparent 60%),
    radial-gradient(55% 70% at 88% 18%, rgba(236,115,252,0.22) 0%, transparent 55%),
    radial-gradient(80% 90% at 70% 100%, rgba(61,90,254,0.30) 0%, transparent 60%);
}
.bg-deep { background-color: #070C16; }

/* Patrones sutiles */
.bg-dot-grid {
  background-image: radial-gradient(rgba(13, 110, 253, 0.12) 1px, transparent 1px);
  background-size: 22px 22px;
}
.bg-dot-grid-light {
  background-image: radial-gradient(rgba(255,255,255,0.10) 1px, transparent 1px);
  background-size: 24px 24px;
}
.bg-grid-lines {
  background-image:
    linear-gradient(to right, rgba(13,110,253,0.06) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(13,110,253,0.06) 1px, transparent 1px);
  background-size: 44px 44px;
}

/* ── Glassmorphism ────────────────────────────────────────────────────── */
.glass {
  background: rgba(255, 255, 255, 0.62);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.55);
}
.glass-strong {
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.7);
}
.glass-nav {
  background: rgba(255, 255, 255, 0.72);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
}
.glass-dark {
  background: rgba(13, 22, 42, 0.5);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, 0.10);
}

/* Halo decorativo (blobs) */
.blob { position: absolute; border-radius: 9999px; filter: blur(64px); pointer-events: none; }

/* ── Panel de navegación unificado (barra + menú móvil, despliegue suave) ─
   Barra y menú comparten un solo panel de vidrio. En móvil el panel arranca
   recortado a la altura de la barra (4rem + 1px de borde) y se despliega
   animando max-height; en escritorio no se recorta. */
.nav-panel {
  max-height: calc(4rem + 1px);
  transition: max-height .36s cubic-bezier(.16,1,.3,1);
}
.nav-panel #mobileMenu {
  opacity: 0;
  transition: opacity .2s ease;
}
.nav-panel.is-open #mobileMenu {
  opacity: 1;
}
@media (min-width: 768px) {
  .nav-panel { max-height: none; }
}
@media (prefers-reduced-motion: reduce) {
  .nav-panel { transition: none; }
}

/* ── Aparición al hacer scroll ────────────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .7s cubic-bezier(.22,1,.36,1), transform .7s cubic-bezier(.22,1,.36,1);
  will-change: opacity, transform;
}
.reveal.is-visible { opacity: 1; transform: none; }

/* Brillo de carga (skeleton / shimmer) */
.shimmer { position: relative; overflow: hidden; }
.shimmer::after {
  content: ""; position: absolute; inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.45), transparent);
  animation: shimmer 1.4s infinite;
}
@keyframes shimmer { 100% { transform: translateX(100%); } }

/* ── Logo animado (snake SVGator embebido vía <object>) ────────────────── */
/* El SVG animado parte "sin dibujar" y se traza al cargar. Para garantizar que
   SIEMPRE haya logo visible, se muestra el isotipo estático cuando el usuario
   prefiere movimiento reducido (o si el <object> falla).
   Los dos nodos del logo son CALADOS (transparentes): dejan ver el disco del
   medallón que hay detrás, en lugar de pintarse de blanco. */
.hero-logo-object { display: block; pointer-events: none; }
/* El <object> no deduce su alto del viewBox: fijamos la proporción del logo
   (254.9 × 145.6) para que escale correctamente dentro del medallón. */
.hero-anim, .hero-static { display: block; aspect-ratio: 254.9 / 145.6; }
.hero-static { display: none; }
@media (prefers-reduced-motion: reduce) {
  .hero-anim { display: none !important; }
  .hero-static { display: block !important; }
}

/* ── Coreografía del héroe en móvil ───────────────────────────────────────
   Sólo se activa con html.hero-choreo (la añade un script en <head> únicamente
   en móvil y con movimiento permitido). Clave para el CLS: el héroe reserva su
   tamaño FINAL desde el primer pintado. No se anima ninguna propiedad de layout
   (alto, gap, grid-rows): la coreografía es 100 % transform + opacity, que no
   provocan reflujo, así que la cadena de layout shifts desaparece (CLS ≈ 0).
   El medallón es visible desde el inicio, parte elevado (foco central mientras
   se traza el logo) y baja a su sitio cuando el trazado termina. Sin JS o con
   reduced-motion la clase no se añade y el héroe se ve completo de inmediato. */
@media (max-width: 1023px) {
  /* El texto ocupa su espacio final desde el inicio (no se colapsa): sólo
     animan opacidad y desplazamiento → cero layout shift. */
  html.hero-choreo [data-hero-text] { opacity: 1; transform: none; }
  html.hero-choreo [data-hero-text-inner] {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity .6s ease .05s, transform .6s cubic-bezier(.22,1,.36,1) .05s;
  }
  html.hero-choreo [data-hero].is-revealed [data-hero-text-inner] {
    opacity: 1;
    transform: none;
  }

  /* El medallón parte elevado hasta lo alto del héroe (donde aparecerá el
     titular «Conexión sin fronteras») y baja a translateY(0) al revelarse,
     cuando el logo ya terminó de trazarse. El JS de la coreografía fija
     --medallion-lift al alto exacto del bloque de texto + gap; el -90% es sólo
     el respaldo si el JS no llega a correr. Es transform puro → no cuenta para
     el CLS por mucho que valga el desplazamiento. */
  html.hero-choreo [data-hero-media] {
    transform: translateY(var(--medallion-lift, -90%));
    transition: transform .8s cubic-bezier(.22,1,.36,1);
  }
  html.hero-choreo [data-hero].is-revealed [data-hero-media] {
    transform: none;
  }
}

/* ── Medallón de vidrio (héroe): disco glassmorphism con el logo animado ── */

/* Resplandor ambiental azul → magenta detrás del disco */
.bg-medallion-glow {
  background-image:
    radial-gradient(58% 58% at 30% 28%, rgba(13,110,253,0.55) 0%, transparent 72%),
    radial-gradient(54% 54% at 74% 76%, rgba(236,115,252,0.50) 0%, transparent 72%);
}

/* El disco: vidrio esmerilado claro. Su superficie es lo que se ve a través
   de los nodos calados del logo, por eso se mantiene clara y uniforme. */
.medallion {
  border-radius: 9999px;
  background:
    radial-gradient(125% 125% at 30% 22%,
      rgba(255,255,255,0.95) 0%,
      rgba(255,255,255,0.78) 40%,
      rgba(231,241,255,0.62) 72%,
      rgba(207,227,255,0.50) 100%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.75);
  box-shadow:
    0 40px 90px -32px rgba(8,32,78,0.70),
    inset 0 2px 1px rgba(255,255,255,0.95),
    inset 0 -34px 70px -34px rgba(13,110,253,0.30);
}

/* Aro de marca giratorio (azul → violeta → magenta) recortado a un anillo */
.medallion-rim {
  position: absolute; inset: -10px; border-radius: 9999px;
  background: conic-gradient(from 0deg, #0D6EFD, #5A9CFE, #EC73FC, #8E7DFF, #0D6EFD);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 7px), #000 calc(100% - 6px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 7px), #000 calc(100% - 6px));
  filter: drop-shadow(0 0 14px rgba(13,110,253,0.45));
  animation: spin-slow 22s linear infinite;
}

/* Órbita punteada con dos nodos que giran alrededor del disco */
.medallion-orbit {
  z-index: 1;
  position: absolute; inset: -30px; border-radius: 9999px;
  border: 1px dashed rgba(255,255,255,0.20);
  animation: spin-rev 40s linear infinite;
}
.medallion-node {
  position: absolute; left: 50%; width: 14px; height: 14px;
  border-radius: 9999px; transform: translate(-50%, -50%);
  box-shadow: 0 0 0 5px rgba(255,255,255,0.06), 0 4px 10px rgba(8,32,78,0.45);
}
.medallion-node--brand  { top: 0;    background: #0D6EFD; }
.medallion-node--accent { top: 100%; background: #EC73FC; }

@keyframes spin-slow { to { transform: rotate(360deg); } }
@keyframes spin-rev  { to { transform: rotate(-360deg); } }

/* ── Mapa: Leaflet tematizado (coherente con la gama azul) ── */
.leaflet-container {
  font-family: inherit;
  background: #e8f0fb;
  touch-action: manipulation; /* evita el retraso de ~300ms del navegador al tocar */
}
/* Oculta el banner de atribución de Leaflet (se muestra un crédito propio
   y discreto bajo el mapa en su lugar). */
.leaflet-control-attribution { display: none !important; }

/* Aviso "usa dos dedos / ctrl+scroll" (leaflet-gesture-handling): la
   librería solo anima la ENTRADA (keyframe fijo de 0.8s) y quita la clase
   de golpe al salir, por eso se sentía abrupto. Se reemplaza por una
   transición de opacidad simétrica (entra y sale igual de suave) y más
   corta para que se sienta ágil en vez de pesada. La entrada además espera
   200ms antes de arrancar: un toque simple (para fijar tu ubicación) suelta
   el dedo antes de ese plazo, así que el aviso nunca llega a asomarse; solo
   aparece si de verdad mantienes/arrastras con un dedo. La salida no lleva
   demora, para que desaparezca de inmediato al soltar. */
.leaflet-container::after {
  content: attr(data-gesture-handling-touch-content);
  animation: none !important;
  opacity: 0;
  transition: opacity .2s ease-out;
  text-align: center;
  font-weight: 600;
}
.leaflet-container.leaflet-gesture-handling-scroll-warning::after {
  content: attr(data-gesture-handling-scroll-content);
}
.leaflet-container.leaflet-gesture-handling-touch-warning::after,
.leaflet-container.leaflet-gesture-handling-scroll-warning::after {
  opacity: 1;
  transition: opacity .2s ease-out .2s;
}

/* Controles de zoom: vidrio redondeado de marca */
.leaflet-touch .leaflet-bar,
.leaflet-bar {
  border: none !important;
  box-shadow: 0 10px 30px -12px rgba(8,32,78,0.45) !important;
  border-radius: 14px !important;
  overflow: hidden;
}
.leaflet-bar a {
  background: rgba(255,255,255,0.85) !important;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  color: #0B57CC !important;
  width: 38px !important; height: 38px !important; line-height: 38px !important;
  font-size: 20px !important; font-weight: 700;
  border-bottom: 1px solid rgba(13,110,253,0.12) !important;
  transition: background .15s ease, color .15s ease;
}
.leaflet-bar a:hover { background: #0D6EFD !important; color: #fff !important; }
.leaflet-bar a:first-child { border-top-left-radius: 14px; border-top-right-radius: 14px; }
.leaflet-bar a:last-child { border-bottom-left-radius: 14px; border-bottom-right-radius: 14px; border-bottom: none !important; }

/* Popups: tarjeta de vidrio */
.leaflet-popup-content-wrapper {
  background: rgba(255,255,255,0.92);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.7);
  border-radius: 16px !important;
  box-shadow: 0 22px 50px -20px rgba(8,32,78,0.45) !important;
  color: var(--ink);
}
.leaflet-popup-content { margin: 14px 16px !important; font-size: 13px; }
.leaflet-popup-tip { background: rgba(255,255,255,0.92) !important; }
.leaflet-popup-close-button { color: #64748b !important; }

/* Marcadores de cobertura (divIcon): punto limpio con halo sutil del color
   del servicio. Sin pulso continuo (con decenas de zonas resultaría ruidoso). */
.coverage-pin {
  display: block;
  width: 15px; height: 15px; border-radius: 9999px;
  border: 3px solid #ffffff;
  box-shadow: 0 1px 4px rgba(8, 32, 78, 0.5), 0 3px 10px rgba(8, 32, 78, 0.25);
}
.user-pin > svg { display: block; }

/* Marcador "tu ubicación" (resultado de búsqueda): SÍ pulsa, es el foco. */
.user-pin {
  position: relative;
  width: 22px; height: 22px; border-radius: 9999px;
  background: #0B1220; border: 3px solid #fff;
  box-shadow: 0 0 0 4px rgba(13,110,253,0.35), 0 6px 16px rgba(8,32,78,0.5);
  display: grid; place-items: center; color: #fff;
}
.user-pin::before {
  content: ""; position: absolute; inset: -4px; border-radius: 9999px;
  border: 2px solid #0D6EFD; opacity: .6;
  animation: pulse-ring 2.4s cubic-bezier(.22,1,.36,1) infinite;
}
@keyframes pulse-ring { 0% { transform: scale(.7); opacity:.6 } 70%,100% { transform: scale(2.6); opacity:0 } }

/* ── Selects: chevron propio + panel de opciones tematizado ───────────────
   Sustituye la flecha nativa por una de marca y atenúa la opción
   "placeholder" (value vacío) para diferenciarla de una elección real.
   El panel desplegable del navegador no es 100% estilizable en todas las
   plataformas; se tematiza lo que el motor permite (Firefox / Chromium). */
.an-select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2364748b' stroke-width='2.2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
  background-size: 1.15rem 1.15rem;
  padding-right: 2.75rem;
  cursor: pointer;
}
.an-select:focus {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%230D6EFD' stroke-width='2.2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
/* Opciones: la vacía atenuada, las reales en tinta; la elegida en azul marca. */
.an-select option { color: var(--ink); background: #ffffff; }
.an-select option[value=""] { color: #94a3b8; }
.an-select option:checked { color: var(--brand-700); background: #E7F1FF; }

/* Deshabilitado: superficie atenuada coherente con la marca (un solo estilo
   para "aún no toca" y "cargando"), sin opacidad global que emborrone el texto. */
.an-select:disabled {
  cursor: not-allowed;
  color: #94a3b8;
  background-color: #F1F5F9;
  border-color: #E2E8F0;
}
/* Mientras HTMX trae sus opciones, el propio select "respira". */
.an-select.htmx-request { animation: an-select-loading 1.1s ease-in-out infinite; }
@keyframes an-select-loading { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

/* ── Selector de planes: botón "Limpiar selección" y fundido de resultados ──
   El botón solo existe cuando hay un estado real elegido. Se resuelve con
   :has() sobre la opción marcada: cero JavaScript y siempre en sincronía,
   incluso tras los intercambios de HTMX. */
#clear-selection-btn { display: none; }
#location-card:has(#estado-select option:checked:not([value=""])) #clear-selection-btn {
  display: inline-flex;
  animation: an-fade-in 0.18s ease-out;
}
@keyframes an-fade-in {
  from { opacity: 0; transform: translateY(2px); }
  to   { opacity: 1; transform: none; }
}

/* Los resultados se desvanecen al salir y reaparecen suaves al llegar
   (coordinado con hx-swap="... swap:120ms" en la página de planes). */
#plans-results { opacity: 1; transition: opacity 180ms ease-out; }
#plans-results.htmx-swapping { opacity: 0; transition: opacity 120ms ease-in; }

/* ── FAQ: barrido suave al abrir cada pregunta ────────────────────────────
   Acordeón nativo <details>. Animamos el pseudo-elemento ::details-content
   (altura + opacidad) para un despliegue tipo cortina. content-visibility se
   transiciona con allow-discrete para que el contenido siga visible mientras
   se pliega al cerrar. interpolate-size habilita animar hasta height:auto.
   Sólo se activa sin preferencia de movimiento reducido; donde el navegador no
   soporte ::details-content, la pregunta simplemente abre al instante. */
@media (prefers-reduced-motion: no-preference) {
  .faq-item {
    interpolate-size: allow-keywords;
  }
  .faq-item::details-content {
    block-size: 0;
    overflow: hidden;
    opacity: 0;
    transition:
      block-size 0.35s ease,
      opacity 0.3s ease 0.05s,
      content-visibility 0.35s allow-discrete;
  }
  .faq-item[open]::details-content {
    block-size: auto;
    opacity: 1;
  }
}

/* ── Accesibilidad / pulido ───────────────────────────────────────────── */
:focus-visible { outline: none; }
.text-balance { text-wrap: balance; }

/* Scrollbar discreta (navegadores webkit) */
@media (pointer: fine) {
  ::-webkit-scrollbar { width: 12px; height: 12px; }
  ::-webkit-scrollbar-thumb { background: rgba(13,110,253,0.28); border-radius: 9999px; border: 3px solid #fff; }
  ::-webkit-scrollbar-thumb:hover { background: rgba(13,110,253,0.45); }
}

/* ── Respeta la preferencia de movimiento reducido ────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .user-pin::before, .bg-animated-gradient, .shimmer::after,
  .medallion-rim, .medallion-orbit { animation: none !important; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* HTMX indicators — not bundled in htmx 2.x, must be declared here */
.htmx-indicator { display: none; }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { display: inline-flex; }

/* ── Modo FX ligero (html.lite-fx) — equipos de gama baja ──
   El script de <head> marca <html> con .lite-fx cuando detecta poca RAM /
   pocos núcleos / ahorro de datos / red 2G. Aquí apagamos los efectos de GPU
   más caros y los sustituimos por equivalentes baratos que conservan el aire
   de la marca. En equipos capaces NADA de esto aplica: el aspecto es idéntico. */

/* backdrop-filter (desenfoque de fondo) es de lo más costoso de componer en
   móviles flojos. Se elimina y, a cambio, se sube la opacidad del fondo para
   que el "vidrio" siga leyéndose como superficie esmerilada y no transparente. */
html.lite-fx .glass,
html.lite-fx .glass-strong,
html.lite-fx .glass-nav,
html.lite-fx .glass-dark,
html.lite-fx .medallion {
  -webkit-backdrop-filter: none !important;
          backdrop-filter: none !important;
}
html.lite-fx .glass        { background: rgba(255,255,255,0.90); }
html.lite-fx .glass-strong { background: rgba(255,255,255,0.95); }
html.lite-fx .glass-nav    { background: rgba(255,255,255,0.92); }
html.lite-fx .glass-dark   { background: rgba(13,22,42,0.80); }

/* Los blobs son halos decorativos con blur(64px): se ocultan en gama baja
   (el fondo «mesh» ya aporta color ambiental, así que apenas se nota). */
html.lite-fx .blob { display: none; }

/* Sin bucles de animación infinitos gastando batería/CPU: el degradado y el
   aro/órbita quedan estáticos (se siguen viendo, sólo no se mueven). */
html.lite-fx .bg-animated-gradient,
html.lite-fx .medallion-rim,
html.lite-fx .medallion-orbit,
html.lite-fx .shimmer::after,
html.lite-fx .user-pin::before {
  animation: none !important;
}
