/* ============================================================================
   NexaCore — Movimiento
   ----------------------------------------------------------------------------
   Archivo aparte a propósito: no toca nexacore-site.css, así tus ediciones
   quedan intactas y esto se puede revisar (o borrar) por separado.

   TESIS: el sitio habla de sistemas en operación, así que el movimiento dice
   "esto se está encendiendo". Nada decora: cada efecto explica un estado, una
   llegada o una respuesta.

   SEGURIDAD: todo cuelga de `html.nx-motion`, una clase que solo pone el guion
   cuando hay JS y el visitante no pidió menos movimiento. Sin guion, sin clase:
   la página se ve completa y quieta. Nunca se oculta contenido de forma
   permanente.
   ========================================================================== */

/* ============================================================================
   1 · LLEGADA DE PANELES
   Los paneles entran escalonados, como un tablero que arranca. Tope de 6
   escalones para que el último no se haga esperar.
   ========================================================================== */

html.nx-motion [data-enter] {
  opacity: 0;
  transform: translateY(16px);
}

html.nx-motion [data-enter].is-on {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--dur-slow) var(--ease),
    transform var(--dur-slow) var(--ease);
}

/* ============================================================================
   2 · CIFRAS QUE LLEGAN
   Las métricas cuentan desde cero al entrar en pantalla. El valor final es
   siempre el texto original: el guion lo restaura al terminar.
   ========================================================================== */

html.nx-motion [data-count] {
  font-variant-numeric: tabular-nums;
}

/* ============================================================================
   3 · NODO VIVO
   El punto de las insignias "en operación" late despacio. Es el ADN de marca:
   un nodo encendido significa sistema activo.
   ========================================================================== */

html.nx-motion .nx-badge--online i {
  animation: nx-pulse 2.6s var(--ease) infinite;
}

@keyframes nx-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .45; transform: scale(.82); }
}

/* ============================================================================
   4 · REVELADO DE PANTALLAS
   Las capturas se descubren de abajo hacia arriba al entrar. La imagen no se
   desplaza: se recorta, así que el encuadre nunca miente sobre el producto.
   ========================================================================== */

html.nx-motion [data-reveal-shot] {
  clip-path: inset(0 0 100% 0);
}

html.nx-motion [data-reveal-shot].is-on {
  clip-path: inset(0 0 0 0);
  transition: clip-path 720ms var(--ease);
}

/* ============================================================================
   5 · RESPUESTA AL PUNTERO
   Feedback, no adorno: la pieza acusa recibo de que la estás señalando.
   ========================================================================== */

.case-card,
.work,
.tile,
.cell,
.shot {
  transition:
    transform var(--dur-base) var(--ease),
    border-color var(--dur-base) var(--ease),
    box-shadow var(--dur-base) var(--ease);
}

html.nx-motion .case-card:hover { transform: translateY(-3px); }
html.nx-motion .work:hover      { transform: translateY(-3px); }

/* Enlaces de navegación: subrayado que crece desde el centro. */
html.nx-motion .nav-links a {
  position: relative;
}

html.nx-motion .nav-links a::after {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 2px;
  height: 1px;
  background: var(--signal);
  transform: scaleX(0);
  transition: transform var(--dur-base) var(--ease);
}

html.nx-motion .nav-links a:hover::after { transform: scaleX(1); }
html.nx-motion .nav-links a[aria-current="page"]::after { transform: scaleX(1); }

/* Botones: acuse de recibo al presionar, sin rebote. */
html.nx-motion .nx-btn { transition: all var(--dur-fast) var(--ease); }
html.nx-motion .nx-btn:active { transform: translateY(1px); }

/* Filas de servicios y contacto: se levantan, como en la referencia de lista.
   Con transform, no con padding: mover caja obliga al navegador a recalcular
   el trazado en cada cuadro. */
html.nx-motion .plist a,
html.nx-motion .contact-list a {
  display: block;
  transition: color var(--dur-fast) var(--ease), transform var(--dur-base) var(--ease);
}

html.nx-motion .plist a:hover,
html.nx-motion .contact-list a:hover { transform: translateY(-2px); }

/* ============================================================================
   6 · PARADA TOTAL
   Con "reducir movimiento" el guion ni siquiera pone la clase, así que nada de
   lo anterior aplica. Esto es el cinturón por si la preferencia cambia en vivo.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html.nx-motion [data-enter],
  html.nx-motion [data-reveal-shot] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    transition: none !important;
  }

  html.nx-motion .nx-badge--online i { animation: none; }

  html.nx-motion .cell::before,
  html.nx-motion .tile::before,
  html.nx-motion .nav-links a::after { transition: none; }
}


/* ============================================================================
   7 · IMPRESIÓN
   Al imprimir no hay desplazamiento que dispare nada: todo lo marcado tiene
   que estar visible, o la hoja saldría con secciones en blanco.
   ========================================================================== */

@media print {
  html.nx-motion [data-enter],
  html.nx-motion [data-reveal-shot] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    transition: none !important;
  }

  html.nx-motion .nx-badge--online i { animation: none !important; }
}


