/* Bonux fx: animation effects rebuilt in plain CSS/JS from ideas in React Bits
   (https://github.com/DavidHDev/react-bits, MIT + Commons Clause, (c) David Haz).
   Use them on our own pages only: the Commons Clause forbids offering these effects to merchants as a product feature.
   Usage: data-fx="name" (several names allowed, space separated). fx.js adds .fx-js to <html>, so without JS nothing stays hidden. */

.fx-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.fx-w { display: inline-block; white-space: nowrap; }

/* ---------- Text ---------- */

/* With .fx-js set early in <head>, split text stays hidden until fx.js has split it, so it does not flash and vanish */
.fx-js [data-fx~="blur-text"]:not(.fx-split), .fx-js [data-fx~="split-text"]:not(.fx-split) { opacity: 0; }

.fx-js [data-fx~="blur-text"] .fx-u { display: inline-block; opacity: 0; filter: blur(10px); transform: translateY(-.35em); transition: opacity .6s ease, filter .6s ease, transform .6s ease; transition-delay: calc(var(--i) * 70ms); }
.fx-js [data-fx~="blur-text"].fx-in .fx-u { opacity: 1; filter: none; transform: none; }

.fx-js [data-fx~="split-text"] .fx-u { display: inline-block; opacity: 0; transform: translateY(.6em); transition: opacity .5s cubic-bezier(.2, .7, .2, 1), transform .5s cubic-bezier(.2, .7, .2, 1); transition-delay: calc(var(--i) * 30ms); }
.fx-js [data-fx~="split-text"].fx-in .fx-u { opacity: 1; transform: none; }

