/* ===== MÓDULO: Scroll & Profundidad ===== */
/* =====================================================================
   FX5 — "Scroll & Profundidad"  (aditivo · namespaced fx5-* / #fx-progress)
   Solo transform/opacity/translate/filter -> cero CLS.
   No toca .reveal/[data-count]/[data-stagger]/[data-fill] (los maneja app.js).
   ===================================================================== */

/* (a) Barra de progreso de lectura fija arriba ---------------------- */
#fx-progress{
  position:fixed; top:0; left:0; right:0; height:3px; z-index:200;
  transform:scaleX(0); transform-origin:0 50%;        /* crece sin reflow */
  background:linear-gradient(90deg,#5db8da,#3CA4CD 55%,#2f8fb6);
  box-shadow:0 0 12px rgba(60,164,205,.55);
  will-change:transform; pointer-events:none;
  opacity:0; transition:opacity .4s ease;
}
#fx-progress.fx5-on{opacity:1}

/* (b) Parallax: usamos la propiedad CSS `translate` (independiente de
   `transform`) para NO pisar las animaciones floaty/auroraMove que ya
   viven en .orb/.hero-card/.hero-badge. El JS escribe --fx5-x/--fx5-y. */
.fx5-par{
  translate:var(--fx5-x,0) var(--fx5-y,0);
  will-change:translate;
}

/* (c) Entradas escalonadas para elementos SIN .reveal --------------- */
/* Estado inicial: oculto + leve desplazamiento. Solo si JS está activo. */
.js .fx5-rise{
  opacity:0; transform:translateY(16px);
  transition:opacity .6s var(--ease-out,cubic-bezier(.16,1,.3,1)),
             transform .6s var(--ease-out,cubic-bezier(.16,1,.3,1));
  transition-delay:var(--fx5-d,0ms);
  will-change:opacity,transform;
}
.js .fx5-rise.fx5-in{opacity:1; transform:none}
/* filas de tabla: el slide entra desde la izquierda, muy sutil */
.js tr.fx5-rise{transform:translateX(-12px)}
.js tr.fx5-rise.fx5-in{transform:none}

/* (d) "Section glow": línea + brillo sutil al entrar una .section --- */
.fx5-glow{position:relative}
.fx5-glow::after{
  content:""; position:absolute; left:0; right:0; top:0; height:1px;
  pointer-events:none; z-index:3;
  background:linear-gradient(90deg,transparent,rgba(60,164,205,.55) 50%,transparent);
  transform:scaleX(0); transform-origin:50% 50%; opacity:0;
  transition:transform .9s var(--ease-out,cubic-bezier(.16,1,.3,1)), opacity .9s ease;
  will-change:transform,opacity;
}
.fx5-glow.fx5-lit::after{transform:scaleX(1); opacity:1}
/* halo difuso muy tenue, se desvanece tras entrar (no permanente) */
.fx5-glow::before{
  content:""; position:absolute; inset:0 0 auto 0; height:120px;
  pointer-events:none; z-index:0;
  background:radial-gradient(60% 100% at 50% 0%,rgba(60,164,205,.10),transparent 70%);
  opacity:0; transition:opacity 1.1s ease; will-change:opacity;
}
.fx5-glow.fx5-lit::before{opacity:1}
/* sobre fondos navy el brillo se ve mejor un poco más claro */
.bg-navy.fx5-glow::after,.hero.fx5-glow::after{
  background:linear-gradient(90deg,transparent,rgba(127,208,236,.6) 50%,transparent)}

/* ---- Accesibilidad: reduce -> sin movimiento, todo visible -------- */
@media (prefers-reduced-motion:reduce){
  #fx-progress{display:none!important}
  .js .fx5-rise{opacity:1!important; transform:none!important; transition:none!important}
  .fx5-par{translate:0 0!important}
  .fx5-glow::after,.fx5-glow::before{transition:none!important}
}

/* ===== MÓDULO: Botones & Enlaces (micro-interacciones) ===== */
/* =====================================================================
   FX-BTN · Botones & Enlaces — micro-interacciones premium
   Namespaced (.fxb-*) · aditivo · cero CLS (solo transform/opacity/filter)
   Compone con app.css usando la propiedad CSS 'translate' (independiente
   de 'transform', que app.css ya usa en hover/active del .btn).
   ===================================================================== */

