fix: use box-shadow animation for cross-browser compatibility

Previous implementation used CSS @property which isn't supported in
Firefox. New approach uses animated box-shadow with three layers:
- 3px solid border cycling through colors
- 15px inner glow
- 30px outer glow

Colors cycle: purple → magenta → cyan → violet → purple, then fade out.
Works in all modern browsers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
2026-01-13 21:15:50 +01:00
parent d96c70be05
commit 7f3b1944d2

View File

@@ -596,98 +596,47 @@ kbd {
border-radius: var(--border-radius-sm); border-radius: var(--border-radius-sm);
} }
/* Success Match Animation - Gemini-style rotating gradient glow */ /* Success Match Animation - Gemini-style glowing border */
@property --gradient-angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
.preview-wrapper.matched { .preview-wrapper.matched {
--glow-size: 3px; animation: glow-cycle 2.5s ease-out forwards;
--glow-spread: 12px;
} }
/* Glow layer (blurred background) */ @keyframes glow-cycle {
.preview-wrapper.matched::before {
content: "";
position: absolute;
inset: calc(var(--glow-size) * -1);
border-radius: calc(var(--border-radius-md) + var(--glow-size));
background: conic-gradient(
from var(--gradient-angle, 0deg),
#9b59b6,
#e040fb,
#00bcd4,
#7c4dff,
#9b59b6
);
z-index: -1;
filter: blur(var(--glow-spread));
opacity: 0;
animation: glow-fade 2.5s ease-out forwards;
}
/* Border layer (crisp rotating gradient) */
.preview-wrapper.matched::after {
content: "";
position: absolute;
inset: calc(var(--glow-size) * -1);
border-radius: calc(var(--border-radius-md) + var(--glow-size));
background: conic-gradient(
from var(--gradient-angle, 0deg),
#9b59b6,
#e040fb,
#00bcd4,
#7c4dff,
#9b59b6
);
z-index: -1;
padding: var(--glow-size);
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
opacity: 0;
animation: border-rotate 2.5s ease-out forwards;
}
@keyframes border-rotate {
0% { 0% {
--gradient-angle: 0deg; box-shadow:
opacity: 1; 0 0 0 3px #9b59b6,
0 0 15px 5px rgba(155, 89, 182, 0.6),
0 0 30px 10px rgba(155, 89, 182, 0.3);
} }
70% { 25% {
opacity: 1; box-shadow:
} 0 0 0 3px #e040fb,
100% { 0 0 15px 5px rgba(224, 64, 251, 0.6),
--gradient-angle: -360deg; 0 0 30px 10px rgba(224, 64, 251, 0.3);
opacity: 0;
}
}
@keyframes glow-fade {
0% {
--gradient-angle: 0deg;
opacity: 0;
filter: blur(var(--glow-spread));
}
15% {
opacity: 0.7;
filter: blur(calc(var(--glow-spread) * 1.5));
} }
50% { 50% {
opacity: 0.5; box-shadow:
filter: blur(var(--glow-spread)); 0 0 0 3px #00bcd4,
0 0 15px 5px rgba(0, 188, 212, 0.6),
0 0 30px 10px rgba(0, 188, 212, 0.3);
} }
70% { 75% {
opacity: 0.3; box-shadow:
0 0 0 3px #7c4dff,
0 0 15px 5px rgba(124, 77, 255, 0.6),
0 0 30px 10px rgba(124, 77, 255, 0.3);
}
90% {
box-shadow:
0 0 0 3px #9b59b6,
0 0 15px 5px rgba(155, 89, 182, 0.4),
0 0 30px 10px rgba(155, 89, 182, 0.2);
} }
100% { 100% {
--gradient-angle: -360deg; box-shadow:
opacity: 0; 0 0 0 0px transparent,
filter: blur(calc(var(--glow-spread) * 0.5)); 0 0 0px 0px transparent,
0 0 0px 0px transparent;
} }
} }