Keyframe animations for cards, icons, loaders and headings - drop a class on an element and it comes alive.
1Pulse Wave Effect
Sends expanding rings out of a button, avatar or status dot to draw the eye. Class: fx-pulse-wave-effect
Chloe Moreau
Live now<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<button type="button" class="btn btn-primary rounded-circle d-inline-flex align-items-center justify-content-center fs-4 fx-pulse-wave-effect" style="width:4rem;height:4rem" aria-label="Start live session"><i class="bi bi-broadcast" aria-hidden="true"></i></button>
<div class="d-flex align-items-center gap-2">
<img src="../assets/img/avatar-2.svg" alt="Portrait of the host" class="rounded-circle fx-pulse-wave-effect" width="48" height="48">
<div>
<div class="fw-semibold small">
Chloe Moreau
</div>
<span class="badge text-bg-success">Live now</span>
</div>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.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; }
}2Gradient 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">Strategy, design and code under one roof</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; }
}