/* (a) MAGNÉTICO — el offset llega por var --fxb-mx/--fxb-my y se aplica
   con 'translate', que se SUMA al 'transform' existente sin pisarlo.
   Solo se activa cuando JS marca .fxb-mag (desktop/no-touch). */
.fxb-mag{
  translate:var(--fxb-mx,0) var(--fxb-my,0);
  transition:translate .35s cubic-bezier(.16,1,.3,1);
  will-change:translate;
}
.fxb-mag.fxb-grab{ transition:translate .08s linear; } /* sigue el cursor en vivo */

/* (c) MICRO-NUDGE del icono del botón al hover (translateX sutil).
   No tocamos width/height -> sin reflow. */
.btn svg{ transition:transform .25s cubic-bezier(.16,1,.3,1); }
.btn:hover svg{ transform:translateX(3px); }
/* botones cuyo icono va a la izquierda del texto: lo movemos al revés
   solo si JS lo etiqueta (1er hijo svg). */
.btn.fxb-ic-left:hover svg{ transform:translateX(-3px); }

/* (b) RIPPLE — onda desde el punto de click. Usa un <span> inyectado
   por JS (.fxb-ripple) para NO chocar con el ::after del .btn-primary. */
.fxb-ripple{
  position:absolute;
  border-radius:50%;
  pointer-events:none;
  background:radial-gradient(circle,rgba(255,255,255,.55),rgba(255,255,255,0) 70%);
  transform:translate(-50%,-50%) scale(0);
  opacity:.7;
  z-index:-1;              /* bajo el contenido (texto/svg quedan encima) */
  mix-blend-mode:screen;   /* se ve elegante sobre degradados y navy */
  animation:fxbRipple .62s cubic-bezier(.22,.61,.36,1) forwards;
}
/* En botones claros (fondo blanco) la onda blanca no se vería: tono marca */
.btn-white .fxb-ripple,.btn-ghost .fxb-ripple,.btn-light .fxb-ripple{
  background:radial-gradient(circle,rgba(60,164,205,.40),rgba(60,164,205,0) 70%);
  mix-blend-mode:normal;
}
@keyframes fxbRipple{
  to{ transform:translate(-50%,-50%) scale(1); opacity:0; }
}

/* (d) SHEEN — barrido de luz en .btn-white al hover (el primary ya tiene
   el suyo en app.css; no tocamos navy/primary). Capa propia .fxb-sheen. */
.fxb-sheen{
  position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  border-radius:inherit;
}
.fxb-sheen::before{
  content:"";position:absolute;top:0;bottom:0;left:0;width:60%;
  background:linear-gradient(110deg,transparent 25%,rgba(60,164,205,.22) 50%,transparent 75%);
  transform:translateX(-180%) skewX(-16deg);
}
.btn-white:hover .fxb-sheen::before{ animation:fxbSheen .9s cubic-bezier(.22,.61,.36,1); }
@keyframes fxbSheen{
  from{ transform:translateX(-180%) skewX(-16deg); }
  to{   transform:translateX(260%) skewX(-16deg); }
}

/* (d) SUBRAYADO animado para enlaces de contenido (.prose a, footer).
   Usamos background-size en un gradiente -> NO altera layout. */
.prose a:not(.btn),
.site-footer a:not(.btn){
  background-image:linear-gradient(currentColor,currentColor);
  background-position:0 100%;
  background-repeat:no-repeat;
  background-size:0% 1.5px;
  transition:background-size .32s cubic-bezier(.16,1,.3,1),color .15s,transform .15s;
  padding-bottom:1px;
}
.prose a:not(.btn):hover,
.prose a:not(.btn):focus-visible,
.site-footer a:not(.btn):hover,
.site-footer a:not(.btn):focus-visible{
  background-size:100% 1.5px;
}
/* el footer ya hace translateX(3px) en app.css: el subrayado lo complementa */

/* (e) PULSO DE FOCO accesible — anillo suave en foco por teclado.
   El :focus-visible global de app.css pinta el outline; aquí añadimos
   un halo animado, namespaced, sin desplazar nada. */
.btn.fxb-focus:focus-visible{ animation:fxbFocus 1.1s ease-out; }
.fxb-focus:focus-visible{ animation:fxbFocus 1.1s ease-out; } /* enlaces/inputs marcados */
@keyframes fxbFocus{
  0%{   box-shadow:0 0 0 0 rgba(60,164,205,.50); }
  70%{  box-shadow:0 0 0 8px rgba(60,164,205,0); }
  100%{ box-shadow:0 0 0 0 rgba(60,164,205,0); }
}

