/* ════════════════════════════════════════════════════════════════
   FX TOOLKIT — build-free animated effects (inspired by React Bits)
   Drop in <link rel="stylesheet" href="effects.css"> + <script src="effects.js">
   Activate with data-fx / data-bg attributes. Reduced-motion safe.
   ════════════════════════════════════════════════════════════════ */

:root{
  --fx-accent: #d97706;       /* override to taste */
  --fx-accent-lt: #f59e0b;
  --fx-ease: cubic-bezier(.22,1,.36,1);
  --fx-mx: 50vw; --fx-my: 50vh;   /* live cursor, written by JS */
}

/* ── Scroll reveal ─────────────────────────────────── */
[data-fx~="reveal"]{opacity:0;transform:translateY(28px);filter:blur(4px);transition:opacity .8s var(--fx-ease),transform .8s var(--fx-ease),filter .8s var(--fx-ease)}
[data-fx~="reveal"].fx-in{opacity:1;transform:none;filter:none}
[data-fx-delay="1"]{transition-delay:.08s}[data-fx-delay="2"]{transition-delay:.16s}
[data-fx-delay="3"]{transition-delay:.24s}[data-fx-delay="4"]{transition-delay:.32s}
[data-fx-delay="5"]{transition-delay:.40s}[data-fx-delay="6"]{transition-delay:.48s}

/* ── Split text (per-char rise) ────────────────────── */
[data-fx~="split"] .fx-char{display:inline-block;opacity:0;transform:translateY(110%) rotate(4deg);will-change:transform}
[data-fx~="split"] .fx-word{display:inline-block;overflow:hidden;padding-bottom:.05em}
[data-fx~="split"].fx-in .fx-char{opacity:1;transform:none;transition:opacity .5s var(--fx-ease),transform .6s var(--fx-ease);transition-delay:calc(var(--ci,0)*.03s)}

/* ── Shiny text (sweeping sheen) ───────────────────── */
[data-fx~="shiny"]{
  background:linear-gradient(110deg,currentColor 0%,currentColor 40%,var(--fx-accent-lt) 50%,currentColor 60%,currentColor 100%);
  background-size:220% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:currentColor;
  animation:fx-shine 4s linear infinite}
@keyframes fx-shine{0%{background-position:140% 0}100%{background-position:-40% 0}}

/* ── Gradient text (animated fill) ─────────────────── */
[data-fx~="gradient-text"]{
  background:linear-gradient(90deg,var(--fx-accent),var(--fx-accent-lt),var(--fx-accent));
  background-size:200% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;
  animation:fx-grad 5s linear infinite}
@keyframes fx-grad{0%{background-position:0 0}100%{background-position:200% 0}}

/* ── Magnetic ──────────────────────────────────────── */
[data-fx~="magnetic"]{transition:transform .4s var(--fx-ease)}
[data-fx~="magnetic"].fx-mag-active{transition:none}
.fx-no-pointer [data-fx~="magnetic"]{transform:none!important}

/* ── 3D tilt ───────────────────────────────────────── */
[data-fx~="tilt"]{transform-style:preserve-3d;transition:transform .4s var(--fx-ease)}

/* ── Spotlight card (cursor glow) ──────────────────── */
[data-fx~="spotlight"]{position:relative;overflow:hidden}
[data-fx~="spotlight"]::before{content:'';position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .35s;
  background:radial-gradient(240px circle at var(--sx,50%) var(--sy,50%),rgba(255,255,255,.16),transparent 60%)}
[data-fx~="spotlight"]:hover::before{opacity:1}

/* ── Click ripple ──────────────────────────────────── */
.fx-ripple{position:fixed;z-index:9998;pointer-events:none;width:16px;height:16px;margin:-8px 0 0 -8px;border-radius:50%;border:1px solid var(--fx-accent-lt);opacity:0}

/* ── Marquee ───────────────────────────────────────── */
[data-fx~="marquee"]{display:flex;overflow:hidden;width:100%;mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
[data-fx~="marquee"] .fx-marquee-track{display:flex;flex-shrink:0;gap:0;animation:fx-marquee var(--fx-speed,26s) linear infinite}
[data-fx~="marquee"][data-fx-reverse] .fx-marquee-track{animation-direction:reverse}
@keyframes fx-marquee{to{transform:translateX(-100%)}}

/* ── Backgrounds ───────────────────────────────────── */
[data-bg]{position:relative}
[data-bg]>*{position:relative;z-index:1}
.fx-bg-layer{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}

/* aurora */
.fx-bg-aurora{background:
  radial-gradient(40% 50% at 18% 22%,rgba(99,102,241,.34),transparent 70%),
  radial-gradient(42% 52% at 82% 28%,rgba(168,85,247,.26),transparent 70%),
  radial-gradient(50% 60% at 55% 95%,rgba(129,140,248,.22),transparent 70%);
  filter:blur(22px);animation:fx-aurora 16s ease-in-out infinite alternate}
@keyframes fx-aurora{0%{transform:translate3d(-4%,-2%,0) scale(1.1)}100%{transform:translate3d(5%,3%,0) scale(1.25)}}

/* dot grid */
.fx-bg-dots{background-image:radial-gradient(rgba(255,255,255,.14) 1px,transparent 1px);background-size:22px 22px;animation:fx-dots 24s linear infinite}
@keyframes fx-dots{to{background-position:0 220px}}

/* moving grid */
.fx-bg-grid{background-image:linear-gradient(rgba(255,255,255,.06) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.06) 1px,transparent 1px);background-size:46px 46px;animation:fx-grid 20s linear infinite}
@keyframes fx-grid{to{background-position:0 460px,460px 0}}

/* grain (static, cheap) */
.fx-bg-grain{opacity:.05;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* canvas backgrounds (particles) fill their layer */
.fx-bg-layer canvas{width:100%;height:100%;display:block}

/* ── Custom cursor (opt-in: <body data-fx-cursor>) ─── */
.fx-cursor{position:fixed;top:0;left:0;z-index:9999;pointer-events:none;border-radius:50%;will-change:transform}
.fx-cursor-dot{width:7px;height:7px;margin:-3.5px 0 0 -3.5px;background:var(--fx-accent-lt)}
.fx-cursor-ring{width:38px;height:38px;margin:-19px 0 0 -19px;border:1.5px solid rgba(255,255,255,.5);transition:width .2s,height .2s,background .2s,opacity .2s}
.fx-cursor-ring.fx-hover{width:54px;height:54px;margin:-27px 0 0 -27px;background:rgba(217,119,6,.18);border-color:transparent}
body.fx-cursor-on{cursor:none}
body.fx-cursor-on a,body.fx-cursor-on button{cursor:none}

/* ── Reduced motion: collapse to clean static ──────── */
@media(prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
  [data-fx~="reveal"],[data-fx~="split"] .fx-char{opacity:1!important;transform:none!important;filter:none!important}
  .fx-cursor,.fx-bg-aurora,.fx-bg-dots,.fx-bg-grid{display:none!important}
  body.fx-cursor-on{cursor:auto!important}
}
