/* ForeverHumans Toolkit — fx.css
 * Styles for the shared FX engine (js/fx.js). Decoration only:
 * glow, sweep, shine, reveals, tilt easing and the touch pulse.
 * Everything here is driven by the palette vars fx.js sets inline
 * (--fx-accent / --fx-accent2 / --fx-base); the :root values below
 * are just the pre-JS defaults. Content is fully visible with no JS,
 * no canvas, and no motion — reveals only hide under html.fx-motion,
 * which fx.js adds solely when motion is allowed. */

:root{
  --fx-accent:#39ff14;
  --fx-accent2:#ff2ea6;
  --fx-base:#0a0a0f;
}

/* ---------- FX canvases (created by fx.js) ---------- */
.fh-fx-bg{
  position:fixed;inset:0;width:100%;height:100%;
  z-index:0;pointer-events:none;
}
.fh-fx-burst{
  position:fixed;inset:0;width:100%;height:100%;
  z-index:90;pointer-events:none;
}

/* Standalone link page: the backdrop canvas paints the theme base,
   so the rendered page itself stays transparent over it. Direct
   body child only — an embedded preview keeps its own background. */
html.fx-on body > .fh-linkpage{background:transparent}

/* ---------- Headline glow (.fx-glow) ---------- */
.fx-glow{animation:fx-titlepulse 3.8s ease-in-out infinite}
@keyframes fx-titlepulse{
  0%,100%{
    text-shadow:0 0 22px rgba(57,255,20,.30),0 0 60px rgba(57,255,20,.12);
    text-shadow:0 0 22px color-mix(in srgb, var(--fx-accent) 30%, transparent),
                 0 0 60px color-mix(in srgb, var(--fx-accent) 12%, transparent);
  }
  50%{
    text-shadow:0 0 42px rgba(57,255,20,.55),0 0 95px rgba(57,255,20,.24);
    text-shadow:0 0 42px color-mix(in srgb, var(--fx-accent) 55%, transparent),
                 0 0 95px color-mix(in srgb, var(--fx-accent) 24%, transparent);
  }
}

/* ---------- Light sweep (.fx-sweep) ---------- */
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .fx-sweep{
    background:linear-gradient(100deg, var(--fx-accent) 30%, #ffffff 50%, var(--fx-accent) 70%);
    background-size:220% 100%;
    -webkit-background-clip:text;background-clip:text;
    -webkit-text-fill-color:transparent;color:transparent;
    animation:fx-sweep 3.4s linear infinite;
  }
}
@keyframes fx-sweep{from{background-position:180% 0}to{background-position:-80% 0}}

/* ---------- Button shine ---------- */
.btn, .btn-primary, .download-btn, .download-all-btn, .fh-merch-btn, .preset-btn{
  position:relative;overflow:hidden;
}
.btn::after, .btn-primary::after, .download-btn::after,
.download-all-btn::after, .fh-merch-btn::after, .preset-btn::after{
  content:"";position:absolute;top:0;left:0;width:55%;height:100%;pointer-events:none;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.45),transparent);
  transform:translateX(-190%) skewX(-20deg);transition:transform .55s ease;
}
@media (hover:hover){
  .btn:hover::after, .btn-primary:hover::after, .download-btn:hover::after,
  .download-all-btn:hover::after, .fh-merch-btn:hover::after, .preset-btn:hover::after{
    transform:translateX(320%) skewX(-20deg);
  }
}

/* ---------- Scroll reveals ----------
   Hidden ONLY after fx.js opts in via html.fx-motion (motion
   allowed + IntersectionObserver present). */
html.fx-motion .fx-reveal{
  opacity:0;transform:translateY(30px);
  transition:opacity .55s ease,transform .6s cubic-bezier(.22,1.25,.36,1);
}
html.fx-motion .fx-reveal.fx-in{opacity:1;transform:none}

/* ---------- Pointer tilt state (fx.js sets the transform) ---------- */
.tilting{
  transition:transform .15s ease-out,box-shadow .25s ease;
  will-change:transform;
  box-shadow:0 0 38px rgba(57,255,20,.5);
  box-shadow:0 0 38px color-mix(in srgb, var(--fx-accent) 50%, transparent);
}

/* ---------- Touch devices: a slow glow pulse instead of tilt ---------- */
@media (hover:none){
  .demo-card, .panel-card, .scene, .fh-channel{animation:fx-pulse 3.6s ease-in-out infinite}
}
@keyframes fx-pulse{
  0%,100%{
    box-shadow:0 0 8px rgba(57,255,20,.14);
    box-shadow:0 0 8px color-mix(in srgb, var(--fx-accent) 14%, transparent);
  }
  50%{
    box-shadow:0 0 24px rgba(57,255,20,.32);
    box-shadow:0 0 24px color-mix(in srgb, var(--fx-accent) 32%, transparent);
  }
}

/* ---------- Kill switches ----------
   fx.js never arms motion in these states; this is the CSS belt to
   its suspenders, so even a stray class can't animate. */
html.fx-off .fx-glow, html.fx-off .fx-sweep{animation:none}
html.fx-off .demo-card, html.fx-off .panel-card,
html.fx-off .scene, html.fx-off .fh-channel{animation:none}
html.fx-off .btn::after, html.fx-off .btn-primary::after,
html.fx-off .download-btn::after, html.fx-off .download-all-btn::after,
html.fx-off .fh-merch-btn::after, html.fx-off .preset-btn::after{display:none}
html.fx-off .fx-reveal{opacity:1;transform:none;transition:none}

@media (prefers-reduced-motion: reduce){
  .fx-glow, .fx-sweep{animation:none}
  .demo-card, .panel-card, .scene, .fh-channel{animation:none}
  .btn::after, .btn-primary::after, .download-btn::after,
  .download-all-btn::after, .fh-merch-btn::after, .preset-btn::after{display:none}
  html.fx-motion .fx-reveal{opacity:1;transform:none;transition:none}
}