/* ---- Accesibilidad: reduced-motion desactiva todo el movimiento ---- */
@media (prefers-reduced-motion:reduce){
  .fxb-mag{ translate:none!important; transition:none!important; }
  .btn:hover svg,.btn.fxb-ic-left:hover svg{ transform:none!important; }
  .fxb-ripple{ animation:none!important; display:none!important; }
  .fxb-sheen::before,
  .btn-white:hover .fxb-sheen::before{ animation:none!important; }
  .prose a:not(.btn),.site-footer a:not(.btn){ transition:none!important; }
  .btn.fxb-focus:focus-visible,.fxb-focus:focus-visible{ animation:none!important; }
}
/* ---- Touch: nada de magnético (JS no añade .fxb-mag en pointer:coarse) ---- */

/* ===== MÓDULO: Tarjetas Cinematics (tilt 3D + glare) ===== */
/* =====================================================================
   FXC — Tarjetas Cinematics: tilt 3D suave + glare que sigue el cursor
   Namespacing: prefijo .fxc-  ·  NO toca app.css
   Sólo desktop (pointer:fine, lo activa el JS añadiendo .fxc-ready al <html>)
   Cero CLS: sólo transform/opacity. No quita sombras ni el lift :hover existente.
   ===================================================================== */

/* La tarjeta-objetivo: damos contexto 3D y suavizado.
   Variables --fxc-rx/--fxc-ry (rotación) y --fxc-ty (lift) las setea el JS.
   transform-style preserve-3d para que el rotateX/Y se vea con profundidad. */
.fxc-ready .fxc-card{
  --fxc-rx:0deg; --fxc-ry:0deg; --fxc-ty:0px; --fxc-sc:1;
  transform-style:preserve-3d;
  /* La transición sólo se usa al SOLTAR (reset suave). Mientras seguimos el
     cursor, el JS pone .fxc-active y quitamos la transición del transform para
     respuesta inmediata vía rAF. box-shadow conserva su transición original. */
  transition:transform .5s var(--fxc-ease,cubic-bezier(.16,1,.3,1));
  will-change:transform;
}

/* Estado activo (puntero dentro): aplicamos el tilt + lift.
   Reproducimos el lift que ya hacía el :hover (translateY) DENTRO de este mismo
   transform, así no se pierde y no hay pelea de propiedades. */
.fxc-ready .fxc-card.fxc-active{
  transform:perspective(900px)
            translate3d(0,var(--fxc-ty),0)
            rotateX(var(--fxc-rx))
            rotateY(var(--fxc-ry))
            scale(var(--fxc-sc));
  transition:none; /* seguimiento inmediato; el reset lo da la clase base */
}

/* Capa de brillo (glare). Es un <i> real inyectado por JS -> sin colisión con
   los ::before/::after que ya usan .pillar/.kpi. Clip al radio de la tarjeta. */
.fxc-ready .fxc-card{position:relative} /* asegura contención del glare */
.fxc-glare{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  border-radius:inherit; overflow:hidden;
  opacity:0; transition:opacity .45s ease;
  /* el degradado radial se mueve siguiendo --fxc-gx/--fxc-gy (px desde JS) */
  background:radial-gradient(220px circle at var(--fxc-gx,50%) var(--fxc-gy,0%),
            rgba(255,255,255,.28), rgba(255,255,255,.07) 38%, transparent 62%);
  mix-blend-mode:soft-light; /* sutil sobre fondos claros y oscuros */
}
.fxc-ready .fxc-card.fxc-active .fxc-glare{opacity:1}

/* Sobre tarjetas oscuras/cristal (hero-card, navy) el soft-light puede quedar
   plano: subimos un pelín el brillo con un realce screen muy tenue. */
.fxc-glare::after{
  content:""; position:absolute; inset:0; border-radius:inherit;
  background:radial-gradient(160px circle at var(--fxc-gx,50%) var(--fxc-gy,0%),
            rgba(190,233,248,.18), transparent 60%);
  mix-blend-mode:screen; opacity:.6;
}

/* Borde de luz muy fino que también reacciona (premium, no chillón). */
.fxc-ready .fxc-card.fxc-active{
  box-shadow:var(--sh-md,0 18px 44px -16px rgba(14,32,74,.20)),
             0 0 0 1px rgba(60,164,205,.10) inset;
}

