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

/* ===== Modern CSS Animations ===== */
/* 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; }
}
/* Heartbeat - A double-beat pulse for like buttons, favourite icons and notification badges. */
.fx-heartbeat { display: inline-block; animation: fx-heartbeat-beat 1.5s ease-in-out infinite; transform-origin: center; }
@keyframes fx-heartbeat-beat {
  0%, 40%, 100% { transform: scale(1); }
  12% { transform: scale(1.2); }
  24% { transform: scale(.96); }
  32% { transform: scale(1.14); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-heartbeat, .fx-heartbeat::before, .fx-heartbeat::after, .fx-heartbeat *, .fx-heartbeat *::before, .fx-heartbeat *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Clip-path Effects ===== */
/* Hexagon Scale - Crops avatars or product shots to a hexagon that grows and tilts slightly on hover. */
.fx-hexagon-scale {
  -webkit-clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0 50%); clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0 50%);
  transition: transform .45s cubic-bezier(.34, 1.56, .64, 1), filter .45s;
}
.fx-hexagon-scale:hover { transform: scale(1.1) rotate(4deg); filter: saturate(1.3); }
@media (prefers-reduced-motion: reduce) {
  .fx-hexagon-scale, .fx-hexagon-scale::before, .fx-hexagon-scale::after, .fx-hexagon-scale *, .fx-hexagon-scale *::before, .fx-hexagon-scale *::after { animation: none !important; transition: none !important; }
}
/* Shape Shifter - A twelve-corner circle that snaps into a plus sign on hover - handy for add buttons and icons. */
.fx-shape-shifter {
  -webkit-clip-path: polygon(30.9% 3.8%, 56.5% 0.4%, 80.4% 10.3%, 96.2% 30.9%, 99.6% 56.5%, 89.7% 80.4%, 69.1% 96.2%, 43.5% 99.6%, 19.6% 89.7%, 3.8% 69.1%, 0.4% 43.5%, 10.3% 19.6%); clip-path: polygon(30.9% 3.8%, 56.5% 0.4%, 80.4% 10.3%, 96.2% 30.9%, 99.6% 56.5%, 89.7% 80.4%, 69.1% 96.2%, 43.5% 99.6%, 19.6% 89.7%, 3.8% 69.1%, 0.4% 43.5%, 10.3% 19.6%);
  transition: clip-path .5s cubic-bezier(.68, -.4, .27, 1.4), transform .5s;
  background: linear-gradient(135deg, var(--wt-primary), var(--wt-secondary));
}
.fx-shape-shifter:hover, .fx-shape-shifter:focus-visible { -webkit-clip-path: polygon(35% 0, 65% 0, 65% 35%, 100% 35%, 100% 65%, 65% 65%, 65% 100%, 35% 100%, 35% 65%, 0 65%, 0 35%, 35% 35%); clip-path: polygon(35% 0, 65% 0, 65% 35%, 100% 35%, 100% 65%, 65% 65%, 65% 100%, 35% 100%, 35% 65%, 0 65%, 0 35%, 35% 35%); transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
  .fx-shape-shifter, .fx-shape-shifter::before, .fx-shape-shifter::after, .fx-shape-shifter *, .fx-shape-shifter *::before, .fx-shape-shifter *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Filter Effects ===== */
/* Grayscale to Color - Keeps images black and white until they are hovered or focused - ideal for logo walls and team grids. */
.fx-grayscale-to-color { filter: grayscale(1); transition: filter .5s ease; }
.fx-grayscale-to-color:hover, .fx-grayscale-to-color:focus-visible, :focus-visible > .fx-grayscale-to-color { filter: grayscale(0); }
@media (prefers-reduced-motion: reduce) {
  .fx-grayscale-to-color, .fx-grayscale-to-color::before, .fx-grayscale-to-color::after, .fx-grayscale-to-color *, .fx-grayscale-to-color *::before, .fx-grayscale-to-color *::after { animation: none !important; transition: none !important; }
}
/* Hue Rotation - Continuously cycles the colours of a gradient, illustration or image through the colour wheel. */
.fx-hue-rotation { animation: fx-hue-rotation-hue 8s linear infinite; }
@keyframes fx-hue-rotation-hue { to { filter: hue-rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .fx-hue-rotation, .fx-hue-rotation::before, .fx-hue-rotation::after, .fx-hue-rotation *, .fx-hue-rotation *::before, .fx-hue-rotation *::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 ===== */
/* 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; }
}
/* Scale & Rotate - A springy scale-and-twist on hover for icons, avatars, logos and small buttons. */
.fx-scale-rotate { transition: transform .45s cubic-bezier(.34, 1.8, .64, 1); }
.fx-scale-rotate:hover, .fx-scale-rotate:focus-visible { transform: scale(1.15) rotate(-8deg); }
@media (prefers-reduced-motion: reduce) {
  .fx-scale-rotate, .fx-scale-rotate::before, .fx-scale-rotate::after, .fx-scale-rotate *, .fx-scale-rotate *::before, .fx-scale-rotate *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Transitions ===== */
/* Neon Fill Button - An outline button that fills with colour from the left and glows; works on any .btn or link. */
.fx-neon-fill-button, .btn.fx-neon-fill-button {
  position: relative; isolation: isolate; overflow: hidden; z-index: 0;
  color: var(--wt-primary-ink); background: transparent; border: 2px solid var(--wt-primary);
  transition: color .35s ease, box-shadow .35s ease;
}
.fx-neon-fill-button::before {
  content: ""; position: absolute; inset: 0; z-index: -1; background: var(--wt-primary);
  transform: scaleX(0); transform-origin: left center; transition: transform .4s cubic-bezier(.7, 0, .3, 1);
}
.fx-neon-fill-button:hover, .fx-neon-fill-button:focus-visible, .btn.fx-neon-fill-button:hover, .btn.fx-neon-fill-button:focus-visible {
  color: var(--wt-on-primary, #fff); border-color: var(--wt-primary);
  box-shadow: 0 0 12px rgba(var(--wt-primary-rgb), .6), 0 0 32px rgba(var(--wt-primary-rgb), .35);
}
.fx-neon-fill-button:hover::before, .fx-neon-fill-button:focus-visible::before { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .fx-neon-fill-button, .fx-neon-fill-button::before, .fx-neon-fill-button::after, .fx-neon-fill-button *, .fx-neon-fill-button *::before, .fx-neon-fill-button *::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; }
}
/* Split Text Fill - Fills a heading or link with the primary colour from both sides at once on hover - top half from the left, bottom half from the right. */
.fx-split-text-fill {
  display: inline-block; text-decoration: none;
  -webkit-text-fill-color: transparent;
  background-image: linear-gradient(var(--wt-primary), var(--wt-primary)), linear-gradient(var(--wt-primary), var(--wt-primary)), linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 0, 100% 100%, 0 0;
  background-size: 0% 50%, 0% 50%, 100% 100%;
  -webkit-background-clip: text; background-clip: text;
  transition: background-size .6s cubic-bezier(.7, 0, .3, 1);
}
.fx-split-text-fill:hover, .fx-split-text-fill:focus-visible { background-size: 100% 50%, 100% 50%, 100% 100%; }
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .fx-split-text-fill { -webkit-text-fill-color: currentColor; background: none; }
  .fx-split-text-fill:hover { color: var(--wt-primary-ink); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-split-text-fill, .fx-split-text-fill::before, .fx-split-text-fill::after, .fx-split-text-fill *, .fx-split-text-fill *::before, .fx-split-text-fill *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Gradient Effects ===== */
/* Aurora Hover - Northern-lights colour clouds that drift inside a card and brighten when it is hovered. */
.fx-aurora-hover { position: relative; isolation: isolate; overflow: hidden; }
.fx-aurora-hover::before {
  content: ""; position: absolute; inset: -40%; z-index: -1; pointer-events: none; opacity: .35;
  background:
    radial-gradient(closest-side at 30% 40%, rgba(var(--wt-primary-rgb), .9), transparent),
    radial-gradient(closest-side at 70% 30%, rgba(var(--wt-accent-rgb), .8), transparent),
    radial-gradient(closest-side at 55% 70%, rgba(var(--wt-secondary-rgb), .8), transparent);
  filter: blur(24px);
  transition: opacity .6s ease;
  animation: fx-aurora-hover-drift 12s ease-in-out infinite alternate;
}
.fx-aurora-hover:hover::before, .fx-aurora-hover:focus-within::before { opacity: .85; }
@keyframes fx-aurora-hover-drift {
  from { transform: translate(-6%, -4%) rotate(0deg); }
  to { transform: translate(6%, 5%) rotate(25deg); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-aurora-hover, .fx-aurora-hover::before, .fx-aurora-hover::after, .fx-aurora-hover *, .fx-aurora-hover *::before, .fx-aurora-hover *::after { animation: none !important; transition: none !important; }
}
/* Shimmer Effect - A diagonal light sweep that glides across buttons, cards or images every few seconds. */
.fx-shimmer-effect { position: relative; overflow: hidden; isolation: isolate; }
.fx-shimmer-effect::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 60%; pointer-events: none;
  background: linear-gradient(110deg, transparent 20%, rgba(255, 255, 255, .55) 50%, transparent 80%);
  transform: translateX(-120%);
  animation: fx-shimmer-effect-sweep 3.2s ease-in-out infinite;
}
@keyframes fx-shimmer-effect-sweep { 0% { transform: translateX(-120%); } 45%, 100% { transform: translateX(260%); } }
@media (prefers-reduced-motion: reduce) {
  .fx-shimmer-effect, .fx-shimmer-effect::before, .fx-shimmer-effect::after, .fx-shimmer-effect *, .fx-shimmer-effect *::before, .fx-shimmer-effect *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern Shadow Effects ===== */
/* Neon Glow - A pulsing neon outline glow for cards, buttons and inputs, best on dark sections. */
.fx-shadow-neon-glow {
  border: 1px solid rgba(var(--wt-primary-rgb), .8);
  box-shadow: 0 0 8px rgba(var(--wt-primary-rgb), .6), 0 0 24px rgba(var(--wt-primary-rgb), .35), inset 0 0 12px rgba(var(--wt-primary-rgb), .25);
  animation: fx-shadow-neon-glow-pulse 2.6s ease-in-out infinite;
}
@keyframes fx-shadow-neon-glow-pulse {
  50% { box-shadow: 0 0 14px rgba(var(--wt-primary-rgb), .8), 0 0 42px rgba(var(--wt-primary-rgb), .5), inset 0 0 18px rgba(var(--wt-primary-rgb), .35); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-shadow-neon-glow, .fx-shadow-neon-glow::before, .fx-shadow-neon-glow::after, .fx-shadow-neon-glow *, .fx-shadow-neon-glow *::before, .fx-shadow-neon-glow *::after { animation: none !important; transition: none !important; }
}
/* Neon Text - Glowing neon-sign lettering with a subtle flicker; looks best on a dark background. */
.fx-neon-text {
  color: #fff;
  text-shadow: 0 0 4px #fff, 0 0 10px rgba(var(--wt-primary-rgb), 1), 0 0 22px rgba(var(--wt-primary-rgb), .9), 0 0 42px rgba(var(--wt-primary-rgb), .7);
  animation: fx-neon-text-flicker 4s linear infinite;
}
@keyframes fx-neon-text-flicker {
  0%, 19%, 21%, 23%, 54%, 56%, 100% { opacity: 1; }
  20%, 22%, 55% { opacity: .55; text-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
  .fx-neon-text, .fx-neon-text::before, .fx-neon-text::after, .fx-neon-text *, .fx-neon-text *::before, .fx-neon-text *::after { animation: none !important; transition: none !important; }
}
/* Soft Glow - A gentle breathing halo in the primary colour that makes a card or avatar feel highlighted. */
.fx-soft-glow { box-shadow: 0 0 24px rgba(var(--wt-primary-rgb), .22); animation: fx-soft-glow-breathe 4s ease-in-out infinite; }
@keyframes fx-soft-glow-breathe { 50% { box-shadow: 0 0 44px rgba(var(--wt-primary-rgb), .42); } }
@media (prefers-reduced-motion: reduce) {
  .fx-soft-glow, .fx-soft-glow::before, .fx-soft-glow::after, .fx-soft-glow *, .fx-soft-glow *::before, .fx-soft-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; }
}
/* Scrolling - A fine blueprint grid that scrolls diagonally forever and fades out towards the edges. */
.fx-bg-scrolling { position: relative; isolation: isolate; overflow: hidden; }
.fx-bg-scrolling::before, .fx-bg-scrolling::after { content: ""; position: absolute; pointer-events: none; z-index: -1; }
.fx-bg-scrolling::before {
  inset: 0;
  background-image:
    linear-gradient(rgba(var(--wt-primary-rgb), .16) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--wt-primary-rgb), .16) 1px, transparent 1px);
  background-size: 36px 36px;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 30%, transparent 78%); mask-image: radial-gradient(ellipse at center, #000 30%, transparent 78%);
  animation: fx-bg-scrolling-scroll 6s linear infinite;
}
@keyframes fx-bg-scrolling-scroll { to { background-position: 36px 36px; } }
@media (prefers-reduced-motion: reduce) {
  .fx-bg-scrolling, .fx-bg-scrolling::before, .fx-bg-scrolling::after, .fx-bg-scrolling *, .fx-bg-scrolling *::before, .fx-bg-scrolling *::after { animation: none !important; transition: none !important; }
}
