Four candidates on the 4px-corner button. Copyable CSS under each one, dev notes below.
conic-gradient painted on an absolutely positioned pseudo-element behind the button, masked down to a thin band with a two-layer mask + mask-composite: exclude. The rotation animates a registered custom property --a (via @property), so the gradient angle tweens smoothly. Corners are followed exactly; no SVG needed.inset: -2px with padding: 2px (band thickness) and border-radius: button radius + 2px. If the button radius changes, change the ring radius with it.-webkit-mask prefixed lines.prefers-reduced-motion: reduce (included in each snippet).#005EFF, tint #E6EFFF, translucent stops rgba(0,94,255,α). Do not introduce other hues..wrap) and put the ring class on the wrapper. No changes inside the button DOM.<div class="wrap comet">
<button class="pro-btn">…</button>
</div>
/* animated angle */
@property --a { syntax: '<angle>'; initial-value: 0deg; inherits: false; }
@keyframes spin { to { --a: 360deg; } }
.wrap { position: relative; display: inline-flex; }
.comet::before {
content: ''; position: absolute; inset: -2px;
border-radius: 6px; /* button radius 4px + 2px inset */
padding: 2px; /* band thickness */
pointer-events: none;
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor; mask-composite: exclude;
background: conic-gradient(from var(--a),
transparent 0deg, transparent 250deg,
rgba(0,94,255,0) 260deg, rgba(0,94,255,0.55) 320deg,
#005EFF 352deg, #E6EFFF 360deg);
animation: spin 3s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.comet::before { animation: none; }
}
/* same scaffolding as Comet tail (wrap + @property + spin keyframes),
only the ring differs: thinner band, longer tail, slower lap */
.silk::before {
content: ''; position: absolute; inset: -2px;
border-radius: 6px;
padding: 1.5px;
pointer-events: none;
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor; mask-composite: exclude;
background: conic-gradient(from var(--a),
transparent 0deg, transparent 170deg,
rgba(0,94,255,0) 180deg, rgba(0,94,255,0.25) 260deg,
rgba(0,94,255,0.6) 330deg, #005EFF 354deg, #E6EFFF 360deg);
animation: spin 4.6s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.silk::before { animation: none; }
}
/* same scaffolding as Comet tail; thicker band + outer bloom */
.beam::before {
content: ''; position: absolute; inset: -3px;
border-radius: 7px; /* button radius 4px + 3px inset */
padding: 3px;
pointer-events: none;
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor; mask-composite: exclude;
background: conic-gradient(from var(--a),
transparent 0deg, transparent 240deg,
rgba(0,94,255,0) 250deg, rgba(0,94,255,0.5) 315deg,
#005EFF 350deg, #E6EFFF 360deg);
filter: drop-shadow(0 0 6px rgba(0,94,255,0.55));
animation: spin 3s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.beam::before { animation: none; }
}
/* Comet tail ring (variant 01) PLUS a slow drift on the button fill.
The gradient is oversized then eased side to side. */
.pro-btn--living {
background: linear-gradient(90deg, #ccdcfd 0%, #dfe9fe 30%, #f3f6fe 55%,
#fdfdfe 70%, #dfe9fe 100%);
background-size: 250% 100%;
animation: bg-drift 7s ease-in-out infinite;
}
@keyframes bg-drift {
0%, 100% { background-position: 0% 0; }
50% { background-position: 100% 0; }
}
@media (prefers-reduced-motion: reduce) {
.pro-btn--living { animation: none; }
}