Keyframe animations for cards, icons, loaders and headings - drop a class on an element and it comes alive.
1Floating Animation
Lets any card, icon or image drift gently up and down as if it were weightless. Class: fx-floating-animation
Volunteer network
Hover to pause
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="card border-0 shadow text-center fx-floating-animation" style="width:12rem">
<div class="card-body">
<div class="fs-1 text-primary mb-2">
<i class="bi bi-rocket-takeoff" aria-hidden="true"></i>
</div>
<h3 class="h6 mb-1">Volunteer network</h3>
<p class="small text-body-secondary mb-0">Hover to pause</p>
</div>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-floating-animation { animation: fx-floating-animation-float 3.6s ease-in-out infinite; will-change: transform; }
.fx-floating-animation:hover { animation-play-state: paused; }
@keyframes fx-floating-animation-float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-12px); }
}
@media (prefers-reduced-motion: reduce) {
.fx-floating-animation, .fx-floating-animation::before, .fx-floating-animation::after, .fx-floating-animation *, .fx-floating-animation *::before, .fx-floating-animation *::after { animation: none !important; transition: none !important; }
}2Multi-Layer Spinner
A loading indicator made of three counter-rotating rings in the theme colours. Class: fx-multi-layer-spinner
Loading...
Preparing your plan
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="text-center">
<div class="fx-multi-layer-spinner" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="small text-body-secondary mt-3 mb-0">Preparing your plan</p>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-multi-layer-spinner {
position: relative; display: inline-block; width: 4rem; height: 4rem; border-radius: 50%;
border: 4px solid transparent; border-top-color: var(--wt-primary);
animation: fx-multi-layer-spinner-spin 1.1s linear infinite;
}
.fx-multi-layer-spinner::before, .fx-multi-layer-spinner::after { content: ""; position: absolute; border-radius: 50%; border: 4px solid transparent; }
.fx-multi-layer-spinner::before { inset: 4px; border-top-color: var(--wt-secondary); animation: fx-multi-layer-spinner-spin 1.7s linear infinite reverse; }
.fx-multi-layer-spinner::after { inset: 14px; border-top-color: var(--wt-accent); animation: fx-multi-layer-spinner-spin .8s linear infinite; }
@keyframes fx-multi-layer-spinner-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
.fx-multi-layer-spinner, .fx-multi-layer-spinner::before, .fx-multi-layer-spinner::after, .fx-multi-layer-spinner *, .fx-multi-layer-spinner *::before, .fx-multi-layer-spinner *::after { animation: none !important; transition: none !important; }
}3Gradient Wave
A banner whose theme gradient flows sideways while a soft wave rolls along its bottom edge. Class: fx-gradient-wave
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="fx-gradient-wave rounded-4 p-4 w-100" style="max-width:19rem">
<p class="small text-uppercase fw-semibold mb-1 opacity-75">New season</p>
<h3 class="h4 fw-bold mb-3">Small acts, big impact</h3>
<a href="#" class="btn btn-light btn-sm">Explore</a>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-gradient-wave {
position: relative; overflow: hidden; color: var(--wt-on-primary, #fff);
background: linear-gradient(90deg, var(--wt-primary), var(--wt-secondary), var(--wt-accent), var(--wt-primary));
background-size: 200% 100%;
animation: fx-gradient-wave-flow 8s linear infinite;
}
.fx-gradient-wave::after {
content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 24px; pointer-events: none;
background: radial-gradient(20px 12px at 50% 100%, rgba(255, 255, 255, .35) 98%, transparent 100%) 0 100% / 40px 24px repeat-x;
animation: fx-gradient-wave-roll 2.4s linear infinite;
}
.fx-gradient-wave > * { position: relative; z-index: 1; }
@keyframes fx-gradient-wave-flow { to { background-position: -200% 0; } }
@keyframes fx-gradient-wave-roll { to { background-position: 40px 100%; } }
@media (prefers-reduced-motion: reduce) {
.fx-gradient-wave, .fx-gradient-wave::before, .fx-gradient-wave::after, .fx-gradient-wave *, .fx-gradient-wave *::before, .fx-gradient-wave *::after { animation: none !important; transition: none !important; }
}