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

/* ===== Modern CSS Animations ===== */
/* Pulse Wave Effect - Sends expanding rings out of a button, avatar or status dot to draw the eye. */
.fx-pulse-wave-effect { animation: fx-pulse-wave-effect-pulse 2s ease-out infinite; }
@keyframes fx-pulse-wave-effect-pulse {
  0% { box-shadow: 0 0 0 0 rgba(var(--wt-primary-rgb), .55), 0 0 0 0 rgba(var(--wt-primary-rgb), .35); }
  70% { box-shadow: 0 0 0 16px rgba(var(--wt-primary-rgb), 0), 0 0 0 32px rgba(var(--wt-primary-rgb), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--wt-primary-rgb), 0), 0 0 0 0 rgba(var(--wt-primary-rgb), 0); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-pulse-wave-effect, .fx-pulse-wave-effect::before, .fx-pulse-wave-effect::after, .fx-pulse-wave-effect *, .fx-pulse-wave-effect *::before, .fx-pulse-wave-effect *::after { animation: none !important; transition: none !important; }
}
/* Glitch Text - Splits a heading into offset colour slices that jitter like a broken screen; repeat the text in data-text. */
.fx-glitch-text { position: relative; display: inline-block; }
.fx-glitch-text::before, .fx-glitch-text::after {
  content: attr(data-text); position: absolute; inset: 0; pointer-events: none;
  -webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0);
}
.fx-glitch-text::before { color: var(--wt-accent); left: 2px; text-shadow: -1px 0 var(--wt-primary); animation: fx-glitch-text-a 2.6s steps(1) infinite; }
.fx-glitch-text::after { color: var(--wt-secondary); left: -2px; text-shadow: 1px 0 var(--wt-accent); animation: fx-glitch-text-b 3.1s steps(1) infinite; }
@keyframes fx-glitch-text-a {
  0% { -webkit-clip-path: inset(0 0 82% 0); clip-path: inset(0 0 82% 0); transform: translate(-3px, -1px); }
  15% { -webkit-clip-path: inset(30% 0 52% 0); clip-path: inset(30% 0 52% 0); transform: translate(3px, 1px); }
  30% { -webkit-clip-path: inset(62% 0 20% 0); clip-path: inset(62% 0 20% 0); transform: translate(-2px, 0); }
  45% { -webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0); }
  80% { -webkit-clip-path: inset(12% 0 70% 0); clip-path: inset(12% 0 70% 0); transform: translate(2px, -1px); }
  90% { -webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0); }
}
@keyframes fx-glitch-text-b {
  0% { -webkit-clip-path: inset(70% 0 8% 0); clip-path: inset(70% 0 8% 0); transform: translate(2px, 1px); }
  20% { -webkit-clip-path: inset(8% 0 76% 0); clip-path: inset(8% 0 76% 0); transform: translate(-3px, 0); }
  35% { -webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0); }
  70% { -webkit-clip-path: inset(40% 0 38% 0); clip-path: inset(40% 0 38% 0); transform: translate(3px, -1px); }
  85% { -webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-glitch-text, .fx-glitch-text::before, .fx-glitch-text::after, .fx-glitch-text *, .fx-glitch-text *::before, .fx-glitch-text *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Clip-path Effects ===== */
/* Circle Reveal - Shows a circular window of an image that opens to the full picture on hover or keyboard focus. */
.fx-circle-reveal { -webkit-clip-path: circle(36% at 50% 50%); clip-path: circle(36% at 50% 50%); transition: clip-path .7s cubic-bezier(.6, 0, .2, 1); }
.fx-circle-reveal:hover, .fx-circle-reveal:focus-visible, :focus-visible > .fx-circle-reveal { -webkit-clip-path: circle(75% at 50% 50%); clip-path: circle(75% at 50% 50%); }
@media (prefers-reduced-motion: reduce) {
  .fx-circle-reveal, .fx-circle-reveal::before, .fx-circle-reveal::after, .fx-circle-reveal *, .fx-circle-reveal *::before, .fx-circle-reveal *::after { animation: none !important; transition: none !important; }
}
/* Ellipse Morph - An elliptical frame that breathes between wide and tall - soft and organic for portraits. */
.fx-ellipse-morph { -webkit-clip-path: ellipse(46% 34% at 50% 50%); clip-path: ellipse(46% 34% at 50% 50%); animation: fx-ellipse-morph-breathe 5s ease-in-out infinite alternate; }
@keyframes fx-ellipse-morph-breathe {
  0% { -webkit-clip-path: ellipse(46% 34% at 50% 50%); clip-path: ellipse(46% 34% at 50% 50%); }
  100% { -webkit-clip-path: ellipse(32% 48% at 50% 50%); clip-path: ellipse(32% 48% at 50% 50%); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-ellipse-morph, .fx-ellipse-morph::before, .fx-ellipse-morph::after, .fx-ellipse-morph *, .fx-ellipse-morph *::before, .fx-ellipse-morph *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Filter Effects ===== */
/* 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; }
}
/* Multiple Filters - Stacks contrast, saturation and a drop shadow, then swaps to a warmer combination on hover. */
.fx-multiple-filters { filter: contrast(1.15) saturate(1.3) drop-shadow(0 10px 14px rgba(var(--wt-primary-rgb), .35)); transition: filter .5s ease; }
.fx-multiple-filters:hover { filter: contrast(1.25) saturate(1.6) sepia(.25) drop-shadow(0 16px 22px rgba(var(--wt-accent-rgb), .45)); }
@media (prefers-reduced-motion: reduce) {
  .fx-multiple-filters, .fx-multiple-filters::before, .fx-multiple-filters::after, .fx-multiple-filters *, .fx-multiple-filters *::before, .fx-multiple-filters *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Transform Effects ===== */
/* 3D Rotating Cube - A spinning six-sided cube; give the element six children for the faces and set --fx-size if needed. */
.fx-3d-rotating-cube {
  --fx-half: calc(var(--fx-size, 6rem) / 2);
  position: relative; width: var(--fx-size, 6rem); height: var(--fx-size, 6rem);
  transform-style: preserve-3d;
  animation: fx-3d-rotating-cube-spin 12s linear infinite;
}
.fx-3d-rotating-cube:hover { animation-play-state: paused; }
.fx-3d-rotating-cube > * {
  position: absolute; inset: 0; display: grid; place-items: center; font-size: 1.6rem;
  color: var(--wt-on-primary, #fff); border: 1px solid rgba(255, 255, 255, .35);
  background: rgba(var(--wt-primary-rgb), .88);
}
.fx-3d-rotating-cube > :nth-child(1) { transform: translateZ(var(--fx-half)); }
.fx-3d-rotating-cube > :nth-child(2) { transform: rotateY(180deg) translateZ(var(--fx-half)); background: rgba(var(--wt-secondary-rgb), .88); }
.fx-3d-rotating-cube > :nth-child(3) { transform: rotateY(90deg) translateZ(var(--fx-half)); background: rgba(var(--wt-accent-rgb), .88); }
.fx-3d-rotating-cube > :nth-child(4) { transform: rotateY(-90deg) translateZ(var(--fx-half)); background: rgba(var(--wt-secondary-rgb), .88); }
.fx-3d-rotating-cube > :nth-child(5) { transform: rotateX(90deg) translateZ(var(--fx-half)); background: rgba(var(--wt-accent-rgb), .88); }
.fx-3d-rotating-cube > :nth-child(6) { transform: rotateX(-90deg) translateZ(var(--fx-half)); }
@keyframes fx-3d-rotating-cube-spin {
  from { transform: perspective(700px) rotateX(-22deg) rotateY(0deg); }
  to { transform: perspective(700px) rotateX(-22deg) rotateY(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-3d-rotating-cube, .fx-3d-rotating-cube::before, .fx-3d-rotating-cube::after, .fx-3d-rotating-cube *, .fx-3d-rotating-cube *::before, .fx-3d-rotating-cube *::after { animation: none !important; transition: none !important; }
}
/* Matrix Transform - Uses a single matrix() to scale, skew and lift a tile at once on hover. */
.fx-matrix-transform { transition: transform .5s cubic-bezier(.34, 1.56, .64, 1), box-shadow .5s; }
.fx-matrix-transform:hover, .fx-matrix-transform:focus-visible { transform: matrix(1.05, -.08, .12, 1.05, 0, -8); box-shadow: 0 20px 30px -16px rgba(var(--wt-primary-rgb), .5); }
@media (prefers-reduced-motion: reduce) {
  .fx-matrix-transform, .fx-matrix-transform::before, .fx-matrix-transform::after, .fx-matrix-transform *, .fx-matrix-transform *::before, .fx-matrix-transform *::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 ===== */
/* Glassmorphism Hover - A frosted-glass card that turns clearer, brighter and lifts when hovered; place it over a colourful background. */
.fx-glassmorphism-hover {
  color: #fff; background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .28);
  -webkit-backdrop-filter: blur(8px) saturate(140%); backdrop-filter: blur(8px) saturate(140%);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
  transition: background .45s, backdrop-filter .45s, transform .45s cubic-bezier(.2, .8, .2, 1), box-shadow .45s, border-color .45s;
}
.fx-glassmorphism-hover:hover, .fx-glassmorphism-hover:focus-within {
  background: rgba(255, 255, 255, .24); border-color: rgba(255, 255, 255, .55);
  -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%);
  transform: translateY(-5px); box-shadow: 0 18px 40px rgba(0, 0, 0, .2);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .fx-glassmorphism-hover { background: rgba(var(--wt-primary-rgb), .82); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-glassmorphism-hover, .fx-glassmorphism-hover::before, .fx-glassmorphism-hover::after, .fx-glassmorphism-hover *, .fx-glassmorphism-hover *::before, .fx-glassmorphism-hover *::after { animation: none !important; transition: none !important; }
}
/* Rainbow Glow - Surrounds a button or card with a glow that cycles through the theme colours while hovered. */
.fx-rainbow-glow { transition: box-shadow .4s ease, transform .4s ease; }
.fx-rainbow-glow:hover, .fx-rainbow-glow:focus-visible { transform: translateY(-2px); animation: fx-rainbow-glow-glow 2.4s linear infinite; }
@keyframes fx-rainbow-glow-glow {
  0%, 100% { box-shadow: 0 0 14px rgba(var(--wt-primary-rgb), .75), 0 0 34px rgba(var(--wt-primary-rgb), .35); }
  33% { box-shadow: 0 0 14px rgba(var(--wt-accent-rgb), .75), 0 0 34px rgba(var(--wt-accent-rgb), .35); }
  66% { box-shadow: 0 0 14px rgba(var(--wt-secondary-rgb), .75), 0 0 34px rgba(var(--wt-secondary-rgb), .35); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-rainbow-glow, .fx-rainbow-glow::before, .fx-rainbow-glow::after, .fx-rainbow-glow *, .fx-rainbow-glow *::before, .fx-rainbow-glow *::after { animation: none !important; transition: none !important; }
}
/* Elastic Scale - Buttons, chips and cards that grow with a rubbery overshoot on hover and squash when pressed. */
.fx-elastic-scale { transition: transform .5s cubic-bezier(.34, 1.56, .64, 1); }
.fx-elastic-scale:hover, .fx-elastic-scale:focus-visible { transform: scale(1.08); }
.fx-elastic-scale:active { transform: scale(.94); transition-duration: .15s; }
@media (prefers-reduced-motion: reduce) {
  .fx-elastic-scale, .fx-elastic-scale::before, .fx-elastic-scale::after, .fx-elastic-scale *, .fx-elastic-scale *::before, .fx-elastic-scale *::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 ===== */
/* Glassmorphism - A frosted translucent panel with an inner highlight and soft drop shadow for overlays on images or gradients. */
.fx-glassmorphism {
  color: #fff;
  background: linear-gradient(135deg, rgba(255, 255, 255, .22), rgba(255, 255, 255, .08));
  border: 1px solid rgba(255, 255, 255, .3);
  -webkit-backdrop-filter: blur(14px) saturate(160%); backdrop-filter: blur(14px) saturate(160%);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18), inset 0 1px 0 rgba(255, 255, 255, .45);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .fx-glassmorphism { background: rgba(var(--wt-primary-rgb), .85); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-glassmorphism, .fx-glassmorphism::before, .fx-glassmorphism::after, .fx-glassmorphism *, .fx-glassmorphism *::before, .fx-glassmorphism *::after { animation: none !important; transition: none !important; }
}
/* 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; }
}

/* ===== Advanced Animated Backgrounds ===== */
/* Gradient - A slow, breathing wash of the primary, secondary and accent colours flowing behind the section. */
.fx-bg-gradient-flow { position: relative; isolation: isolate; overflow: hidden; }
.fx-bg-gradient-flow::before, .fx-bg-gradient-flow::after { content: ""; position: absolute; pointer-events: none; z-index: -1; }
.fx-bg-gradient-flow::before {
  inset: 0;
  background: linear-gradient(120deg, rgba(var(--wt-primary-rgb), .30), rgba(var(--wt-secondary-rgb), .22), rgba(var(--wt-accent-rgb), .28), rgba(var(--wt-primary-rgb), .30));
  background-size: 300% 300%;
  animation: fx-bg-gradient-flow-flow 16s ease infinite;
}
@keyframes fx-bg-gradient-flow-flow { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
@media (prefers-reduced-motion: reduce) {
  .fx-bg-gradient-flow, .fx-bg-gradient-flow::before, .fx-bg-gradient-flow::after, .fx-bg-gradient-flow *, .fx-bg-gradient-flow *::before, .fx-bg-gradient-flow *::after { animation: none !important; transition: none !important; }
}
/* 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; }
}
