/* ═══════════════════════════════════════════════════════════════════════
   paso-fx — effets premium BUILDLESS pour les surfaces publiques Paso.
   ───────────────────────────────────────────────────────────────────────
   Réplique en CSS pur + vanilla JS (paso-fx.js) les patterns des
   bibliothèques modernes (Aceternity, Magic UI) SANS React, SANS Tailwind,
   SANS build : spotlight souris, tilt 3D, border beam, shimmer, bento.
   Décision Julien 2026-08-31 : les outils publics doivent être au niveau
   de ces bibliothèques ; on se construit l'équivalent dans la charte.

   Tokens uniquement (--navy/--amber/--gray-*). Chargé APRÈS paso-ui.css.
   Chaque effet respecte prefers-reduced-motion (bloc en fin de fichier).

   Usage : classes .fx-* + attributs data-fx (initialisés par paso-fx.js).
     <div class="fx-tilt" data-fx="tilt">          tilt 3D au survol
     <section class="fx-spot" data-fx="spot">      spotlight qui suit la souris
     <div class="fx-beam">                         faisceau animé sur le bord
     <span class="fx-shimmer">42 €</span>          reflet qui traverse le texte
   ═══════════════════════════════════════════════════════════════════════ */

/* ─ Spotlight : halo qui suit la souris (variables posées par paso-fx.js) ─ */
.fx-spot{position:relative}
.fx-spot::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;opacity:0;transition:opacity .4s ease;background:radial-gradient(560px 560px at var(--fx-mx,50%) var(--fx-my,50%),color-mix(in srgb,var(--navy-light) 13%,transparent),transparent 62%)}
.fx-spot:hover::after{opacity:1}
.fx-spot--amber::after{background:radial-gradient(480px 480px at var(--fx-mx,50%) var(--fx-my,50%),color-mix(in srgb,var(--amber) 7%,transparent),transparent 60%)}

/* ─ Tilt 3D : perspective posée ici, angles posés par paso-fx.js ─ */
.fx-tilt{transform:perspective(1100px) rotateX(var(--fx-rx,0deg)) rotateY(var(--fx-ry,0deg));transition:transform .18s ease-out;will-change:transform}
.fx-tilt:hover{transition:transform .06s ease-out}

/* ─ Border beam : faisceau lumineux qui parcourt le pourtour ─ */
@property --fx-angle { syntax:"<angle>"; initial-value:0deg; inherits:false; }
.fx-beam{position:relative}
.fx-beam::before{content:"";position:absolute;inset:-1.5px;border-radius:inherit;padding:1.5px;background:conic-gradient(from var(--fx-angle),transparent 0 82%,color-mix(in srgb,var(--amber) 85%,transparent) 92%,transparent 100%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;animation:fxBeam 5.5s linear infinite;pointer-events:none}
.fx-beam--soft::before{background:conic-gradient(from var(--fx-angle),transparent 0 78%,color-mix(in srgb,var(--navy-light) 70%,transparent) 90%,transparent 100%)}
@keyframes fxBeam{to{--fx-angle:360deg}}

/* ─ Shimmer : reflet qui traverse un texte fort (chiffre héro) ─ */
.fx-shimmer{position:relative;background:linear-gradient(100deg,currentColor 42%,color-mix(in srgb,currentColor 55%,var(--white)) 50%,currentColor 58%);background-size:220% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:fxShimmer 3.2s ease-in-out infinite}
@keyframes fxShimmer{0%{background-position:120% 0}100%{background-position:-120% 0}}

/* ─ Bento : grille découpée au filet, cellules nettes (façon app) ─ */
.fx-bento{display:grid;gap:1px;background:var(--gray-200);border:1px solid var(--gray-200);border-radius:16px;overflow:hidden}
.fx-cell{background:var(--white);padding:20px 22px;min-width:0}
.fx-cell-h{display:flex;align-items:center;gap:8px;font:700 10.5px/1 var(--font);letter-spacing:.1em;text-transform:uppercase;color:var(--gray-400);margin:0 0 14px}
.fx-cell-h svg{flex:0 0 auto;color:var(--navy-light)}

/* ─ Dot pattern discret (fond de section sombre) ─ */
.fx-dots{background-image:radial-gradient(rgba(255,255,255,.05) 1px,transparent 1px);background-size:22px 22px}

/* ─ Top-glow : LA lumière d'un hero sombre. Une ligne nette + une lueur courte,
     jamais un gros halo radial flou (jugé cheap, veto Julien 2026-08-31). ─ */
.fx-topglow{position:relative}
.fx-topglow::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent 12%,color-mix(in srgb,var(--amber) 65%,transparent) 50%,transparent 88%);pointer-events:none;z-index:1}
.fx-topglow::after{content:"";position:absolute;top:0;left:0;right:0;height:120px;background:radial-gradient(46% 100% at 50% 0%,color-mix(in srgb,var(--amber) 8%,transparent),transparent 72%);pointer-events:none}

/* ─ Grain : texture fine qui densifie un aplat sombre (opacité volontairement faible) ─ */
.fx-grain{position:relative}
.fx-grain>*{position:relative;z-index:1}
.fx-grain::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.05;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E")}

/* ─ Reveal en cascade au premier rendu ─ */
.fx-in{opacity:0;transform:translateY(12px);animation:fxIn .55s cubic-bezier(.2,.8,.2,1) forwards}
@keyframes fxIn{to{opacity:1;transform:none}}

/* ─ Accessibilité : tout s'éteint proprement ─ */
@media (prefers-reduced-motion: reduce){
  .fx-spot::after{display:none}
  .fx-tilt{transform:none !important;transition:none}
  .fx-beam::before{animation:none;opacity:.5}
  .fx-shimmer{animation:none;background:none;-webkit-text-fill-color:currentColor}
  .fx-in{animation:none;opacity:1;transform:none}
}
