/**
 * ============================================================
 *  L-LEDS — FASE 5: GLOBAL LOADER + SPA TRANSITIONS (CSS)
 *  Archivo : ll-router.css
 *  Dep.    : ll-tokens.css rev.3
 *
 *  SECCIONES:
 *   §1  Global Loader — capa de transición de página
 *   §2  Barra de progreso LED (top loader, estilo NProgress)
 *   §3  Animaciones del loader (línea de luz + pulso)
 *   §4  Revelado de contenido al cargar (page reveal)
 *   §5  Micro-estado del link interceptado
 *   §6  Reducción de movimiento (prefers-reduced-motion)
 * ============================================================
 */


/* ═══════════════════════════════════════════════════════════
   §1 — GLOBAL LOADER (capa completa sobre el viewport)
   ═══════════════════════════════════════════════════════════ */

#ll-global-loader {
  position         : fixed;
  inset            : 0;                      /* top 0 right 0 bottom 0 left 0 */
  z-index          : var(--ll-z-loader);     /* 9999 — por encima de todo */

  /* Fondo: --ll-color-bg-dark = #050A00 Negro Ónix */
  background       : var(--ll-color-bg-dark);

  /* Estado inicial: invisible, no bloquea eventos */
  opacity          : 0;
  pointer-events   : none;

  /* Transición de entrada (fade-in rápido para no perder el click) */
  transition       : opacity var(--ll-transition-slow);

  /* Centrar el contenido del loader */
  display          : flex;
  flex-direction   : column;
  align-items      : center;
  justify-content  : center;
  gap              : var(--ll-space-6);

  /* Aceleración GPU */
  will-change      : opacity;
  contain          : strict;
}

/* Estado activo (JS añade .is-active) */
#ll-global-loader.is-active {
  opacity          : 1;
  pointer-events   : auto;
}

/* Estado saliente — fade-out más lento para revelar la nueva página */
#ll-global-loader.is-leaving {
  opacity          : 0;
  pointer-events   : none;
  /* Transición de salida usa --ll-transition-page (500ms) */
  transition       : opacity var(--ll-transition-page);
}


/* ── Glow de fondo del loader (logo-glow.webp palpitante) ─── */
/*
 * POSICIÓN: fixed centrado en el viewport, independiente
 *   del flex-flow del loader para que siempre ocupe el centro
 *   óptico de la pantalla negra.
 *
 * ANIMACIÓN ll-glow-breathe:
 *   Ciclo de 3 s ease-in-out que varía opacity (0.4 → 1) y
 *   una escala sutil (0.95 → 1.05) — evoca el palpitar de
 *   una fuente de luz LED encendiéndose.
 *
 * Z-INDEX: 0 — queda detrás de todos los elementos del
 *   loader (.ll-loader__brand, .ll-loader__anim, etc.)
 *   que no definen z-index explícito pero superan al 0
 *   por orden de apilado normal.
 */
.ll-router-bg-glow {
  /* Posicionamiento: centrado en el viewport */
  position         : fixed;
  top              : 50%;
  left             : 50%;
  transform        : translate(-50%, -50%);
  z-index          : 0;            /* detrás del contenido del loader */

  /* Tamaño: generoso para que el resplandor inunde la pantalla */
  width            : min(80vw, 600px);
  height           : auto;
  display          : block;

  /* Decorativo — no interfiere con mouse ni teclado */
  pointer-events   : none;
  user-select      : none;

  /* Animación de respiración infinita */
  animation        : ll-glow-breathe 3s ease-in-out infinite;

  /* GPU hint */
  will-change      : opacity, transform;
}

@keyframes ll-glow-breathe {
  0%, 100% {
    opacity   : 0.40;
    transform : translate(-50%, -50%) scale(0.95);
  }
  50% {
    opacity   : 1;
    transform : translate(-50%, -50%) scale(1.05);
  }
}


/* ── Logo / marca en el centro del loader ─────────────────── */
.ll-loader__brand {
  display          : flex;
  flex-direction   : column;
  align-items      : center;
  gap              : var(--ll-space-3);
}

.ll-loader__logo-mark {
  width            : 48px;
  height           : 48px;
  border-radius    : var(--ll-radius-xl);
  background       : var(--ll-color-primary-muted);
  border           : 1px solid var(--ll-color-border-accent);
  display          : flex;
  align-items      : center;
  justify-content  : center;
}

.ll-loader__logo-mark svg {
  width            : 24px;
  height           : 24px;
  stroke           : var(--ll-color-primary);
  fill             : none;
  stroke-width     : 2;
  stroke-linecap   : round;
}