[data-fx~="shiny-text"] { color: transparent; background: linear-gradient(110deg, var(--fx-base, #8a8f98) 40%, var(--fx-shine, #fff) 50%, var(--fx-base, #8a8f98) 60%) 100% 0 / 250% 100%; -webkit-background-clip: text; background-clip: text; animation: fx-shine 4s linear infinite; }
@keyframes fx-shine { to { background-position: 0 0; } }

[data-fx~="gradient-text"] { color: transparent; background: linear-gradient(90deg, var(--fx-c1, #40ffaa), var(--fx-c2, #4079ff), var(--fx-c3, #c040ff), var(--fx-c1, #40ffaa)) 0 0 / 200% 100%; -webkit-background-clip: text; background-clip: text; animation: fx-pan 8s linear infinite; }
@keyframes fx-pan { to { background-position: 200% 0; } }

[data-fx~="text-type"]::after { content: ""; display: inline-block; width: .08em; height: 1em; margin-left: .08em; vertical-align: -.12em; background: var(--fx-cursor, currentColor); animation: fx-blink 1s steps(1) infinite; }
@keyframes fx-blink { 50% { opacity: 0; } }

/* rotating-text and text-loop: every word sits in the same grid cell, so the width is the longest word and nothing jumps */
.fx-rot { display: inline-grid; overflow: hidden; vertical-align: bottom; padding-bottom: .12em; margin-bottom: -.12em; transition: width .4s cubic-bezier(.2, .7, .2, 1); }
.fx-rot > span { grid-area: 1 / 1; justify-self: start; white-space: nowrap; transition: transform .5s cubic-bezier(.2, .7, .2, 1), opacity .5s ease, filter .5s ease; }
.fx-rot > .fx-enter { transform: translateY(100%); opacity: 0; }
.fx-rot > .fx-leave { transform: translateY(-100%); opacity: 0; }
[data-fx~="text-loop"] .fx-rot > .fx-enter, [data-fx~="text-loop"] .fx-rot > .fx-leave { transform: none; filter: blur(6px); }

[data-fx~="glitch-text"] { position: relative; display: inline-block; }
[data-fx~="glitch-text"]::before, [data-fx~="glitch-text"]::after { content: attr(data-text); position: absolute; top: 0; left: 0; width: 100%; color: inherit; pointer-events: none; }
[data-fx~="glitch-text"]::before { transform: translateX(2px); text-shadow: -2px 0 var(--fx-c1, #ff00c1); animation: fx-glitch 3s infinite linear alternate-reverse; }
[data-fx~="glitch-text"]::after { transform: translateX(-2px); text-shadow: 2px 0 var(--fx-c2, #00e5ff); animation: fx-glitch 2s infinite linear alternate-reverse; }
@keyframes fx-glitch {
    0% { clip-path: inset(20% 0 50% 0); } 20% { clip-path: inset(60% 0 10% 0); } 40% { clip-path: inset(40% 0 40% 0); }
    60% { clip-path: inset(80% 0 5% 0); } 80% { clip-path: inset(10% 0 70% 0); } 100% { clip-path: inset(30% 0 30% 0); }
}

[data-fx~="stroke-text"] { color: transparent; -webkit-text-stroke: var(--fx-stroke-width, 1.5px) var(--fx-stroke, #212529); background: linear-gradient(var(--fx-stroke, #212529), var(--fx-stroke, #212529)) no-repeat 0 0 / 0% 100%; -webkit-background-clip: text; background-clip: text; transition: background-size .8s ease; }
@media (hover: hover) { [data-fx~="stroke-text"]:hover { background-size: 100% 100%; } }

[data-fx~="circular-text"] { position: relative; display: inline-block; width: var(--fx-size, 8rem); height: var(--fx-size, 8rem); animation: fx-spin var(--fx-speed, 20s) linear infinite; }
[data-fx~="circular-text"] .fx-u { position: absolute; left: 50%; top: 0; height: 50%; transform-origin: bottom center; transform: translateX(-50%) rotate(var(--a)); }
@keyframes fx-spin { to { transform: rotate(1turn); } }

[data-fx~="curved-loop"] { display: block; overflow: hidden; }
[data-fx~="curved-loop"] svg { display: block; width: 100%; height: auto; }
[data-fx~="curved-loop"] text { fill: currentColor; font-size: var(--fx-size, 56px); font-weight: 800; white-space: pre; }

/* ---------- Entrances and borders ---------- */

.fx-js [data-fx~="fade"] { opacity: 0; filter: blur(8px); transition: opacity .8s ease var(--fx-delay, 0s), filter .8s ease var(--fx-delay, 0s); }
.fx-js [data-fx~="fade"].fx-in { opacity: 1; filter: none; }

.fx-js [data-fx~="animated-content"] { opacity: 0; transform: translate(var(--fx-x, 0), var(--fx-y, 40px)); transition: opacity .7s ease var(--fx-delay, 0s), transform .8s cubic-bezier(.2, .7, .2, 1) var(--fx-delay, 0s); }
.fx-js [data-fx~="animated-content"].fx-in { opacity: 1; transform: none; }

/* star-border wraps one child that has its own background (a button, a card) */
[data-fx~="star-border"] { position: relative; display: inline-block; padding: 1px 0; border-radius: var(--fx-radius, 1.25rem); overflow: hidden; }
[data-fx~="star-border"] > * { position: relative; z-index: 1; }
[data-fx~="star-border"]::before, [data-fx~="star-border"]::after { content: ""; position: absolute; width: 300%; height: 50%; border-radius: 50%; background: radial-gradient(circle, var(--fx-star, #fff), transparent 10%); opacity: .7; }
[data-fx~="star-border"]::before { top: -10px; left: -250%; animation: fx-star-top 6s linear infinite alternate; }
[data-fx~="star-border"]::after { bottom: -11px; right: -250%; animation: fx-star-bottom 6s linear infinite alternate; }
@keyframes fx-star-top { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } }
@keyframes fx-star-bottom { from { transform: translateX(0); opacity: 1; } to { transform: translateX(-100%); opacity: 0; } }

@property --fx-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
[data-fx~="electric-border"] { position: relative; isolation: isolate; border-radius: var(--fx-radius, 1rem); }
[data-fx~="electric-border"]::before, [data-fx~="electric-border"]::after { content: ""; position: absolute; inset: -2px; padding: 2px; border-radius: inherit; pointer-events: none; background: conic-gradient(from var(--fx-angle), transparent 0 55%, var(--fx-c1, #5227ff) 72%, #fff 80%, var(--fx-c1, #5227ff) 88%, transparent); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: fx-angle 4s linear infinite; }
[data-fx~="electric-border"]::after { filter: blur(8px); opacity: .7; }
@keyframes fx-angle { to { --fx-angle: 1turn; } }

/* logo-loop: fx.js moves the children into .fx-track and repeats them; margin (not gap) keeps -50% exact */
[data-fx~="logo-loop"] { overflow: hidden; -webkit-mask: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); mask: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); }
[data-fx~="logo-loop"] .fx-track { display: flex; align-items: center; width: max-content; animation: fx-marquee 30s linear infinite; }
[data-fx~="logo-loop"] .fx-track > * { flex: none; margin-right: var(--fx-gap, 3rem); }
[data-fx~="logo-loop"]:hover .fx-track { animation-play-state: paused; }
@keyframes fx-marquee { to { transform: translateX(-50%); } }

/* ---------- Backgrounds (on a section: the layer sits behind its content) ---------- */

[data-fx~="aurora"], [data-fx~="soft-aurora"], [data-fx~="grainient"], [data-fx~="dot-grid"], [data-fx~="gradient-waves"] { position: relative; isolation: isolate; overflow: hidden; }

[data-fx~="aurora"]::before, [data-fx~="soft-aurora"]::before { content: ""; position: absolute; inset: -25%; z-index: -1; pointer-events: none; background: radial-gradient(40% 50% at 20% 30%, var(--fx-c1, #3a29ff), transparent 70%), radial-gradient(35% 45% at 80% 20%, var(--fx-c2, #ff94b4), transparent 70%), radial-gradient(45% 50% at 50% 85%, var(--fx-c3, #ff3232), transparent 70%); filter: blur(40px); opacity: .55; animation: fx-aurora 18s ease-in-out infinite alternate; }
[data-fx~="soft-aurora"]::before { filter: blur(70px); opacity: .3; animation-duration: 30s; }
@keyframes fx-aurora { 50% { transform: translate(5%, -4%) rotate(8deg) scale(1.1); } 100% { transform: translate(-5%, 3%) rotate(-6deg); } }

[data-fx~="grainient"] { background: linear-gradient(135deg, var(--fx-c1, #ff9ffc), var(--fx-c2, #5227ff), var(--fx-c3, #b19eef)) 0 0 / 200% 200%; animation: fx-grainient 16s ease infinite alternate; }
[data-fx~="grainient"]::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: var(--fx-grain, .35); mix-blend-mode: overlay; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
@keyframes fx-grainient { to { background-position: 100% 100%; } }

[data-fx~="dot-grid"]::before, [data-fx~="dot-grid"]::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: radial-gradient(var(--fx-dot, rgba(82, 39, 255, .3)) 1.5px, transparent 1.6px) 0 0 / var(--fx-gap, 22px) var(--fx-gap, 22px); }
[data-fx~="dot-grid"]::before { -webkit-mask: radial-gradient(ellipse at center, #000 35%, transparent 80%); mask: radial-gradient(ellipse at center, #000 35%, transparent 80%); }
[data-fx~="dot-grid"]::after { background-image: radial-gradient(var(--fx-dot-active, #5227ff) 2px, transparent 2.1px); -webkit-mask: radial-gradient(160px circle at var(--mx, -999px) var(--my, -999px), #000, transparent); mask: radial-gradient(160px circle at var(--mx, -999px) var(--my, -999px), #000, transparent); }

[data-fx~="gradient-waves"]::before, [data-fx~="gradient-waves"]::after { content: ""; position: absolute; left: 0; bottom: 0; width: 200%; height: var(--fx-wave-height, 40%); z-index: -1; pointer-events: none; background: var(--fx-wave, #6366f1); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 120' preserveAspectRatio='none'%3E%3Cpath d='M0,60 C300,0 300,120 600,60 C900,0 900,120 1200,60 V120 H0Z'/%3E%3C/svg%3E") 0 0 / 50% 100% repeat-x; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 120' preserveAspectRatio='none'%3E%3Cpath d='M0,60 C300,0 300,120 600,60 C900,0 900,120 1200,60 V120 H0Z'/%3E%3C/svg%3E") 0 0 / 50% 100% repeat-x; opacity: .22; animation: fx-wave 14s linear infinite; }
[data-fx~="gradient-waves"]::after { height: calc(var(--fx-wave-height, 40%) * .75); opacity: .15; animation-duration: 22s; animation-direction: reverse; }
@keyframes fx-wave { to { transform: translateX(-50%); } }

/* ---------- Need fx.js ---------- */

[data-fx~="count-up"] { font-variant-numeric: tabular-nums; }

.fx-js [data-fx~="scroll-reveal"] .fx-u { opacity: calc(.12 + .88 * var(--p, 0)); filter: blur(calc((1 - var(--p, 0)) * 4px)); }
.fx-js [data-fx~="scroll-float"] .fx-u { display: inline-block; opacity: var(--p, 0); transform: translateY(calc((1 - var(--p, 0)) * .8em)) scaleY(calc(1 + (1 - var(--p, 0)) * .5)); transform-origin: 50% 0; }

[data-fx~="decrypted-text"] .fx-out, [data-fx~="scrambled-text"] .fx-out { white-space: pre-wrap; }

/* Pointer effects: fx.js only feeds --mx/--my on devices with a real mouse; on a phone these are plain cards */
[data-fx~="spotlight-card"] { position: relative; isolation: isolate; overflow: hidden; }
[data-fx~="spotlight-card"]::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), var(--fx-spot, rgba(82, 39, 255, .18)), transparent 60%); opacity: 0; transition: opacity .4s ease; }
@media (hover: hover) { [data-fx~="spotlight-card"]:hover::before { opacity: 1; } }

[data-fx~="tilted-card"] { transform: perspective(800px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) scale(var(--s, 1)); transition: transform .25s ease; will-change: transform; }

[data-fx~="glare-hover"] { position: relative; overflow: hidden; }
[data-fx~="glare-hover"]::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(-45deg, transparent 60%, var(--fx-glare, rgba(255, 255, 255, .5)) 70%, transparent 80%) 100% 100% / 250% 250% no-repeat; transition: background-position .7s ease; }
@media (hover: hover) { [data-fx~="glare-hover"]:hover::after { background-position: 0 0; } }

[data-fx~="border-glow"] { position: relative; }
[data-fx~="border-glow"]::after { content: ""; position: absolute; inset: 0; padding: 1.5px; border-radius: inherit; pointer-events: none; background: radial-gradient(220px circle at var(--mx, -999px) var(--my, -999px), var(--fx-glow, #5227ff), transparent 70%); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: opacity .3s ease; }
@media (hover: hover) { [data-fx~="border-glow"]:hover::after { opacity: 1; } }

/* magic-bento: a grid whose cards get spotlight-card + border-glow from fx.js; .fx-wide and .fx-tall make big tiles */
[data-fx~="magic-bento"] { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 768px) {
    [data-fx~="magic-bento"] { grid-template-columns: repeat(4, 1fr); }
    [data-fx~="magic-bento"] > .fx-wide { grid-column: span 2; }
    [data-fx~="magic-bento"] > .fx-tall { grid-row: span 2; }
}

/* stepper: an <ol>; vertical on the phone, a row from 768px; fx.js lights the steps one by one when it scrolls into view */
[data-fx~="stepper"] { list-style: none; padding: 0; margin: 0; counter-reset: fx-step; display: grid; gap: 1.5rem; }
[data-fx~="stepper"] > li { position: relative; counter-increment: fx-step; padding-left: 3.5rem; min-height: 2.5rem; }
[data-fx~="stepper"] > li::before { content: counter(fx-step); position: absolute; left: 0; top: 0; width: 2.5rem; height: 2.5rem; border-radius: 50%; display: grid; place-items: center; font-weight: 700; background: var(--fx-step, #e9ecef); color: #495057; transition: background .4s ease, color .4s ease, transform .4s ease; }
[data-fx~="stepper"] > li.fx-done::before { background: var(--fx-step-done, var(--primary, #007bff)); color: #fff; transform: scale(1.08); }
[data-fx~="stepper"] > li:not(:last-child)::after { content: ""; position: absolute; left: 1.2rem; top: 2.85rem; bottom: -1.35rem; width: 2px; background: linear-gradient(var(--fx-step-done, var(--primary, #007bff)), var(--fx-step-done, var(--primary, #007bff))) 0 0 / 100% 0% no-repeat, var(--fx-step-line, #dee2e6); transition: background-size .6s ease; }
[data-fx~="stepper"] > li.fx-done::after { background-size: 100% 100%; }
@media (min-width: 768px) {
    [data-fx~="stepper"] { grid-auto-flow: column; grid-auto-columns: 1fr; }
    [data-fx~="stepper"] > li { padding-left: 0; padding-top: 3.5rem; }
    [data-fx~="stepper"] > li:not(:last-child)::after { left: 3rem; right: -1.25rem; top: 1.2rem; bottom: auto; width: auto; height: 2px; background-size: 0% 100%; }
    [data-fx~="stepper"] > li.fx-done::after { background-size: 100% 100%; }
}

/* ---------- Reduce motion: everything still, final state ---------- */
@media (prefers-reduced-motion: reduce) {
    [data-fx], [data-fx]::before, [data-fx]::after, [data-fx] *, [data-fx] *::before, [data-fx] *::after { animation: none !important; transition: none !important; }
    [data-fx~="glitch-text"]::before, [data-fx~="glitch-text"]::after { display: none; }
}
