Box and text shadows from neumorphism and glass to neon, fire and retro lettering.
1Neumorphism
Soft extruded surfaces that match the page background; they press in on hover and adapt to dark mode. Class: fx-neumorphism
50°
Cape Town
<div class="d-flex flex-wrap align-items-center justify-content-center gap-4 p-4 h-100" style="min-height:200px;background:var(--wt-bg)">
<button type="button" class="fx-neumorphism rounded-circle text-primary fs-3" style="width:72px;height:72px" aria-label="Play"><i class="bi bi-play-fill" aria-hidden="true"></i></button>
<div class="fx-neumorphism rounded-4 p-3 text-center" style="width:9rem">
<div class="fs-4 fw-bold">
50°
</div>
<div class="small text-body-secondary">
Cape Town
</div>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-neumorphism {
--fx-neu-bg: var(--wt-bg, #e9edf2);
background: var(--fx-neu-bg); border: 0;
--fx-neu-dark: rgba(0, 0, 0, .14); --fx-neu-light: rgba(255, 255, 255, .75);
box-shadow: 8px 8px 18px var(--fx-neu-dark), -8px -8px 18px var(--fx-neu-light);
transition: box-shadow .35s ease;
}
@supports (color: color-mix(in srgb, red 50%, blue)) {
.fx-neumorphism {
--fx-neu-dark: color-mix(in srgb, var(--fx-neu-bg) 78%, #000);
--fx-neu-light: color-mix(in srgb, var(--fx-neu-bg) 70%, #fff);
}
}
.fx-neumorphism:hover, .fx-neumorphism:focus-visible, .fx-neumorphism:active { box-shadow: inset 6px 6px 12px var(--fx-neu-dark), inset -6px -6px 12px var(--fx-neu-light); }
@media (prefers-reduced-motion: reduce) {
.fx-neumorphism, .fx-neumorphism::before, .fx-neumorphism::after, .fx-neumorphism *, .fx-neumorphism *::before, .fx-neumorphism *::after { animation: none !important; transition: none !important; }
}23D Text Shadow
Stacks hard shadows under a heading so the letters look extruded, with a soft ambient shadow below. Class: fx-3d-text-shadow
Extrude
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<h2 class="display-4 fw-bold mb-0 fx-3d-text-shadow">Extrude</h2>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-3d-text-shadow {
color: var(--wt-primary-ink);
--fx-depth: rgba(0, 0, 0, .35);
text-shadow: 0 1px 0 var(--fx-depth), 0 2px 0 var(--fx-depth), 0 3px 0 var(--fx-depth), 0 4px 0 var(--fx-depth), 0 5px 0 var(--fx-depth), 0 6px 0 var(--fx-depth),
0 8px 6px rgba(0, 0, 0, .2), 0 14px 18px rgba(0, 0, 0, .18);
}
@supports (color: color-mix(in srgb, red 50%, blue)) {
.fx-3d-text-shadow { --fx-depth: color-mix(in srgb, var(--wt-primary) 60%, #000); }
}
@media (prefers-reduced-motion: reduce) {
.fx-3d-text-shadow, .fx-3d-text-shadow::before, .fx-3d-text-shadow::after, .fx-3d-text-shadow *, .fx-3d-text-shadow *::before, .fx-3d-text-shadow *::after { animation: none !important; transition: none !important; }
}3Outline Glow
A glowing focus ring for inputs, buttons and cards that appears on hover and keyboard focus. Class: fx-outline-glow
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="w-100" style="max-width:17rem">
<label for="fx-outline-1269" class="form-label small">Email address</label>
<div class="d-flex gap-2">
<input type="email" class="form-control fx-outline-glow" id="fx-outline-1269" placeholder="you@example.com">
<button type="button" class="btn btn-primary fx-outline-glow"><i class="bi bi-send-fill" aria-hidden="true"></i><span class="visually-hidden">Subscribe</span></button>
</div>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.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; }
}