.ll-loader__brand-name {
  font-family      : var(--ll-font-sans);
  font-size        : var(--ll-text-sm);
  font-weight      : var(--ll-font-semibold);
  color            : var(--ll-color-text-muted);
  letter-spacing   : var(--ll-tracking-widest);
  text-transform   : uppercase;
}


/* ═══════════════════════════════════════════════════════════
   §2 — BARRA DE PROGRESO LED (top loader — estilo NProgress)
   ══════════════════════════════════════════════════════════

   La barra aparece en el borde superior del viewport y simula
   una carga progresiva. La animación está determinada por el
   tiempo esperado de navegación (JS controla el width con
   una CSS custom property --ll-bar-pct).
   ═══════════════════════════════════════════════════════════ */

.ll-loader__bar-track {
  position         : fixed;
  top              : 0;
  left             : 0;
  right            : 0;
  height           : 3px;
  z-index          : calc(var(--ll-z-loader) + 1);
  background       : rgba(125, 218, 0, 0.08);
  overflow         : visible;            /* para el glow */
  pointer-events   : none;
}

.ll-loader__bar {
  position         : absolute;
  top              : 0;
  left             : 0;
  height           : 100%;

  /* El width es controlado por la CSS var que JS actualiza */
  width            : var(--ll-bar-pct, 0%);

  /* Gradiente de la barra: Verde LED → Lima */
  background       : linear-gradient(
    90deg,
    var(--ll-color-primary)   0%,
    var(--ll-color-secondary) 100%
  );

  border-radius    : 0 var(--ll-radius-full) var(--ll-radius-full) 0;
  transition       : width 300ms ease-out;

  /* Glow suave debajo de la barra */
  box-shadow       : 0 0 10px rgba(125, 218, 0, 0.60),
                     0 0 24px rgba(194, 240, 0, 0.20);
}

/* Partícula de luz al final de la barra */
.ll-loader__bar::after {
  content          : '';
  position         : absolute;
  right            : 0;
  top              : 50%;
  transform        : translateY(-50%);
  width            : 80px;
  height           : 3px;
  background       : radial-gradient(
    ellipse at right,
    rgba(194, 240, 0, 0.80) 0%,
    transparent              70%
  );
  animation        : ll-bar-particle 1.2s ease-in-out infinite alternate;
}

@keyframes ll-bar-particle {
  0%   { opacity: 0.6; transform: translateY(-50%) scaleX(0.8); }
  100% { opacity: 1;   transform: translateY(-50%) scaleX(1.2); }
}


/* ═══════════════════════════════════════════════════════════
   §3 — ANIMACIONES DEL CENTRO DEL LOADER
   ══════════════════════════════════════════════════════════

   DISEÑO: "Línea de luz expansiva + punto pulsante"
   Evoca una tira LED encendiéndose — coherente con la marca.
   ═══════════════════════════════════════════════════════════ */

.ll-loader__anim {
  position         : relative;
  display          : flex;
  align-items      : center;
  justify-content  : center;
  width            : 160px;
  height           : 2px;
}

/* Línea base (pista de la tira LED) */
.ll-loader__anim::before {
  content          : '';
  position         : absolute;
  inset            : 0;
  background       : rgba(125, 218, 0, 0.12);
  border-radius    : var(--ll-radius-full);
}

