Rotating Rainbow Border Button
How it works
This is the "Announcing Resend Forward" pill from Resend's hero, ported with the real CSS. The trick that makes a gradient *rotate* is a registered custom property:
@property --angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
Registering --angle as an <angle> type makes it interpolatable, so a @keyframes rotate { to { --angle: 360deg } } can smoothly tween it. A plain CSS variable would jump from 0 to 360 with no in-between frames; the typed @property is what lets linear-gradient(var(--angle), …) visibly spin.
The outer element carries linear-gradient(var(--angle), #02fcef70 0%, #ffb52b70 50%, #a02bfe70 100%) (Resend's real cyan→amber→violet, at ~44% alpha) and a 1px padding; an inner <span> painted the page's background color (#0b0e14) covers everything but that 1px rim, so only a thin rotating outline shows. The animation runs 30s linear infinite.
A ::after pseudo-element holds a brighter, fully-opaque copy of the same rotating gradient with filter: blur(20px), sat behind the pill at opacity: 0. On :hover it fades to 0.9 and stretches (transform: scaleX(1.1)), blooming a soft glow; the face also darkens slightly. Both the rim and the glow share the same --angle keyframe so they stay in lockstep.
Code — copy & paste this whole file
<!doctype html>
<!--
Rotating Rainbow Border Button (Resend "Announcing Resend Forward" pill)
─────────────────────────────────────────────────────────────────────────────
A rounded pill whose 1px border is a linear-gradient rotated forever by an
animated CSS custom property. A registered @property --angle of type <angle>
is interpolatable, so @keyframes can tween it from 0deg→360deg and the gradient
visibly spins. A blurred duplicate of the same gradient sits behind the pill as
a glow that fades in on hover.
Source: extracted verbatim from resend.com/home (rainbow-border CSS). Colors,
timings and structure are the real ones.
Completely standalone — no CDN, no web fonts, no external assets.
-->
<html lang="en">
<head>
<link rel="icon" href="data:,">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rotating Rainbow Border Button</title>
<!-- a14y:begin head — machine-readable metadata; safe to delete when copying -->
<meta name="description" content="A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.">
<link rel="canonical" href="https://fx.statico.io/effects/resend-rainbow-button.html">
<link rel="alternate" type="text/markdown" href="https://fx.statico.io/effects/resend-rainbow-button.md" title="Rotating Rainbow Border Button (Markdown)">
<meta property="og:type" content="website">
<meta property="og:site_name" content="cool web fx">
<meta property="og:title" content="Rotating Rainbow Border Button">
<meta property="og:description" content="A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.">
<meta property="og:url" content="https://fx.statico.io/effects/resend-rainbow-button.html">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Rotating Rainbow Border Button">
<meta name="twitter:description" content="A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.">
<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"SoftwareSourceCode","@id":"https://fx.statico.io/effects/resend-rainbow-button.html#effect","name":"Rotating Rainbow Border Button","url":"https://fx.statico.io/effects/resend-rainbow-button.html","abstract":"A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.","description":"A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.","programmingLanguage":"HTML","codeSampleType":"full solution","runtimePlatform":"Web browser","codeRepository":"https://github.com/statico/cool-web-fx","license":"https://unlicense.org/","isBasedOn":"https://resend.com/home","mainEntityOfPage":"https://fx.statico.io/demos/resend-rainbow-button","dateModified":"2026-07-27T17:24:00-07:00","inLanguage":"en"},{"@type":"BreadcrumbList","@id":"https://fx.statico.io/effects/resend-rainbow-button.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://fx.statico.io/"},{"@type":"ListItem","position":2,"name":"Rotating Rainbow Border Button","item":"https://fx.statico.io/demos/resend-rainbow-button"},{"@type":"ListItem","position":3,"name":"Standalone source","item":"https://fx.statico.io/effects/resend-rainbow-button.html"}]}]}</script>
<style>.a14y-doc{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}</style>
<!-- a14y:end head -->
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #0b0e14; /* Resend's dark background */
display: flex;
align-items: center;
justify-content: center;
font-family: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;
}
/* A registered custom property of type <angle> — REQUIRED so that the
browser can interpolate it inside @keyframes (a plain --angle would jump). */
@property --angle {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@keyframes rotate { to { --angle: 360deg; } }
/* The outer element IS the gradient ring. The inner <span> covers all but a
1px rim, so only that rim of gradient shows. Both the ring and the glow
share the same 30s linear spin. */
.rainbow-border {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 1px; /* thickness of the visible gradient rim */
height: 32px;
border-radius: 9999px;
background: linear-gradient(var(--angle), #02fcef70 0%, #ffb52b70 50%, #a02bfe70 100%);
animation: rotate 30s linear infinite;
cursor: pointer;
}
/* Blurred glow: a brighter copy of the gradient, hidden until hover. */
.rainbow-border::after {
content: "";
position: absolute;
inset: 0;
z-index: -1;
border-radius: 9999px;
background: linear-gradient(var(--angle), #02fcef 0%, #ffb52b 50%, #a02bfe 100%);
filter: blur(20px);
opacity: 0;
transform: scale(0.95, 0.6);
transition: all 0.3s ease-out;
animation: rotate 30s linear infinite;
}
.rainbow-border:hover::after { opacity: 0.9; transform: scaleX(1.1); }
/* The button face. Slightly inset from the ring; matches the page bg so the
pill reads as a thin glowing outline. */
.rainbow-border span {
display: inline-flex;
align-items: center;
gap: 6px;
height: 30px;
padding: 0 14px;
border-radius: 9999px;
background-color: #0b0e14;
color: #e6e8ee;
font-size: 13px;
letter-spacing: 0.01em;
white-space: nowrap;
transition: all 0.2s ease-out;
}
.rainbow-border:hover span { background-color: #0b0e14d1; }
.rainbow-border svg { width: 12px; height: 12px; }
</style>
</head>
<body>
<!-- a14y:begin body — visually hidden description; safe to delete when copying -->
<div class="a14y-doc">
<h1>Rotating Rainbow Border Button</h1>
<p>A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.</p>
<h2>How it works</h2>
<p>This is the "Announcing Resend Forward" pill from Resend's hero, ported with the real CSS. The trick that makes a gradient *rotate* is a registered custom property:</p>
<p>@property --angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }</p>
<p>Registering --angle as an <angle> type makes it interpolatable, so a @keyframes rotate { to { --angle: 360deg } } can smoothly tween it. A plain CSS variable would jump from 0 to 360 with no in-between frames; the typed @property is what lets linear-gradient(var(--angle), …) visibly spin.</p>
<p>The outer element carries linear-gradient(var(--angle), #02fcef70 0%, #ffb52b70 50%, #a02bfe70 100%) (Resend's real cyan→amber→violet, at ~44% alpha) and a 1px padding; an inner <span> painted the page's background color (#0b0e14) covers everything but that 1px rim, so only a thin rotating outline shows. The animation runs 30s linear infinite.</p>
<p>A ::after pseudo-element holds a brighter, fully-opaque copy of the same rotating gradient with filter: blur(20px), sat behind the pill at opacity: 0. On :hover it fades to 0.9 and stretches (transform: scaleX(1.1)), blooming a soft glow; the face also darkens slightly. Both the rim and the glow share the same --angle keyframe so they stay in lockstep.</p>
<h2>How to use this file</h2>
<p>This is a complete, self-contained HTML document — copy it verbatim rather than reconstructing it. Markdown version: <a href="https://fx.statico.io/effects/resend-rainbow-button.md">https://fx.statico.io/effects/resend-rainbow-button.md</a>. Full writeup and live preview: <a href="https://fx.statico.io/demos/resend-rainbow-button">https://fx.statico.io/demos/resend-rainbow-button</a>.</p>
<h2>Source and credit</h2>
<p>Effect originally seen on Resend (https://resend.com/home) — credit to Resend. This is an independent recreation built from scratch for educational use; no proprietary source code was copied. Released under the Unlicense.</p>
<h2>More</h2>
<p>Terms used above are defined in the <a href="https://fx.statico.io/glossary">glossary</a>. See also the <a href="https://fx.statico.io/sitemap.md">site map</a>, <a href="https://fx.statico.io/AGENTS.md">AGENTS.md</a> and <a href="https://fx.statico.io/llms.txt">llms.txt</a>.</p>
</div>
<!-- a14y:end body -->
<a class="rainbow-border" href="#" aria-label="Announcing Resend Forward">
<span>
Announcing Resend Forward
<!-- chevron-right -->
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
</span>
</a>
</body>
</html>
Source & credit
Effect seen on https://resend.com/home — credit to Resend.
This is an independent recreation of the effect built from scratch for educational use. No proprietary source code was copied.
<!doctype html>
<!--
Rotating Rainbow Border Button (Resend "Announcing Resend Forward" pill)
─────────────────────────────────────────────────────────────────────────────
A rounded pill whose 1px border is a linear-gradient rotated forever by an
animated CSS custom property. A registered @property --angle of type <angle>
is interpolatable, so @keyframes can tween it from 0deg→360deg and the gradient
visibly spins. A blurred duplicate of the same gradient sits behind the pill as
a glow that fades in on hover.
Source: extracted verbatim from resend.com/home (rainbow-border CSS). Colors,
timings and structure are the real ones.
Completely standalone — no CDN, no web fonts, no external assets.
-->
<html lang="en">
<head>
<link rel="icon" href="data:,">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rotating Rainbow Border Button</title>
<!-- a14y:begin head — machine-readable metadata; safe to delete when copying -->
<meta name="description" content="A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.">
<link rel="canonical" href="https://fx.statico.io/effects/resend-rainbow-button.html">
<link rel="alternate" type="text/markdown" href="https://fx.statico.io/effects/resend-rainbow-button.md" title="Rotating Rainbow Border Button (Markdown)">
<meta property="og:type" content="website">
<meta property="og:site_name" content="cool web fx">
<meta property="og:title" content="Rotating Rainbow Border Button">
<meta property="og:description" content="A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.">
<meta property="og:url" content="https://fx.statico.io/effects/resend-rainbow-button.html">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Rotating Rainbow Border Button">
<meta name="twitter:description" content="A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.">
<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"SoftwareSourceCode","@id":"https://fx.statico.io/effects/resend-rainbow-button.html#effect","name":"Rotating Rainbow Border Button","url":"https://fx.statico.io/effects/resend-rainbow-button.html","abstract":"A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.","description":"A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.","programmingLanguage":"HTML","codeSampleType":"full solution","runtimePlatform":"Web browser","codeRepository":"https://github.com/statico/cool-web-fx","license":"https://unlicense.org/","isBasedOn":"https://resend.com/home","mainEntityOfPage":"https://fx.statico.io/demos/resend-rainbow-button","dateModified":"2026-07-27T17:24:00-07:00","inLanguage":"en"},{"@type":"BreadcrumbList","@id":"https://fx.statico.io/effects/resend-rainbow-button.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://fx.statico.io/"},{"@type":"ListItem","position":2,"name":"Rotating Rainbow Border Button","item":"https://fx.statico.io/demos/resend-rainbow-button"},{"@type":"ListItem","position":3,"name":"Standalone source","item":"https://fx.statico.io/effects/resend-rainbow-button.html"}]}]}</script>
<style>.a14y-doc{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}</style>
<!-- a14y:end head -->
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #0b0e14; /* Resend's dark background */
display: flex;
align-items: center;
justify-content: center;
font-family: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;
}
/* A registered custom property of type <angle> — REQUIRED so that the
browser can interpolate it inside @keyframes (a plain --angle would jump). */
@property --angle {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@keyframes rotate { to { --angle: 360deg; } }
/* The outer element IS the gradient ring. The inner <span> covers all but a
1px rim, so only that rim of gradient shows. Both the ring and the glow
share the same 30s linear spin. */
.rainbow-border {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 1px; /* thickness of the visible gradient rim */
height: 32px;
border-radius: 9999px;
background: linear-gradient(var(--angle), #02fcef70 0%, #ffb52b70 50%, #a02bfe70 100%);
animation: rotate 30s linear infinite;
cursor: pointer;
}
/* Blurred glow: a brighter copy of the gradient, hidden until hover. */
.rainbow-border::after {
content: "";
position: absolute;
inset: 0;
z-index: -1;
border-radius: 9999px;
background: linear-gradient(var(--angle), #02fcef 0%, #ffb52b 50%, #a02bfe 100%);
filter: blur(20px);
opacity: 0;
transform: scale(0.95, 0.6);
transition: all 0.3s ease-out;
animation: rotate 30s linear infinite;
}
.rainbow-border:hover::after { opacity: 0.9; transform: scaleX(1.1); }
/* The button face. Slightly inset from the ring; matches the page bg so the
pill reads as a thin glowing outline. */
.rainbow-border span {
display: inline-flex;
align-items: center;
gap: 6px;
height: 30px;
padding: 0 14px;
border-radius: 9999px;
background-color: #0b0e14;
color: #e6e8ee;
font-size: 13px;
letter-spacing: 0.01em;
white-space: nowrap;
transition: all 0.2s ease-out;
}
.rainbow-border:hover span { background-color: #0b0e14d1; }
.rainbow-border svg { width: 12px; height: 12px; }
</style>
</head>
<body>
<!-- a14y:begin body — visually hidden description; safe to delete when copying -->
<div class="a14y-doc">
<h1>Rotating Rainbow Border Button</h1>
<p>A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.</p>
<h2>How it works</h2>
<p>This is the "Announcing Resend Forward" pill from Resend's hero, ported with the real CSS. The trick that makes a gradient *rotate* is a registered custom property:</p>
<p>@property --angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }</p>
<p>Registering --angle as an <angle> type makes it interpolatable, so a @keyframes rotate { to { --angle: 360deg } } can smoothly tween it. A plain CSS variable would jump from 0 to 360 with no in-between frames; the typed @property is what lets linear-gradient(var(--angle), …) visibly spin.</p>
<p>The outer element carries linear-gradient(var(--angle), #02fcef70 0%, #ffb52b70 50%, #a02bfe70 100%) (Resend's real cyan→amber→violet, at ~44% alpha) and a 1px padding; an inner <span> painted the page's background color (#0b0e14) covers everything but that 1px rim, so only a thin rotating outline shows. The animation runs 30s linear infinite.</p>
<p>A ::after pseudo-element holds a brighter, fully-opaque copy of the same rotating gradient with filter: blur(20px), sat behind the pill at opacity: 0. On :hover it fades to 0.9 and stretches (transform: scaleX(1.1)), blooming a soft glow; the face also darkens slightly. Both the rim and the glow share the same --angle keyframe so they stay in lockstep.</p>
<h2>How to use this file</h2>
<p>This is a complete, self-contained HTML document — copy it verbatim rather than reconstructing it. Markdown version: <a href="https://fx.statico.io/effects/resend-rainbow-button.md">https://fx.statico.io/effects/resend-rainbow-button.md</a>. Full writeup and live preview: <a href="https://fx.statico.io/demos/resend-rainbow-button">https://fx.statico.io/demos/resend-rainbow-button</a>.</p>
<h2>Source and credit</h2>
<p>Effect originally seen on Resend (https://resend.com/home) — credit to Resend. This is an independent recreation built from scratch for educational use; no proprietary source code was copied. Released under the Unlicense.</p>
<h2>More</h2>
<p>Terms used above are defined in the <a href="https://fx.statico.io/glossary">glossary</a>. See also the <a href="https://fx.statico.io/sitemap.md">site map</a>, <a href="https://fx.statico.io/AGENTS.md">AGENTS.md</a> and <a href="https://fx.statico.io/llms.txt">llms.txt</a>.</p>
</div>
<!-- a14y:end body -->
<a class="rainbow-border" href="#" aria-label="Announcing Resend Forward">
<span>
Announcing Resend Forward
<!-- chevron-right -->
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
</span>
</a>
</body>
</html>