/* Touch / coarse / reduced-motion: anulamos TODO el módulo.
   (El JS además no inicializa, pero esto es cinturón y tirantes.) */
@media (prefers-reduced-motion:reduce){
  .fxc-ready .fxc-card,
  .fxc-ready .fxc-card.fxc-active{transform:none!important;transition:none!important}
  .fxc-glare{display:none!important}
}
@media (pointer:coarse),(hover:none){
  .fxc-card{transform:none!important}
  .fxc-glare{display:none!important}
}

/* ===== MÓDULO: Números, Anillos & Progreso ===== */
/* =====================================================================
   FX5 — "Números, Anillos & Progreso"  (aditivo, namespaced .fx5-)
   Solo transform/opacity/filter + width controlado en barras dentro de
   tracks de alto fijo (cero reflow del documento). No toca app.css.
   ===================================================================== */

/* (a) BARRAS NO controladas por app.js (.progress-bar i / .mini-bar i sin data-fill).
   El JS guarda el width objetivo, lo pone a 0 y al entrar en viewport
   lo lleva al objetivo con transición. .mini-bar i no tenía transición:
   se la damos namespaced. .progress-bar i ya transiciona width en app.css. */
.fx5-bar{transition:width 1.1s cubic-bezier(.16,1,.3,1)!important;will-change:width}
.mini-bar i.fx5-bar{transition:width 1s cubic-bezier(.16,1,.3,1)!important}

/* (b) SHEEN: destello que recorre la barra al completarse.
   Se monta sobre el <i> (position:relative) sin alterar su tamaño. */
.fx5-bar{position:relative;overflow:hidden}
.fx5-bar.fx5-sheen::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.55) 50%,transparent 80%);
  transform:translateX(-120%) skewX(-16deg);
  animation:fx5-sheen 1.05s cubic-bezier(.22,.61,.36,1) .15s both}
@keyframes fx5-sheen{from{transform:translateX(-120%) skewX(-16deg)}
  to{transform:translateX(220%) skewX(-16deg)}}

/* (c) ANILLO de progreso por conic-gradient para [data-ring="NN"].
   Tamaño/grosor configurables vía custom props; --fx5-p (0..100) anima el barrido.
   El texto central se inyecta por JS. Sin CLS: el contenedor reserva su caja. */
@property --fx5-p{syntax:'<number>';inherits:false;initial-value:0}
.fx5-ring{
  --fx5-size:120px; --fx5-thick:11px; --fx5-track:rgba(60,164,205,.16);
  --fx5-c1:#5db8da; --fx5-c2:#2f8fb6; --fx5-p:0;
  position:relative;flex:0 0 auto;display:inline-grid;place-items:center;
  width:var(--fx5-size);height:var(--fx5-size);border-radius:50%;
  background:
    conic-gradient(from -90deg,var(--fx5-c1),var(--fx5-c2) calc(var(--fx5-p)*1% ),
      var(--fx5-track) 0);
  transition:--fx5-p 1.2s cubic-bezier(.16,1,.3,1);
  filter:drop-shadow(0 8px 20px rgba(60,164,205,.28))}