/* Luz viajera de izquierda a derecha */
.ll-loader__beam {
  position         : absolute;
  top              : 0;
  left             : 0;
  width            : 60px;
  height           : 100%;
  border-radius    : var(--ll-radius-full);
  background       : linear-gradient(
    90deg,
    transparent               0%,
    var(--ll-color-primary)   40%,
    var(--ll-color-secondary) 60%,
    transparent               100%
  );
  box-shadow       : 0 0 12px rgba(125, 218, 0, 0.80),
                     0 0 24px rgba(194, 240, 0, 0.40);
  animation        : ll-beam-travel 1.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes ll-beam-travel {
  0%   { left: -60px;  opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { left: 160px;  opacity: 0; }
}

/* Punto central pulsante */
.ll-loader__dot {
  position         : relative;
  width            : 8px;
  height           : 8px;
  border-radius    : var(--ll-radius-full);
  background       : var(--ll-color-primary);
  box-shadow       : var(--ll-shadow-led);
  animation        : ll-dot-pulse 1.4s ease-in-out infinite;
  z-index          : 1;
}

@keyframes ll-dot-pulse {
  0%, 100% {
    transform : scale(1);
    box-shadow: var(--ll-shadow-led);
  }
  50% {
    transform : scale(1.5);
    box-shadow: 0 0 20px rgba(125, 218, 0, 0.60),
                0 0 40px rgba(194, 240, 0, 0.25);
  }
}

/* Anillos de pulso (expansión desde el punto) */
.ll-loader__dot::before,
.ll-loader__dot::after {
  content          : '';
  position         : absolute;
  inset            : 0;
  border-radius    : var(--ll-radius-full);
  border           : 1px solid var(--ll-color-primary);
  animation        : ll-ring-expand 1.8s ease-out infinite;
}

.ll-loader__dot::after {
  animation-delay  : 0.6s;
}

@keyframes ll-ring-expand {
  0% {
    transform : scale(1);
    opacity   : 0.6;
  }
  100% {
    transform : scale(4.5);
    opacity   : 0;
  }
}

/* Texto de estado (debajo de la animación) */
.ll-loader__status {
  font-family      : var(--ll-font-sans);
  font-size        : var(--ll-text-xs);
  font-weight      : var(--ll-font-medium);
  color            : var(--ll-color-text-muted);
  letter-spacing   : var(--ll-tracking-widest);
  text-transform   : uppercase;
  text-align       : center;
  min-height       : 1em;
  transition       : opacity var(--ll-transition-base);
}

/* Animación de puntos suspensivos en el texto de estado */
.ll-loader__status::after {
  content          : '';
  animation        : ll-ellipsis 1.4s steps(4, end) infinite;
}

@keyframes ll-ellipsis {
  0%   { content: '';    }
  25%  { content: '.';   }
  50%  { content: '..';  }
  75%  { content: '...'; }
  100% { content: '';    }
}


/* ═══════════════════════════════════════════════════════════
   §4 — REVELADO DE CONTENIDO (Page Reveal)
   ══════════════════════════════════════════════════════════

   El <body> arranca con class="ll-page-hidden" (añadida por el
   script inline en el <head>). Cuando el loader hace fade-out,
   JS remueve esa clase y el contenido aparece con un suave
   slide-up + fade-in.
   ═══════════════════════════════════════════════════════════ */

/* Estado inicial: contenido invisible */
body.ll-page-hidden {
  overflow         : hidden;   /* evita scroll flash */
}

body.ll-page-hidden .ll-page-content {
  opacity          : 0;
  transform        : translateY(8px);
}

/* Revelado: transición suave */
.ll-page-content {
  transition       : opacity var(--ll-transition-page),
                     transform var(--ll-transition-page);
  opacity          : 1;
  transform        : translateY(0);
}

/* Wrapper principal del contenido de la página */
/* Aplicar a <main>, o al wrapper central de Elementor */
.ll-page-enter {
  animation        : ll-page-enter-anim var(--ll-transition-page) both;
}

@keyframes ll-page-enter-anim {
  from {
    opacity         : 0;
    transform       : translateY(12px);
  }
  to {
    opacity         : 1;
    transform       : translateY(0);
  }
}


/* ═══════════════════════════════════════════════════════════
   §5 — MICRO-ESTADO DEL LINK INTERCEPTADO
   ═══════════════════════════════════════════════════════════ */

/* Efecto ripple en el link que desencadenó la transición */
[data-ll-navigating] {
  position         : relative;
  overflow         : hidden;
}

[data-ll-navigating]::after {
  content          : '';
  position         : absolute;
  inset            : 0;
  background       : var(--ll-color-primary-muted);
  animation        : ll-link-flash 0.3s ease both;
}

@keyframes ll-link-flash {
  0%   { opacity: 0; }
  50%  { opacity: 1; }
  100% { opacity: 0; }
}


/* ═══════════════════════════════════════════════════════════
   §6 — PREFERS-REDUCED-MOTION (accesibilidad)
   ══════════════════════════════════════════════════════════

   Si el usuario prefiere reducción de movimiento (mareo,
   epilepsia), desactivamos todas las animaciones del loader
   y hacemos las transiciones instantáneas.
   ═══════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {

  #ll-global-loader,
  #ll-global-loader.is-active,
  #ll-global-loader.is-leaving {
    transition     : none;
  }

  .ll-router-bg-glow,
  .ll-loader__beam,
  .ll-loader__dot,
  .ll-loader__dot::before,
  .ll-loader__dot::after,
  .ll-loader__bar::after,
  .ll-loader__status::after {
    animation      : none;
  }

  /* Sin animación: el glow queda estático a opacidad media */
  .ll-router-bg-glow {
    opacity        : 0.6;
    transform      : translate(-50%, -50%) scale(1);
  }

  .ll-loader__bar {
    transition     : none;
  }

  .ll-page-content {
    transition     : none;
  }

  .ll-page-enter {
    animation      : none;
  }

}
