/* Brand name 2 - modern CSS effects used by this template. Each effect is one class: fx-NAME. */

/* ===== Modern CSS Animations ===== */
/* Bouncing Text - Makes each letter of a short word hop in turn; wrap every letter in a span with --i set to its index. */
.fx-bouncing-text { display: inline-flex; }
.fx-bouncing-text > span {
  display: inline-block;
  animation: fx-bouncing-text-bounce 1.6s ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * .09s);
}
@keyframes fx-bouncing-text-bounce {
  0%, 60%, 100% { transform: translateY(0); }
  25% { transform: translateY(-14px); color: var(--wt-primary); }
  40% { transform: translateY(2px); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-bouncing-text, .fx-bouncing-text::before, .fx-bouncing-text::after, .fx-bouncing-text *, .fx-bouncing-text *::before, .fx-bouncing-text *::after { animation: none !important; transition: none !important; }
}
/* Particle Float - Fills a card or panel with small glowing particles that rise behind its content. */
.fx-particle-float { position: relative; isolation: isolate; overflow: hidden; }
.fx-particle-float::before, .fx-particle-float::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    radial-gradient(circle at 12% 30%, rgba(var(--wt-primary-rgb), .7) 0 2px, transparent 3px),
    radial-gradient(circle at 38% 80%, rgba(var(--wt-accent-rgb), .7) 0 3px, transparent 4px),
    radial-gradient(circle at 62% 45%, rgba(var(--wt-secondary-rgb), .6) 0 2px, transparent 3px),
    radial-gradient(circle at 86% 15%, rgba(var(--wt-primary-rgb), .6) 0 3px, transparent 4px);
  background-size: 160px 160px;
  animation: fx-particle-float-rise 10s linear infinite;
}
.fx-particle-float::after { background-size: 230px 230px; opacity: .6; animation: fx-particle-float-rise-slow 16s linear infinite; }
@keyframes fx-particle-float-rise { to { background-position: 0 -160px; } }
@keyframes fx-particle-float-rise-slow { to { background-position: 0 -230px; } }
@media (prefers-reduced-motion: reduce) {
  .fx-particle-float, .fx-particle-float::before, .fx-particle-float::after, .fx-particle-float *, .fx-particle-float *::before, .fx-particle-float *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Clip-path Effects ===== */
/* Triangle Spin - Cuts an element into a triangle and spins it slowly - great for loaders and decorative badges. */
.fx-triangle-spin {
  -webkit-clip-path: polygon(50% 4%, 96% 88%, 4% 88%); clip-path: polygon(50% 4%, 96% 88%, 4% 88%);
  background: linear-gradient(160deg, var(--wt-primary), var(--wt-accent));
  animation: fx-triangle-spin-spin 6s linear infinite;
}
@keyframes fx-triangle-spin-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .fx-triangle-spin, .fx-triangle-spin::before, .fx-triangle-spin::after, .fx-triangle-spin *, .fx-triangle-spin *::before, .fx-triangle-spin *::after { animation: none !important; transition: none !important; }
}
/* Slide Reveal - Wipes an image or banner in from the left, holds it, then wipes it out to the right. */
.fx-slide-reveal { -webkit-clip-path: inset(0 0 0 0); clip-path: inset(0 0 0 0); animation: fx-slide-reveal-wipe 5s cubic-bezier(.7, 0, .3, 1) infinite; }
@keyframes fx-slide-reveal-wipe {
  0% { -webkit-clip-path: inset(0 100% 0 0); clip-path: inset(0 100% 0 0); }
  25%, 75% { -webkit-clip-path: inset(0 0 0 0); clip-path: inset(0 0 0 0); }
  100% { -webkit-clip-path: inset(0 0 0 100%); clip-path: inset(0 0 0 100%); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-slide-reveal, .fx-slide-reveal::before, .fx-slide-reveal::after, .fx-slide-reveal *, .fx-slide-reveal *::before, .fx-slide-reveal *::after { animation: none !important; transition: none !important; }
}
/* Inset Expand - A rounded inner window that expands to the full image edge when hovered. */
.fx-inset-expand { -webkit-clip-path: inset(12% 12% 12% 12% round 1.5rem); clip-path: inset(12% 12% 12% 12% round 1.5rem); transition: clip-path .6s cubic-bezier(.2, .8, .2, 1); }
.fx-inset-expand:hover, .fx-inset-expand:focus-visible { -webkit-clip-path: inset(0 0 0 0 round 0); clip-path: inset(0 0 0 0 round 0); }
@media (prefers-reduced-motion: reduce) {
  .fx-inset-expand, .fx-inset-expand::before, .fx-inset-expand::after, .fx-inset-expand *, .fx-inset-expand *::before, .fx-inset-expand *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Filter Effects ===== */
/* Glitch Filter - Short bursts of hue, contrast and position jumps make an image look like a corrupted signal. */
.fx-glitch-filter { animation: fx-glitch-filter-glitch 3.5s steps(1) infinite; }
@keyframes fx-glitch-filter-glitch {
  0%, 86%, 100% { filter: none; transform: none; }
  88% { filter: hue-rotate(90deg) saturate(3) contrast(1.6); transform: translate(-4px, 1px); }
  90% { filter: invert(.15) contrast(2); transform: translate(4px, -2px) skewX(6deg); }
  92% { filter: hue-rotate(-70deg) saturate(2); transform: translate(-2px, 0); }
  94% { filter: brightness(1.6); transform: translate(2px, 1px); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-glitch-filter, .fx-glitch-filter::before, .fx-glitch-filter::after, .fx-glitch-filter *, .fx-glitch-filter *::before, .fx-glitch-filter *::after { animation: none !important; transition: none !important; }
}
/* Saturation Boost - Desaturated at rest, vivid on hover - draws attention to the product the visitor is looking at. */
.fx-saturation-boost { filter: saturate(.6); transition: filter .4s ease, transform .4s ease; }
.fx-saturation-boost:hover, .fx-saturation-boost:focus-visible { filter: saturate(1.8); transform: scale(1.03); }
@media (prefers-reduced-motion: reduce) {
  .fx-saturation-boost, .fx-saturation-boost::before, .fx-saturation-boost::after, .fx-saturation-boost *, .fx-saturation-boost *::before, .fx-saturation-boost *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Transform Effects ===== */
/* 3D Card Tilt - Tilts a card in 3D with a moving glare on hover - a pure CSS take on the mouse-follow tilt. */
.fx-3d-card-tilt {
  position: relative; overflow: hidden; transform-style: preserve-3d;
  transform: perspective(900px) rotateX(0deg) rotateY(0deg);
  transition: transform .55s cubic-bezier(.2, .8, .2, 1), box-shadow .55s;
}
.fx-3d-card-tilt::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .45) 48%, transparent 62%);
  transform: translateX(-60%); transition: transform .7s ease, opacity .4s;
}
.fx-3d-card-tilt:hover, .fx-3d-card-tilt:focus-within {
  transform: perspective(900px) rotateX(8deg) rotateY(-12deg) translateY(-4px);
  box-shadow: 18px 22px 40px -18px rgba(var(--wt-primary-rgb), .55);
}
.fx-3d-card-tilt:hover::after, .fx-3d-card-tilt:focus-within::after { opacity: 1; transform: translateX(60%); }
@media (prefers-reduced-motion: reduce) {
  .fx-3d-card-tilt, .fx-3d-card-tilt::before, .fx-3d-card-tilt::after, .fx-3d-card-tilt *, .fx-3d-card-tilt *::before, .fx-3d-card-tilt *::after { animation: none !important; transition: none !important; }
}
/* Perspective Text - Lays a heading back in 3D perspective with depth layers; it stands up straight on hover. */
.fx-perspective-text {
  display: inline-block; transform: perspective(500px) rotateX(28deg); transform-origin: 50% 100%;
  text-shadow: 0 1px 0 rgba(var(--wt-primary-rgb), .6), 0 2px 0 rgba(var(--wt-primary-rgb), .5), 0 3px 0 rgba(var(--wt-primary-rgb), .4), 0 10px 14px rgba(0, 0, 0, .25);
  transition: transform .6s cubic-bezier(.2, .8, .2, 1);
}
.fx-perspective-text:hover { transform: perspective(500px) rotateX(0deg); }
@media (prefers-reduced-motion: reduce) {
  .fx-perspective-text, .fx-perspective-text::before, .fx-perspective-text::after, .fx-perspective-text *, .fx-perspective-text *::before, .fx-perspective-text *::after { animation: none !important; transition: none !important; }
}
/* Translate 3D - Stacked layers separate along the Z axis on hover, like an exploded view of your interface. */
.fx-translate-3d { position: relative; transform-style: preserve-3d; transform: perspective(800px); transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
.fx-translate-3d > * { transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
.fx-translate-3d:hover { transform: perspective(800px) rotateX(48deg) rotateZ(-28deg); }
.fx-translate-3d:hover > :nth-child(1) { transform: translate3d(0, 0, 0); }
.fx-translate-3d:hover > :nth-child(2) { transform: translate3d(0, 0, 30px); }
.fx-translate-3d:hover > :nth-child(3) { transform: translate3d(0, 0, 60px); }
.fx-translate-3d:hover > :nth-child(4) { transform: translate3d(0, 0, 90px); }
@media (prefers-reduced-motion: reduce) {
  .fx-translate-3d, .fx-translate-3d::before, .fx-translate-3d::after, .fx-translate-3d *, .fx-translate-3d *::before, .fx-translate-3d *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Transitions ===== */
/* Morphing Gradient - A gradient button that softly changes to a second gradient and morphs into a pill on hover. */
.fx-morphing-gradient, .btn.fx-morphing-gradient {
  position: relative; isolation: isolate; overflow: hidden; z-index: 0; border: 0;
  color: var(--wt-on-primary, #fff); border-radius: .6rem;
  background: linear-gradient(135deg, var(--wt-primary), var(--wt-secondary));
  transition: border-radius .5s ease, transform .5s ease, box-shadow .5s;
}
.fx-morphing-gradient::before {
  content: ""; position: absolute; inset: 0; z-index: -1; opacity: 0;
  background: linear-gradient(135deg, var(--wt-accent), var(--wt-primary));
  transition: opacity .5s ease;
}
.fx-morphing-gradient:hover, .fx-morphing-gradient:focus-visible, .btn.fx-morphing-gradient:hover, .btn.fx-morphing-gradient:focus-visible {
  color: var(--wt-on-primary, #fff); border-radius: 2rem; transform: translateY(-2px);
  box-shadow: 0 12px 24px -10px rgba(var(--wt-accent-rgb), .7);
}
.fx-morphing-gradient:hover::before, .fx-morphing-gradient:focus-visible::before { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .fx-morphing-gradient, .fx-morphing-gradient::before, .fx-morphing-gradient::after, .fx-morphing-gradient *, .fx-morphing-gradient *::before, .fx-morphing-gradient *::after { animation: none !important; transition: none !important; }
}
/* Magnetic Hover - Fakes a magnetic pull: the element lifts toward the pointer and its icon leans further with an elastic ease. */
.fx-magnetic-hover { transition: transform .45s cubic-bezier(.34, 1.56, .64, 1), box-shadow .45s; }
.fx-magnetic-hover > * { display: inline-block; transition: transform .45s cubic-bezier(.34, 1.56, .64, 1); }
.fx-magnetic-hover:hover, .fx-magnetic-hover:focus-visible { transform: translate(3px, -4px) scale(1.06); box-shadow: -6px 12px 22px -10px rgba(var(--wt-primary-rgb), .6); }
.fx-magnetic-hover:hover > *, .fx-magnetic-hover:focus-visible > * { transform: translate(3px, -2px); }
@media (prefers-reduced-motion: reduce) {
  .fx-magnetic-hover, .fx-magnetic-hover::before, .fx-magnetic-hover::after, .fx-magnetic-hover *, .fx-magnetic-hover *::before, .fx-magnetic-hover *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Gradient Effects ===== */
/* Conic Rotation - A spinning conic gradient behind round content such as avatars, scores or loaders. */
.fx-conic-rotation { position: relative; isolation: isolate; overflow: hidden; border-radius: 50%; padding: 5px; }
.fx-conic-rotation::before {
  content: ""; position: absolute; inset: -30%; z-index: -1;
  background: conic-gradient(var(--wt-primary), var(--wt-accent), var(--wt-secondary), var(--wt-primary));
  animation: fx-conic-rotation-spin 3s linear infinite;
}
.fx-conic-rotation > * { display: block; border-radius: 50%; }
@keyframes fx-conic-rotation-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .fx-conic-rotation, .fx-conic-rotation::before, .fx-conic-rotation::after, .fx-conic-rotation *, .fx-conic-rotation *::before, .fx-conic-rotation *::after { animation: none !important; transition: none !important; }
}
/* Moving Stripes - Animated diagonal stripes for progress bars, sale banners and "in progress" states. */
.fx-moving-stripes {
  background-color: var(--wt-primary);
  background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, .22) 0 12px, transparent 12px 24px);
  background-size: 34px 34px;
  color: var(--wt-on-primary, #fff);
  animation: fx-moving-stripes-move 1s linear infinite;
}
@keyframes fx-moving-stripes-move { to { background-position: 34px 0; } }
@media (prefers-reduced-motion: reduce) {
  .fx-moving-stripes, .fx-moving-stripes::before, .fx-moving-stripes::after, .fx-moving-stripes *, .fx-moving-stripes *::before, .fx-moving-stripes *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern Shadow Effects ===== */
/* Layered Shadows - Five stacked, increasingly soft shadows give cards a realistic elevation that deepens on hover. */
.fx-layered-shadows {
  box-shadow: 0 1px 1px rgba(0, 0, 0, .06), 0 2px 2px rgba(0, 0, 0, .06), 0 4px 4px rgba(0, 0, 0, .06), 0 8px 8px rgba(0, 0, 0, .06), 0 16px 16px rgba(0, 0, 0, .06);
  transition: box-shadow .4s ease, transform .4s ease;
}
.fx-layered-shadows:hover, .fx-layered-shadows:focus-within {
  transform: translateY(-4px);
  box-shadow: 0 2px 2px rgba(0, 0, 0, .07), 0 4px 4px rgba(0, 0, 0, .07), 0 8px 8px rgba(0, 0, 0, .07), 0 16px 16px rgba(0, 0, 0, .07), 0 32px 32px rgba(0, 0, 0, .07);
}
@media (prefers-reduced-motion: reduce) {
  .fx-layered-shadows, .fx-layered-shadows::before, .fx-layered-shadows::after, .fx-layered-shadows *, .fx-layered-shadows *::before, .fx-layered-shadows *::after { animation: none !important; transition: none !important; }
}
/* Outline Glow - A glowing focus ring for inputs, buttons and cards that appears on hover and keyboard focus. */
.fx-outline-glow { outline: 2px solid transparent; outline-offset: 2px; transition: box-shadow .3s ease, border-color .3s ease; }
.fx-outline-glow:hover, .fx-outline-glow:focus, .fx-outline-glow:focus-visible, .fx-outline-glow:focus-within {
  border-color: var(--wt-primary);
  box-shadow: 0 0 0 3px rgba(var(--wt-primary-rgb), .3), 0 0 18px rgba(var(--wt-primary-rgb), .45);
}
@media (prefers-reduced-motion: reduce) {
  .fx-outline-glow, .fx-outline-glow::before, .fx-outline-glow::after, .fx-outline-glow *, .fx-outline-glow *::before, .fx-outline-glow *::after { animation: none !important; transition: none !important; }
}

/* ===== Advanced Animated Backgrounds ===== */
/* Wave/Blob - Soft colour blobs morph in the background while two layers of waves roll along the bottom edge. */
.fx-bg-wave-blob { position: relative; isolation: isolate; overflow: hidden; }
.fx-bg-wave-blob::before, .fx-bg-wave-blob::after { content: ""; position: absolute; pointer-events: none; z-index: -1; }
.fx-bg-wave-blob::before {
  width: 55%; aspect-ratio: 1; top: -25%; left: -12%;
  background: radial-gradient(circle at 50% 50%, rgba(var(--wt-primary-rgb), .32), transparent 68%);
  border-radius: 42% 58% 63% 37% / 41% 44% 56% 59%;
  animation: fx-bg-wave-blob-blob 14s ease-in-out infinite alternate;
}
.fx-bg-wave-blob::after {
  left: 0; right: 0; bottom: 0; height: 60px;
  background:
    radial-gradient(84px 18px at 50% 100%, rgba(var(--wt-primary-rgb), .2) 99%, transparent 101%) 0 100% / 160px 30px repeat-x,
    radial-gradient(118px 24px at 50% 100%, rgba(var(--wt-accent-rgb), .18) 99%, transparent 101%) 0 100% / 220px 40px repeat-x,
    linear-gradient(rgba(var(--wt-primary-rgb), .14), rgba(var(--wt-primary-rgb), .14)) 0 100% / 100% 12px no-repeat;
  animation: fx-bg-wave-blob-wave 9s linear infinite;
}
@keyframes fx-bg-wave-blob-blob {
  0% { transform: translate(0, 0) rotate(0deg); border-radius: 42% 58% 63% 37% / 41% 44% 56% 59%; }
  50% { border-radius: 70% 30% 46% 54% / 30% 39% 61% 70%; }
  100% { transform: translate(110%, 35%) rotate(60deg); border-radius: 30% 70% 70% 30% / 53% 30% 70% 47%; }
}
@keyframes fx-bg-wave-blob-wave { to { background-position: 160px 100%, -220px 100%, 0 100%; } }
@media (prefers-reduced-motion: reduce) {
  .fx-bg-wave-blob, .fx-bg-wave-blob::before, .fx-bg-wave-blob::after, .fx-bg-wave-blob *, .fx-bg-wave-blob *::before, .fx-bg-wave-blob *::after { animation: none !important; transition: none !important; }
}
/* Shapes - Rings, dots, squares and triangles in theme colours float and turn slowly behind the content. */
.fx-bg-shapes { position: relative; isolation: isolate; overflow: hidden; }
.fx-bg-shapes::before, .fx-bg-shapes::after { content: ""; position: absolute; pointer-events: none; z-index: -1; }
.fx-bg-shapes::before, .fx-bg-shapes::after { inset: -10%; background-repeat: no-repeat; }
.fx-bg-shapes::before {
  background-image:
    radial-gradient(circle, transparent 0 38%, rgba(var(--wt-primary-rgb), .35) 40% 50%, transparent 52%),
    radial-gradient(circle, rgba(var(--wt-accent-rgb), .35) 0 48%, transparent 50%),
    conic-gradient(from 150deg at 50% 0, rgba(var(--wt-secondary-rgb), .3) 0 60deg, transparent 0);
  background-size: 90px 90px, 34px 34px, 70px 60px;
  background-position: 12% 22%, 82% 18%, 70% 82%;
  animation: fx-bg-shapes-float 12s ease-in-out infinite alternate;
}
.fx-bg-shapes::after {
  background-image:
    linear-gradient(rgba(var(--wt-secondary-rgb), .22), rgba(var(--wt-secondary-rgb), .22)),
    radial-gradient(circle, transparent 0 40%, rgba(var(--wt-accent-rgb), .3) 42% 52%, transparent 54%),
    radial-gradient(circle, rgba(var(--wt-primary-rgb), .3) 0 48%, transparent 50%);
  background-size: 38px 38px, 60px 60px, 22px 22px;
  background-position: 88% 62%, 22% 80%, 45% 12%;
  animation: fx-bg-shapes-turn 18s ease-in-out infinite alternate;
}
@keyframes fx-bg-shapes-float { to { transform: translate(3%, -5%) rotate(6deg); } }
@keyframes fx-bg-shapes-turn { to { transform: translate(-4%, 4%) rotate(-8deg); } }
@media (prefers-reduced-motion: reduce) {
  .fx-bg-shapes, .fx-bg-shapes::before, .fx-bg-shapes::after, .fx-bg-shapes *, .fx-bg-shapes *::before, .fx-bg-shapes *::after { animation: none !important; transition: none !important; }
}