/* núcleo blanco que deja ver solo el grosor del aro */
.fx5-ring::before{content:"";position:absolute;inset:var(--fx5-thick);
  border-radius:50%;background:#fff;box-shadow:inset 0 1px 3px rgba(14,32,74,.08)}
/* sobre fondos navy el núcleo se adapta */
.bg-navy .fx5-ring::before,.hero .fx5-ring::before,.page-hero .fx5-ring::before,
.dash-hero .fx5-ring::before{background:#0e1c3d;
  box-shadow:inset 0 1px 3px rgba(0,0,0,.35)}
.fx5-ring .fx5-ring-val{position:relative;z-index:1;
  font-family:var(--font-display,'Plus Jakarta Sans',sans-serif);
  font-weight:800;letter-spacing:-.02em;color:var(--navy,#0e1c3d);line-height:1;
  font-size:calc(var(--fx5-size)*.235)}
.fx5-ring .fx5-ring-val s{font-size:.62em;font-weight:700;text-decoration:none;opacity:.7;margin-left:1px}
.bg-navy .fx5-ring .fx5-ring-val,.hero .fx5-ring .fx5-ring-val,
.page-hero .fx5-ring .fx5-ring-val,.dash-hero .fx5-ring .fx5-ring-val{color:#fff}
/* pequeño "pop" del aro al entrar */
.fx5-ring.fx5-in{animation:fx5-ring-pop .6s cubic-bezier(.22,.61,.36,1) both}
@keyframes fx5-ring-pop{0%{transform:scale(.92)}60%{transform:scale(1.025)}100%{transform:scale(1)}}

/* (d) POP sutil de .stat-card .num y .kpi .num (solo los SIN data-count).
   Solo transform/opacity para no provocar CLS. */
.fx5-pop{animation:fx5-pop .62s cubic-bezier(.16,1,.3,1) both}
@keyframes fx5-pop{
  0%{opacity:0;transform:translateY(8px) scale(.94)}
  55%{opacity:1;transform:translateY(0) scale(1.035)}
  100%{opacity:1;transform:translateY(0) scale(1)}}

/* ---------- Accesibilidad: reduce-motion desactiva movimiento ---------- */
@media (prefers-reduced-motion:reduce){
  .fx5-bar{transition:none!important}
  .fx5-bar.fx5-sheen::after{animation:none;display:none}
  .fx5-ring{transition:none!important}
  .fx5-ring.fx5-in{animation:none}
  .fx5-pop{animation:none}
}

/* ===== MÓDULO: Texto & Hero ===== */
/* (ver campo css)*/

/* ===== MÓDULO: Pulido de UI & Movimiento global ===== */
/* =====================================================================
   FX · Pulido de UI & Movimiento global  (namespace .fxu-)
   Aditivo: NO toca app.css. Solo transform/opacity/filter -> cero CLS.
   Reduced-motion y touch safe. Premium y sutil sobre video/degradados.
   ===================================================================== */

/* ---- (a) Botón "volver arriba" ---------------------------------------- */
/* Lo crea el JS con id #fx-top. Oculto por defecto (no captura clicks). */
#fx-top{
  position:fixed; left:24px; bottom:24px; z-index:60;   /* esquina izquierda: no choca con el chatbot */
  width:46px; height:46px; border:none; border-radius:50%; cursor:pointer;
  display:grid; place-items:center; color:#fff;
  background:linear-gradient(135deg,#46b0d6,#2f8fb6);
  box-shadow:0 14px 30px -10px rgba(60,164,205,.6),0 4px 12px rgba(14,32,74,.25);
  opacity:0; transform:translateY(14px) scale(.85); pointer-events:none;
  transition:opacity .35s cubic-bezier(.16,1,.3,1),transform .35s cubic-bezier(.16,1,.3,1),box-shadow .25s;
}
#fx-top svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .25s var(--ease,cubic-bezier(.22,.61,.36,1))}
#fx-top.fxu-show{opacity:1;transform:none;pointer-events:auto}
#fx-top:hover{transform:translateY(-3px);box-shadow:0 20px 38px -12px rgba(60,164,205,.75),0 6px 16px rgba(14,32,74,.3)}
#fx-top:hover svg{transform:translateY(-2px)}
#fx-top:active{transform:translateY(0) scale(.94)}
/* En móviles muy estrechos, lo subimos un poco para no chocar con el launcher */
@media (max-width:480px){#fx-top{left:16px;bottom:16px;width:42px;height:42px}}

/* ---- (b) Auto-hide del header al bajar -------------------------------- */
/* Complementa el sticky existente: solo traslada en Y; respeta .scrolled. */
.site-header{transition:transform .4s cubic-bezier(.16,1,.3,1),background .3s,border-color .3s,box-shadow .3s,backdrop-filter .3s}
.site-header.fxu-nav-hidden{transform:translateY(-100%)}
/* Nunca esconder mientras el menú móvil está abierto */
.site-header.menu-open.fxu-nav-hidden{transform:none}

/* ---- (c) Idle-bob + pulso de atención del chat launcher --------------- */
/* Usamos un wrapper de transform propio para NO pisar el :hover/scale del .cl-btn. */
.fxu-bob{animation:fxuBob 4.6s ease-in-out infinite}
@keyframes fxuBob{0%,92%,100%{transform:translateY(0)}96%{transform:translateY(-5px)}}
/* Halo de atención: anillo extra que late de vez en cuando (capa propia ::before del wrapper) */
.fxu-bob::before{
  content:""; position:absolute; inset:0; border-radius:50%; pointer-events:none; z-index:-1;
  box-shadow:0 0 0 0 rgba(60,164,205,.5); opacity:0;
}
.fxu-bob.fxu-attn::before{animation:fxuAttn 1.5s ease-out 1}
@keyframes fxuAttn{
  0%{opacity:.9;box-shadow:0 0 0 0 rgba(60,164,205,.5)}
  100%{opacity:0;box-shadow:0 0 0 26px rgba(60,164,205,0)}
}
/* Ping numérico: micro "wiggle" al disparar la atención */
.fxu-bob.fxu-attn .cl-ping{animation:fxuWiggle .6s ease}
@keyframes fxuWiggle{0%,100%{transform:rotate(0)}25%{transform:rotate(-14deg)}60%{transform:rotate(11deg)}}

/* ---- (d) Blur-up / scale-in de imágenes y hero-card ------------------- */
/* IMÁGENES: estado inicial difuminado; al cargar/entrar -> nítido. */
.fxu-img{filter:blur(14px);opacity:0;transform:scale(1.04);
  transition:filter .8s cubic-bezier(.16,1,.3,1),opacity .8s cubic-bezier(.16,1,.3,1),transform .9s cubic-bezier(.16,1,.3,1);
  will-change:filter,opacity,transform}
.fxu-img.fxu-in{filter:blur(0);opacity:1;transform:none}
/* HERO-CARD: NO tocamos su transform (tiene animation:floaty). Solo filter+opacity. */
.fxu-card{opacity:0;filter:blur(10px) saturate(.85);
  transition:opacity .9s cubic-bezier(.16,1,.3,1),filter .9s cubic-bezier(.16,1,.3,1)}
.fxu-card.fxu-in{opacity:1;filter:none}

/* ---- (e) Aparición del menú móvil + morph del toggle a "X" ------------- */
/* Stagger de items: solo cuando el header está en menu-open. Solo opacity/transform. */
@media (max-width:920px){
  .site-header.menu-open .nav-links > a{
    opacity:0; transform:translateY(-8px);
    animation:fxuItemIn .42s cubic-bezier(.16,1,.3,1) forwards;
    animation-delay:var(--fxu-d,0ms);
  }
}
@keyframes fxuItemIn{to{opacity:1;transform:none}}
/* Morph hamburguesa -> X: animamos las 3 líneas del <svg> de icon('menu').
   icon('menu') = 3 <line> horizontales. Las transformamos sin tocar el markup. */
.nav-toggle svg{overflow:visible}
.nav-toggle svg line{transition:transform .32s cubic-bezier(.22,.61,.36,1),opacity .2s;transform-origin:center}
.site-header.menu-open .nav-toggle svg line:nth-of-type(1){transform:translateY(6px) rotate(45deg)}
.site-header.menu-open .nav-toggle svg line:nth-of-type(2){opacity:0;transform:scaleX(.2)}
.site-header.menu-open .nav-toggle svg line:nth-of-type(3){transform:translateY(-6px) rotate(-45deg)}

/* ---- (f) Glow que sigue el cursor en zonas oscuras (desktop only) ------ */
/* Capa propia ::after, pointer-events:none. Posición vía --fxu-x/--fxu-y. */
.fxu-glow{position:relative}
.fxu-glow::after{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  border-radius:inherit; opacity:0; transition:opacity .5s ease;
  background:radial-gradient(360px 360px at var(--fxu-x,50%) var(--fxu-y,50%),
            rgba(127,208,236,.16),transparent 62%);
  -webkit-mask-image:none;
}
.fxu-glow.fxu-glow-on::after{opacity:1}
/* El glow no debe tapar el contenido: el contenido del hero ya va en z-index:2 */
.hero.fxu-glow > .container{position:relative;z-index:2}

/* ---- Accesibilidad: reduced-motion desactiva movimiento --------------- */
@media (prefers-reduced-motion:reduce){
  #fx-top{transition:opacity .2s ease}
  #fx-top.fxu-show{transform:none}
  #fx-top:hover{transform:none}
  .site-header.fxu-nav-hidden{transform:none}      /* no auto-hide */
  .fxu-bob{animation:none}
  .fxu-bob.fxu-attn::before{animation:none}
  .fxu-bob.fxu-attn .cl-ping{animation:none}
  .fxu-img{filter:none;opacity:1;transform:none;transition:opacity .3s ease}
  .fxu-card{filter:none;opacity:1;transition:opacity .3s ease}
  .site-header.menu-open .nav-links > a{animation:none;opacity:1;transform:none}
  .nav-toggle svg line{transition:none}
  .fxu-glow::after{display:none}
}