/* ============================================================================
   8 · LUZ DE SALA  (adaptación del "spotlight card")
   ----------------------------------------------------------------------------
   Una sola fuente de luz sigue al puntero por TODA la página, y cada tarjeta
   se ilumina según lo cerca que pase. No es un brillo por tarjeta: es una
   lámpara en la sala. Eso lo consigue `background-attachment: fixed`, que ancla
   el degradado al viewport en vez de a la caja.

   DECISIÓN: el componente original gira el tono con la posición X (azul ->
   morado). Aquí el color es de marca, así que el puntero mueve la POSICIÓN y la
   INTENSIDAD, no el tono. La luz es siempre --signal.

   Solo con puntero fino: en táctil no hay cursor al que seguir.
   ========================================================================== */

:root { --glow-rgb: 0, 108, 153; }                         /* signal-700 */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --glow-rgb: 0, 186, 255; }   /* signal-400 */
}

:root[data-theme="dark"] { --glow-rgb: 0, 186, 255; }

@media (hover: hover) and (pointer: fine) {

  html.nx-motion.nx-luz .cell,
  html.nx-motion.nx-luz .tile,
  html.nx-motion.nx-luz .work,
  html.nx-motion.nx-luz .shot,
  html.nx-motion.nx-luz .case-shot {
    position: relative;
  }

  /* Baño de superficie: la luz que cae sobre la cara de la tarjeta. */
  html.nx-motion.nx-luz .cell::before,
  html.nx-motion.nx-luz .tile::before,
  html.nx-motion.nx-luz .work::before,
  html.nx-motion.nx-luz .shot::before,
  html.nx-motion.nx-luz .case-shot::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: inherit;
    pointer-events: none;
    background-image: radial-gradient(
      var(--halo, 220px) var(--halo, 220px) at
      calc(var(--px, -9999) * 1px) calc(var(--py, -9999) * 1px),
      rgba(var(--glow-rgb), .10), transparent 68%);
    background-attachment: fixed;
    background-repeat: no-repeat;
  }

  /* Luz de borde: el canto se enciende al pasar la lámpara.
     La máscara deja solo la banda del borde; el interior se recorta. */
  @supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
    html.nx-motion.nx-luz .cell::after,
    html.nx-motion.nx-luz .tile::after,
    html.nx-motion.nx-luz .work::after,
    html.nx-motion.nx-luz .shot::after,
    html.nx-motion.nx-luz .case-shot::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: 3;
      border: 1px solid transparent;
      border-radius: inherit;
      pointer-events: none;
      background-image: radial-gradient(
        calc(var(--halo, 220px) * .7) calc(var(--halo, 220px) * .7) at
        calc(var(--px, -9999) * 1px) calc(var(--py, -9999) * 1px),
        rgba(var(--glow-rgb), .85), transparent 70%);
      background-attachment: fixed;
      background-repeat: no-repeat;
      -webkit-mask: linear-gradient(#fff 0 0) padding-box,
                    linear-gradient(#fff 0 0) border-box;
      -webkit-mask-composite: xor;
              mask: linear-gradient(#fff 0 0) padding-box,
                    linear-gradient(#fff 0 0) border-box;
              mask-composite: exclude;
    }
  }

  /* La celda de imagen ya lleva su propio velo oscuro: ahí la luz estorba. */
  html.nx-motion.nx-luz .cell--media::before,
  html.nx-motion.nx-luz .cell--media::after { display: none; }
}

/* ============================================================================
   9 · HALO DETRÁS DE LA IMAGEN  (adaptación del "hero fashion")
   ----------------------------------------------------------------------------
   Una mancha de color desenfocada asoma por detrás de la captura. Da
   profundidad sin inventar un fondo: la imagen deja de estar pegada al papel.

   Va en los envoltorios SIN recorte (.product, .case-card). En .work el
   contenedor recorta, así que ahí manda la luz de borde de la sección 8.

   El hero queda fuera a propósito: pediste que se quedara sin fondos.
   ========================================================================== */

html.nx-motion .product,
html.nx-motion .case-card {
  position: relative;
  isolation: isolate;              /* la mancha no se escapa de su tarjeta */
}

html.nx-motion .product::before,
html.nx-motion .case-card::before {
  content: "";
  position: absolute;
  z-index: 0;
  width: 20rem;
  height: 20rem;
  border-radius: 50%;
  background: rgba(var(--glow-rgb), .16);
  filter: blur(80px);
  pointer-events: none;
}

/* El halo se pone del lado de la imagen, y cambia de lado cuando el bloque
   se invierte. */
html.nx-motion .product::before      { top: -4rem; right: -3rem; }
html.nx-motion .product--flip::before { top: -4rem; right: auto; left: -3rem; }
html.nx-motion .case-card::before    { top: -3rem; left: 50%; margin-left: -10rem; }

html.nx-motion .product > *,
html.nx-motion .case-card > * {
  position: relative;
  z-index: 1;
}

/* La captura levanta del papel para que el halo se lea como profundidad. */
html.nx-motion .shot,
html.nx-motion .case-shot {
  box-shadow: 0 1.5rem 3rem -1.5rem rgba(var(--glow-rgb), .35);
}

@media (prefers-reduced-motion: reduce) {
  html.nx-motion .product::before,
  html.nx-motion .case-card::before { display: none; }
}
