24 CSS Animated Cards15 / 24
Ambient Breathing Glow
The featured-plan card that genuinely breathes. Two counter-phased auras swell and fade on different periods so the light never looks like a single lamp switching on and off; a conic halo travels around the panel edge; a registered hue property sweeps the whole palette 46 degrees, violet through magenta and back; the rim, the crown, the badge and the feature pips all pulse on the same 6-second clock at staggered phases. Everything animated is composited — opacity, scale and one custom property — and a veil layer keeps the copy at full contrast on the brightest frame.
Published
The code
<section class="ac-15" aria-label="Ambient breathing glow card demo">
<div class="ac-15__stage">
<div class="ac-15__row">
<article class="ac-15__card">
<p class="ac-15__plan">Starter</p>
<p class="ac-15__price">$0<span>/mo</span></p>
<ul class="ac-15__list" role="list"><li>3 projects</li><li>Community support</li><li>1 GB storage</li></ul>
<button class="ac-15__cta" type="button">Choose Starter</button>
</article>
<article class="ac-15__card ac-15__card--hero">
<span class="ac-15__halo" aria-hidden="true"></span>
<span class="ac-15__aura ac-15__aura--a" aria-hidden="true"></span>
<span class="ac-15__aura ac-15__aura--b" aria-hidden="true"></span>
<span class="ac-15__crown" aria-hidden="true"></span>
<span class="ac-15__veil" aria-hidden="true"></span>
<span class="ac-15__sheen" aria-hidden="true"></span>
<span class="ac-15__flag">Most popular</span>
<div class="ac-15__inner">
<p class="ac-15__plan">Studio</p>
<p class="ac-15__price">$24<span>/mo</span></p>
<ul class="ac-15__list ac-15__list--lit" role="list"><li>Unlimited projects</li><li>Priority support · 4 hr SLA</li><li>250 GB storage</li><li>Custom domains</li></ul>
<button class="ac-15__cta ac-15__cta--go" type="button">Choose Studio<span class="ac-15__ctaglow" aria-hidden="true"></span></button>
</div>
</article>
<article class="ac-15__card">
<p class="ac-15__plan">Scale</p>
<p class="ac-15__price">$96<span>/mo</span></p>
<ul class="ac-15__list" role="list"><li>Everything in Studio</li><li>SSO & audit log</li><li>2 TB storage</li></ul>
<button class="ac-15__cta" type="button">Choose Scale</button>
</article>
</div>
<p class="ac-15__chip" aria-hidden="true">counter-phase auras · @property hue drift · rotating conic halo · phase-lagged rim · 6 s ≈ resting breath</p>
</div>
</section><section class="ac-15" aria-label="Ambient breathing glow card demo">
<div class="ac-15__stage">
<div class="ac-15__row">
<article class="ac-15__card">
<p class="ac-15__plan">Starter</p>
<p class="ac-15__price">$0<span>/mo</span></p>
<ul class="ac-15__list" role="list"><li>3 projects</li><li>Community support</li><li>1 GB storage</li></ul>
<button class="ac-15__cta" type="button">Choose Starter</button>
</article>
<article class="ac-15__card ac-15__card--hero">
<span class="ac-15__halo" aria-hidden="true"></span>
<span class="ac-15__aura ac-15__aura--a" aria-hidden="true"></span>
<span class="ac-15__aura ac-15__aura--b" aria-hidden="true"></span>
<span class="ac-15__crown" aria-hidden="true"></span>
<span class="ac-15__veil" aria-hidden="true"></span>
<span class="ac-15__sheen" aria-hidden="true"></span>
<span class="ac-15__flag">Most popular</span>
<div class="ac-15__inner">
<p class="ac-15__plan">Studio</p>
<p class="ac-15__price">$24<span>/mo</span></p>
<ul class="ac-15__list ac-15__list--lit" role="list"><li>Unlimited projects</li><li>Priority support · 4 hr SLA</li><li>250 GB storage</li><li>Custom domains</li></ul>
<button class="ac-15__cta ac-15__cta--go" type="button">Choose Studio<span class="ac-15__ctaglow" aria-hidden="true"></span></button>
</div>
</article>
<article class="ac-15__card">
<p class="ac-15__plan">Scale</p>
<p class="ac-15__price">$96<span>/mo</span></p>
<ul class="ac-15__list" role="list"><li>Everything in Studio</li><li>SSO & audit log</li><li>2 TB storage</li></ul>
<button class="ac-15__cta" type="button">Choose Scale</button>
</article>
</div>
<p class="ac-15__chip" aria-hidden="true">counter-phase auras · @property hue drift · rotating conic halo · phase-lagged rim · 6 s ≈ resting breath</p>
</div>
</section>@property --ac-15-h {
syntax: '<number>';
inherits: true;
initial-value: 0;
}
@property --ac-15-spin {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.ac-15,
.ac-15 *,
.ac-15 *::before,
.ac-15 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ac-15 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
--ac-15-bg: oklch(0.13 0.018 288);
--ac-15-card: oklch(0.185 0.02 288);
--ac-15-ink: oklch(0.97 0.004 280);
--ac-15-mut: oklch(0.70 0.02 288);
--ac-15-acc: oklch(0.76 0.19 308);
--ac-15-acc2: oklch(0.82 0.15 214);
--ac-15-line: oklch(1 0 0/.10);
--ac-15-live: var(--ac-15-acc);
--ac-15-live2: var(--ac-15-acc2);
background: var(--ac-15-bg);
color: var(--ac-15-ink);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
-webkit-font-smoothing: antialiased;
}
.ac-15__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 26px;
padding: clamp(20px,5vw,58px);
background: radial-gradient(120% 80% at 50% 42%,color-mix(in oklch,var(--ac-15-acc) 9%,transparent),transparent 68%);
}
.ac-15__row {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(220px,1fr));
gap: 16px;
align-items: center;
width: min(100%,900px);
}
.ac-15__card {
position: relative;
display: grid;
gap: 13px;
padding: 24px 22px;
border: 1px solid var(--ac-15-line);
border-radius: 22px;
background: var(--ac-15-card);
}
.ac-15__card--hero {
padding: 0;
border-color: color-mix(in oklch,var(--ac-15-live) 46%,transparent);
background: linear-gradient(180deg,color-mix(in oklch,var(--ac-15-live) 13%,var(--ac-15-card)),var(--ac-15-card) 62%);
isolation: isolate;
--ac-15-live: oklch(0.76 0.19 calc(308 + var(--ac-15-h)));
--ac-15-live2: oklch(0.82 0.15 calc(214 + var(--ac-15-h)));
animation: ac-15-hue 12s ease-in-out infinite;
}
.ac-15__inner {
display: grid;
gap: 13px;
padding: 30px 24px;
position: relative;
z-index: 2;
}
@keyframes ac-15-hue {
0%,
100% {
--ac-15-h: -16;
}
50% {
--ac-15-h: 30;
}
}
.ac-15__halo {
position: absolute;
inset: -16px;
z-index: -3;
border-radius: 32px;
pointer-events: none;
background: conic-gradient(from var(--ac-15-spin),transparent 0 48%,color-mix(in oklch,var(--ac-15-live) 90%,transparent) 68%,var(--ac-15-live2) 82%,transparent 96%);
filter: blur(13px);
opacity: .85;
animation: ac-15-spin 13s linear infinite,ac-15-halo 6s ease-in-out infinite;
}
@keyframes ac-15-spin {
to {
--ac-15-spin: 360deg;
}
}
@keyframes ac-15-halo {
0%,
100% {
opacity: .45;
}
50% {
opacity: 1;
}
}
.ac-15__aura {
position: absolute;
z-index: -2;
border-radius: 50%;
pointer-events: none;
filter: blur(34px);
will-change: transform,opacity;
}
.ac-15__aura--a {
inset: -42% -30%;
background: radial-gradient(closest-side,color-mix(in oklch,var(--ac-15-live) 78%,transparent),transparent 74%);
animation: ac-15-breathe 6s ease-in-out infinite;
}
.ac-15__aura--b {
inset: -24% -46% -50% -20%;
background: radial-gradient(closest-side,color-mix(in oklch,var(--ac-15-live2) 62%,transparent),transparent 76%);
animation: ac-15-breathe-b 8.5s ease-in-out infinite;
}
@keyframes ac-15-breathe {
0%,
100% {
opacity: .34;
scale: .9;
}
50% {
opacity: .92;
scale: 1.1;
}
}
@keyframes ac-15-breathe-b {
0%,
100% {
opacity: .62;
scale: 1.08;
translate: 0 0;
}
50% {
opacity: .22;
scale: .88;
translate: 0 -6%;
}
}
.ac-15__crown {
position: absolute;
inset: 1px 1px auto;
height: 56%;
z-index: -1;
border-radius: 21px 21px 0 0;
pointer-events: none;
background: radial-gradient(120% 100% at 50% 0%,color-mix(in oklch,var(--ac-15-live) 46%,transparent),transparent 70%);
animation: ac-15-crown 6s ease-in-out infinite;
}
@keyframes ac-15-crown {
0%,
100% {
opacity: .28;
}
50% {
opacity: .8;
}
}
.ac-15__veil {
position: absolute;
inset: 1px;
z-index: 1;
border-radius: 21px;
pointer-events: none;
background: linear-gradient(180deg,color-mix(in oklch,var(--ac-15-card) 62%,transparent),color-mix(in oklch,var(--ac-15-card) 88%,transparent) 58%);
}
.ac-15__sheen {
position: absolute;
inset: 1px;
z-index: 3;
border-radius: 21px;
overflow: hidden;
pointer-events: none;
}
.ac-15__sheen::before {
content: '';
position: absolute;
inset: -40% -60%;
background: linear-gradient(104deg,transparent 42%,oklch(1 0 0/.16) 50%,transparent 58%);
translate: -120% 0;
animation: ac-15-sheen 9s cubic-bezier(.4,0,.3,1) infinite;
}
@keyframes ac-15-sheen {
0% {
translate: -120% 0;
}
26% {
translate: 120% 0;
}
100% {
translate: 120% 0;
}
}
.ac-15__card--hero::after {
content: '';
position: absolute;
inset: 0;
z-index: 4;
pointer-events: none;
border-radius: 22px;
box-shadow: inset 0 0 0 1px color-mix(in oklch,var(--ac-15-live) 85%,transparent),inset 0 1px 0 0 oklch(1 0 0/.22);
opacity: .3;
animation: ac-15-rim 6s ease-in-out .9s infinite;
}
@keyframes ac-15-rim {
0%,
100% {
opacity: .22;
}
50% {
opacity: .85;
}
}
.ac-15__flag {
position: absolute;
top: -11px;
left: 50%;
translate: -50% 0;
z-index: 5;
padding: 5px 13px;
border-radius: 99px;
background: var(--ac-15-live);
color: oklch(0.14 0.02 300);
font-size: 11px;
font-weight: 750;
letter-spacing: .09em;
text-transform: uppercase;
white-space: nowrap;
box-shadow: 0 6px 20px -6px color-mix(in oklch,var(--ac-15-live) 90%,transparent);
animation: ac-15-flag 6s ease-in-out infinite;
}
@keyframes ac-15-flag {
0%,
100% {
translate: -50% 0;
box-shadow: 0 6px 20px -8px color-mix(in oklch,var(--ac-15-live) 70%,transparent);
}
50% {
translate: -50% -2px;
box-shadow: 0 10px 28px -6px color-mix(in oklch,var(--ac-15-live) 100%,transparent);
}
}
.ac-15__plan {
font-size: 12px;
font-weight: 700;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--ac-15-mut);
}
.ac-15__card--hero .ac-15__plan {
color: var(--ac-15-live);
}
.ac-15__price {
font-size: clamp(32px,4vw,42px);
font-weight: 700;
letter-spacing: -.045em;
line-height: 1;
font-variant-numeric: tabular-nums;
}
.ac-15__price span {
font-size: .36em;
font-weight: 600;
color: var(--ac-15-mut);
letter-spacing: 0;
}
.ac-15__list {
display: grid;
gap: 9px;
list-style: none;
font-size: 13.5px;
color: var(--ac-15-mut);
line-height: 1.4;
}
.ac-15__list li {
display: flex;
gap: 9px;
align-items: flex-start;
}
.ac-15__list li::before {
content: '';
flex: none;
width: 15px;
height: 15px;
margin-top: 1px;
border-radius: 50%;
background: color-mix(in oklch,var(--ac-15-acc) 22%,transparent);
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-acc) 55%,transparent);
}
.ac-15__list--lit li::before {
background: color-mix(in oklch,var(--ac-15-live) 30%,transparent);
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 75%,transparent);
animation: ac-15-pip 6s ease-in-out infinite;
animation-delay: calc(var(--ac-15-p,0) * .5s);
}
.ac-15__list--lit li:nth-child(2)::before {
--ac-15-p: 1;
}
.ac-15__list--lit li:nth-child(3)::before {
--ac-15-p: 2;
}
.ac-15__list--lit li:nth-child(4)::before {
--ac-15-p: 3;
}
@keyframes ac-15-pip {
0%,
100% {
opacity: .55;
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 55%,transparent);
}
50% {
opacity: 1;
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 95%,transparent),0 0 12px -2px color-mix(in oklch,var(--ac-15-live) 80%,transparent);
}
}
.ac-15__cta {
min-height: 46px;
margin-top: 6px;
padding: 0 18px;
border: 1px solid var(--ac-15-line);
border-radius: 13px;
background: oklch(1 0 0/.05);
color: var(--ac-15-ink);
font-size: 14px;
font-weight: 640;
font-family: inherit;
cursor: pointer;
transition: background .22s,transform .22s,border-color .22s;
}
.ac-15__cta:hover {
background: oklch(1 0 0/.1);
transform: translateY(-1px);
}
.ac-15__cta:focus-visible {
outline: 2px solid var(--ac-15-live);
outline-offset: 3px;
}
.ac-15__cta--go {
position: relative;
overflow: hidden;
background: var(--ac-15-live);
border-color: transparent;
color: oklch(0.14 0.02 300);
}
.ac-15__cta--go:hover {
background: color-mix(in oklch,var(--ac-15-live) 88%,oklch(1 0 0));
}
.ac-15__ctaglow {
position: absolute;
inset: 0;
pointer-events: none;
background: radial-gradient(60% 140% at 50% 120%,oklch(1 0 0/.55),transparent 70%);
opacity: .3;
animation: ac-15-ctaglow 6s ease-in-out infinite;
}
@keyframes ac-15-ctaglow {
0%,
100% {
opacity: .18;
}
50% {
opacity: .6;
}
}
.ac-15__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
line-height: 1.6;
color: var(--ac-15-mut);
padding: 8px 15px;
border: 1px solid var(--ac-15-line);
border-radius: 99px;
text-align: center;
max-width: min(100%,760px);
}
@media (prefers-reduced-motion: reduce) {
.ac-15 *,
.ac-15 *::before,
.ac-15 *::after {
animation: none !important;
}
.ac-15__halo {
opacity: .7;
}
.ac-15__aura--a {
opacity: .7;
}
.ac-15__aura--b {
opacity: .45;
}
.ac-15__crown {
opacity: .55;
}
.ac-15__card--hero::after {
opacity: .6;
}
.ac-15__ctaglow {
opacity: .4;
}
.ac-15__sheen {
display: none;
}
.ac-15__cta {
transition: none;
}
}@property --ac-15-h {
syntax: '<number>';
inherits: true;
initial-value: 0;
}
@property --ac-15-spin {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.ac-15,
.ac-15 *,
.ac-15 *::before,
.ac-15 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ac-15 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
--ac-15-bg: oklch(0.13 0.018 288);
--ac-15-card: oklch(0.185 0.02 288);
--ac-15-ink: oklch(0.97 0.004 280);
--ac-15-mut: oklch(0.70 0.02 288);
--ac-15-acc: oklch(0.76 0.19 308);
--ac-15-acc2: oklch(0.82 0.15 214);
--ac-15-line: oklch(1 0 0/.10);
--ac-15-live: var(--ac-15-acc);
--ac-15-live2: var(--ac-15-acc2);
background: var(--ac-15-bg);
color: var(--ac-15-ink);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
-webkit-font-smoothing: antialiased;
}
.ac-15__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 26px;
padding: clamp(20px,5vw,58px);
background: radial-gradient(120% 80% at 50% 42%,color-mix(in oklch,var(--ac-15-acc) 9%,transparent),transparent 68%);
}
.ac-15__row {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(220px,1fr));
gap: 16px;
align-items: center;
width: min(100%,900px);
}
.ac-15__card {
position: relative;
display: grid;
gap: 13px;
padding: 24px 22px;
border: 1px solid var(--ac-15-line);
border-radius: 22px;
background: var(--ac-15-card);
}
.ac-15__card--hero {
padding: 0;
border-color: color-mix(in oklch,var(--ac-15-live) 46%,transparent);
background: linear-gradient(180deg,color-mix(in oklch,var(--ac-15-live) 13%,var(--ac-15-card)),var(--ac-15-card) 62%);
isolation: isolate;
--ac-15-live: oklch(0.76 0.19 calc(308 + var(--ac-15-h)));
--ac-15-live2: oklch(0.82 0.15 calc(214 + var(--ac-15-h)));
animation: ac-15-hue 12s ease-in-out infinite;
}
.ac-15__inner {
display: grid;
gap: 13px;
padding: 30px 24px;
position: relative;
z-index: 2;
}
@keyframes ac-15-hue {
0%,
100% {
--ac-15-h: -16;
}
50% {
--ac-15-h: 30;
}
}
.ac-15__halo {
position: absolute;
inset: -16px;
z-index: -3;
border-radius: 32px;
pointer-events: none;
background: conic-gradient(from var(--ac-15-spin),transparent 0 48%,color-mix(in oklch,var(--ac-15-live) 90%,transparent) 68%,var(--ac-15-live2) 82%,transparent 96%);
filter: blur(13px);
opacity: .85;
animation: ac-15-spin 13s linear infinite,ac-15-halo 6s ease-in-out infinite;
}
@keyframes ac-15-spin {
to {
--ac-15-spin: 360deg;
}
}
@keyframes ac-15-halo {
0%,
100% {
opacity: .45;
}
50% {
opacity: 1;
}
}
.ac-15__aura {
position: absolute;
z-index: -2;
border-radius: 50%;
pointer-events: none;
filter: blur(34px);
will-change: transform,opacity;
}
.ac-15__aura--a {
inset: -42% -30%;
background: radial-gradient(closest-side,color-mix(in oklch,var(--ac-15-live) 78%,transparent),transparent 74%);
animation: ac-15-breathe 6s ease-in-out infinite;
}
.ac-15__aura--b {
inset: -24% -46% -50% -20%;
background: radial-gradient(closest-side,color-mix(in oklch,var(--ac-15-live2) 62%,transparent),transparent 76%);
animation: ac-15-breathe-b 8.5s ease-in-out infinite;
}
@keyframes ac-15-breathe {
0%,
100% {
opacity: .34;
scale: .9;
}
50% {
opacity: .92;
scale: 1.1;
}
}
@keyframes ac-15-breathe-b {
0%,
100% {
opacity: .62;
scale: 1.08;
translate: 0 0;
}
50% {
opacity: .22;
scale: .88;
translate: 0 -6%;
}
}
.ac-15__crown {
position: absolute;
inset: 1px 1px auto;
height: 56%;
z-index: -1;
border-radius: 21px 21px 0 0;
pointer-events: none;
background: radial-gradient(120% 100% at 50% 0%,color-mix(in oklch,var(--ac-15-live) 46%,transparent),transparent 70%);
animation: ac-15-crown 6s ease-in-out infinite;
}
@keyframes ac-15-crown {
0%,
100% {
opacity: .28;
}
50% {
opacity: .8;
}
}
.ac-15__veil {
position: absolute;
inset: 1px;
z-index: 1;
border-radius: 21px;
pointer-events: none;
background: linear-gradient(180deg,color-mix(in oklch,var(--ac-15-card) 62%,transparent),color-mix(in oklch,var(--ac-15-card) 88%,transparent) 58%);
}
.ac-15__sheen {
position: absolute;
inset: 1px;
z-index: 3;
border-radius: 21px;
overflow: hidden;
pointer-events: none;
}
.ac-15__sheen::before {
content: '';
position: absolute;
inset: -40% -60%;
background: linear-gradient(104deg,transparent 42%,oklch(1 0 0/.16) 50%,transparent 58%);
translate: -120% 0;
animation: ac-15-sheen 9s cubic-bezier(.4,0,.3,1) infinite;
}
@keyframes ac-15-sheen {
0% {
translate: -120% 0;
}
26% {
translate: 120% 0;
}
100% {
translate: 120% 0;
}
}
.ac-15__card--hero::after {
content: '';
position: absolute;
inset: 0;
z-index: 4;
pointer-events: none;
border-radius: 22px;
box-shadow: inset 0 0 0 1px color-mix(in oklch,var(--ac-15-live) 85%,transparent),inset 0 1px 0 0 oklch(1 0 0/.22);
opacity: .3;
animation: ac-15-rim 6s ease-in-out .9s infinite;
}
@keyframes ac-15-rim {
0%,
100% {
opacity: .22;
}
50% {
opacity: .85;
}
}
.ac-15__flag {
position: absolute;
top: -11px;
left: 50%;
translate: -50% 0;
z-index: 5;
padding: 5px 13px;
border-radius: 99px;
background: var(--ac-15-live);
color: oklch(0.14 0.02 300);
font-size: 11px;
font-weight: 750;
letter-spacing: .09em;
text-transform: uppercase;
white-space: nowrap;
box-shadow: 0 6px 20px -6px color-mix(in oklch,var(--ac-15-live) 90%,transparent);
animation: ac-15-flag 6s ease-in-out infinite;
}
@keyframes ac-15-flag {
0%,
100% {
translate: -50% 0;
box-shadow: 0 6px 20px -8px color-mix(in oklch,var(--ac-15-live) 70%,transparent);
}
50% {
translate: -50% -2px;
box-shadow: 0 10px 28px -6px color-mix(in oklch,var(--ac-15-live) 100%,transparent);
}
}
.ac-15__plan {
font-size: 12px;
font-weight: 700;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--ac-15-mut);
}
.ac-15__card--hero .ac-15__plan {
color: var(--ac-15-live);
}
.ac-15__price {
font-size: clamp(32px,4vw,42px);
font-weight: 700;
letter-spacing: -.045em;
line-height: 1;
font-variant-numeric: tabular-nums;
}
.ac-15__price span {
font-size: .36em;
font-weight: 600;
color: var(--ac-15-mut);
letter-spacing: 0;
}
.ac-15__list {
display: grid;
gap: 9px;
list-style: none;
font-size: 13.5px;
color: var(--ac-15-mut);
line-height: 1.4;
}
.ac-15__list li {
display: flex;
gap: 9px;
align-items: flex-start;
}
.ac-15__list li::before {
content: '';
flex: none;
width: 15px;
height: 15px;
margin-top: 1px;
border-radius: 50%;
background: color-mix(in oklch,var(--ac-15-acc) 22%,transparent);
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-acc) 55%,transparent);
}
.ac-15__list--lit li::before {
background: color-mix(in oklch,var(--ac-15-live) 30%,transparent);
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 75%,transparent);
animation: ac-15-pip 6s ease-in-out infinite;
animation-delay: calc(var(--ac-15-p,0) * .5s);
}
.ac-15__list--lit li:nth-child(2)::before {
--ac-15-p: 1;
}
.ac-15__list--lit li:nth-child(3)::before {
--ac-15-p: 2;
}
.ac-15__list--lit li:nth-child(4)::before {
--ac-15-p: 3;
}
@keyframes ac-15-pip {
0%,
100% {
opacity: .55;
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 55%,transparent);
}
50% {
opacity: 1;
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 95%,transparent),0 0 12px -2px color-mix(in oklch,var(--ac-15-live) 80%,transparent);
}
}
.ac-15__cta {
min-height: 46px;
margin-top: 6px;
padding: 0 18px;
border: 1px solid var(--ac-15-line);
border-radius: 13px;
background: oklch(1 0 0/.05);
color: var(--ac-15-ink);
font-size: 14px;
font-weight: 640;
font-family: inherit;
cursor: pointer;
transition: background .22s,transform .22s,border-color .22s;
}
.ac-15__cta:hover {
background: oklch(1 0 0/.1);
transform: translateY(-1px);
}
.ac-15__cta:focus-visible {
outline: 2px solid var(--ac-15-live);
outline-offset: 3px;
}
.ac-15__cta--go {
position: relative;
overflow: hidden;
background: var(--ac-15-live);
border-color: transparent;
color: oklch(0.14 0.02 300);
}
.ac-15__cta--go:hover {
background: color-mix(in oklch,var(--ac-15-live) 88%,oklch(1 0 0));
}
.ac-15__ctaglow {
position: absolute;
inset: 0;
pointer-events: none;
background: radial-gradient(60% 140% at 50% 120%,oklch(1 0 0/.55),transparent 70%);
opacity: .3;
animation: ac-15-ctaglow 6s ease-in-out infinite;
}
@keyframes ac-15-ctaglow {
0%,
100% {
opacity: .18;
}
50% {
opacity: .6;
}
}
.ac-15__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
line-height: 1.6;
color: var(--ac-15-mut);
padding: 8px 15px;
border: 1px solid var(--ac-15-line);
border-radius: 99px;
text-align: center;
max-width: min(100%,760px);
}
@media (prefers-reduced-motion: reduce) {
.ac-15 *,
.ac-15 *::before,
.ac-15 *::after {
animation: none !important;
}
.ac-15__halo {
opacity: .7;
}
.ac-15__aura--a {
opacity: .7;
}
.ac-15__aura--b {
opacity: .45;
}
.ac-15__crown {
opacity: .55;
}
.ac-15__card--hero::after {
opacity: .6;
}
.ac-15__ctaglow {
opacity: .4;
}
.ac-15__sheen {
display: none;
}
.ac-15__cta {
transition: none;
}
}Here's a working CSS Animated Card from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Ambient Breathing Glow
Source: https://codefronts.com/components/css-animated-cards/ambient-breathing-glow/
The featured-plan card that genuinely breathes. Two counter-phased auras swell and fade on different periods so the light never looks like a single lamp switching on and off; a conic halo travels around the panel edge; a registered hue property sweeps the whole palette 46 degrees, violet through magenta and back; the rim, the crown, the badge and the feature pips all pulse on the same 6-second clock at staggered phases. Everything animated is composited — opacity, scale and one custom property — and a veil layer keeps the copy at full contrast on the brightest frame.
## HTML
```html
<section class="ac-15" aria-label="Ambient breathing glow card demo">
<div class="ac-15__stage">
<div class="ac-15__row">
<article class="ac-15__card">
<p class="ac-15__plan">Starter</p>
<p class="ac-15__price">$0<span>/mo</span></p>
<ul class="ac-15__list" role="list"><li>3 projects</li><li>Community support</li><li>1 GB storage</li></ul>
<button class="ac-15__cta" type="button">Choose Starter</button>
</article>
<article class="ac-15__card ac-15__card--hero">
<span class="ac-15__halo" aria-hidden="true"></span>
<span class="ac-15__aura ac-15__aura--a" aria-hidden="true"></span>
<span class="ac-15__aura ac-15__aura--b" aria-hidden="true"></span>
<span class="ac-15__crown" aria-hidden="true"></span>
<span class="ac-15__veil" aria-hidden="true"></span>
<span class="ac-15__sheen" aria-hidden="true"></span>
<span class="ac-15__flag">Most popular</span>
<div class="ac-15__inner">
<p class="ac-15__plan">Studio</p>
<p class="ac-15__price">$24<span>/mo</span></p>
<ul class="ac-15__list ac-15__list--lit" role="list"><li>Unlimited projects</li><li>Priority support · 4 hr SLA</li><li>250 GB storage</li><li>Custom domains</li></ul>
<button class="ac-15__cta ac-15__cta--go" type="button">Choose Studio<span class="ac-15__ctaglow" aria-hidden="true"></span></button>
</div>
</article>
<article class="ac-15__card">
<p class="ac-15__plan">Scale</p>
<p class="ac-15__price">$96<span>/mo</span></p>
<ul class="ac-15__list" role="list"><li>Everything in Studio</li><li>SSO & audit log</li><li>2 TB storage</li></ul>
<button class="ac-15__cta" type="button">Choose Scale</button>
</article>
</div>
<p class="ac-15__chip" aria-hidden="true">counter-phase auras · @property hue drift · rotating conic halo · phase-lagged rim · 6 s ≈ resting breath</p>
</div>
</section>
```
## CSS
```css
@property --ac-15-h {
syntax: '<number>';
inherits: true;
initial-value: 0;
}
@property --ac-15-spin {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.ac-15,
.ac-15 *,
.ac-15 *::before,
.ac-15 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ac-15 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
--ac-15-bg: oklch(0.13 0.018 288);
--ac-15-card: oklch(0.185 0.02 288);
--ac-15-ink: oklch(0.97 0.004 280);
--ac-15-mut: oklch(0.70 0.02 288);
--ac-15-acc: oklch(0.76 0.19 308);
--ac-15-acc2: oklch(0.82 0.15 214);
--ac-15-line: oklch(1 0 0/.10);
--ac-15-live: var(--ac-15-acc);
--ac-15-live2: var(--ac-15-acc2);
background: var(--ac-15-bg);
color: var(--ac-15-ink);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
-webkit-font-smoothing: antialiased;
}
.ac-15__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 26px;
padding: clamp(20px,5vw,58px);
background: radial-gradient(120% 80% at 50% 42%,color-mix(in oklch,var(--ac-15-acc) 9%,transparent),transparent 68%);
}
.ac-15__row {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(220px,1fr));
gap: 16px;
align-items: center;
width: min(100%,900px);
}
.ac-15__card {
position: relative;
display: grid;
gap: 13px;
padding: 24px 22px;
border: 1px solid var(--ac-15-line);
border-radius: 22px;
background: var(--ac-15-card);
}
.ac-15__card--hero {
padding: 0;
border-color: color-mix(in oklch,var(--ac-15-live) 46%,transparent);
background: linear-gradient(180deg,color-mix(in oklch,var(--ac-15-live) 13%,var(--ac-15-card)),var(--ac-15-card) 62%);
isolation: isolate;
--ac-15-live: oklch(0.76 0.19 calc(308 + var(--ac-15-h)));
--ac-15-live2: oklch(0.82 0.15 calc(214 + var(--ac-15-h)));
animation: ac-15-hue 12s ease-in-out infinite;
}
.ac-15__inner {
display: grid;
gap: 13px;
padding: 30px 24px;
position: relative;
z-index: 2;
}
@keyframes ac-15-hue {
0%,
100% {
--ac-15-h: -16;
}
50% {
--ac-15-h: 30;
}
}
.ac-15__halo {
position: absolute;
inset: -16px;
z-index: -3;
border-radius: 32px;
pointer-events: none;
background: conic-gradient(from var(--ac-15-spin),transparent 0 48%,color-mix(in oklch,var(--ac-15-live) 90%,transparent) 68%,var(--ac-15-live2) 82%,transparent 96%);
filter: blur(13px);
opacity: .85;
animation: ac-15-spin 13s linear infinite,ac-15-halo 6s ease-in-out infinite;
}
@keyframes ac-15-spin {
to {
--ac-15-spin: 360deg;
}
}
@keyframes ac-15-halo {
0%,
100% {
opacity: .45;
}
50% {
opacity: 1;
}
}
.ac-15__aura {
position: absolute;
z-index: -2;
border-radius: 50%;
pointer-events: none;
filter: blur(34px);
will-change: transform,opacity;
}
.ac-15__aura--a {
inset: -42% -30%;
background: radial-gradient(closest-side,color-mix(in oklch,var(--ac-15-live) 78%,transparent),transparent 74%);
animation: ac-15-breathe 6s ease-in-out infinite;
}
.ac-15__aura--b {
inset: -24% -46% -50% -20%;
background: radial-gradient(closest-side,color-mix(in oklch,var(--ac-15-live2) 62%,transparent),transparent 76%);
animation: ac-15-breathe-b 8.5s ease-in-out infinite;
}
@keyframes ac-15-breathe {
0%,
100% {
opacity: .34;
scale: .9;
}
50% {
opacity: .92;
scale: 1.1;
}
}
@keyframes ac-15-breathe-b {
0%,
100% {
opacity: .62;
scale: 1.08;
translate: 0 0;
}
50% {
opacity: .22;
scale: .88;
translate: 0 -6%;
}
}
.ac-15__crown {
position: absolute;
inset: 1px 1px auto;
height: 56%;
z-index: -1;
border-radius: 21px 21px 0 0;
pointer-events: none;
background: radial-gradient(120% 100% at 50% 0%,color-mix(in oklch,var(--ac-15-live) 46%,transparent),transparent 70%);
animation: ac-15-crown 6s ease-in-out infinite;
}
@keyframes ac-15-crown {
0%,
100% {
opacity: .28;
}
50% {
opacity: .8;
}
}
.ac-15__veil {
position: absolute;
inset: 1px;
z-index: 1;
border-radius: 21px;
pointer-events: none;
background: linear-gradient(180deg,color-mix(in oklch,var(--ac-15-card) 62%,transparent),color-mix(in oklch,var(--ac-15-card) 88%,transparent) 58%);
}
.ac-15__sheen {
position: absolute;
inset: 1px;
z-index: 3;
border-radius: 21px;
overflow: hidden;
pointer-events: none;
}
.ac-15__sheen::before {
content: '';
position: absolute;
inset: -40% -60%;
background: linear-gradient(104deg,transparent 42%,oklch(1 0 0/.16) 50%,transparent 58%);
translate: -120% 0;
animation: ac-15-sheen 9s cubic-bezier(.4,0,.3,1) infinite;
}
@keyframes ac-15-sheen {
0% {
translate: -120% 0;
}
26% {
translate: 120% 0;
}
100% {
translate: 120% 0;
}
}
.ac-15__card--hero::after {
content: '';
position: absolute;
inset: 0;
z-index: 4;
pointer-events: none;
border-radius: 22px;
box-shadow: inset 0 0 0 1px color-mix(in oklch,var(--ac-15-live) 85%,transparent),inset 0 1px 0 0 oklch(1 0 0/.22);
opacity: .3;
animation: ac-15-rim 6s ease-in-out .9s infinite;
}
@keyframes ac-15-rim {
0%,
100% {
opacity: .22;
}
50% {
opacity: .85;
}
}
.ac-15__flag {
position: absolute;
top: -11px;
left: 50%;
translate: -50% 0;
z-index: 5;
padding: 5px 13px;
border-radius: 99px;
background: var(--ac-15-live);
color: oklch(0.14 0.02 300);
font-size: 11px;
font-weight: 750;
letter-spacing: .09em;
text-transform: uppercase;
white-space: nowrap;
box-shadow: 0 6px 20px -6px color-mix(in oklch,var(--ac-15-live) 90%,transparent);
animation: ac-15-flag 6s ease-in-out infinite;
}
@keyframes ac-15-flag {
0%,
100% {
translate: -50% 0;
box-shadow: 0 6px 20px -8px color-mix(in oklch,var(--ac-15-live) 70%,transparent);
}
50% {
translate: -50% -2px;
box-shadow: 0 10px 28px -6px color-mix(in oklch,var(--ac-15-live) 100%,transparent);
}
}
.ac-15__plan {
font-size: 12px;
font-weight: 700;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--ac-15-mut);
}
.ac-15__card--hero .ac-15__plan {
color: var(--ac-15-live);
}
.ac-15__price {
font-size: clamp(32px,4vw,42px);
font-weight: 700;
letter-spacing: -.045em;
line-height: 1;
font-variant-numeric: tabular-nums;
}
.ac-15__price span {
font-size: .36em;
font-weight: 600;
color: var(--ac-15-mut);
letter-spacing: 0;
}
.ac-15__list {
display: grid;
gap: 9px;
list-style: none;
font-size: 13.5px;
color: var(--ac-15-mut);
line-height: 1.4;
}
.ac-15__list li {
display: flex;
gap: 9px;
align-items: flex-start;
}
.ac-15__list li::before {
content: '';
flex: none;
width: 15px;
height: 15px;
margin-top: 1px;
border-radius: 50%;
background: color-mix(in oklch,var(--ac-15-acc) 22%,transparent);
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-acc) 55%,transparent);
}
.ac-15__list--lit li::before {
background: color-mix(in oklch,var(--ac-15-live) 30%,transparent);
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 75%,transparent);
animation: ac-15-pip 6s ease-in-out infinite;
animation-delay: calc(var(--ac-15-p,0) * .5s);
}
.ac-15__list--lit li:nth-child(2)::before {
--ac-15-p: 1;
}
.ac-15__list--lit li:nth-child(3)::before {
--ac-15-p: 2;
}
.ac-15__list--lit li:nth-child(4)::before {
--ac-15-p: 3;
}
@keyframes ac-15-pip {
0%,
100% {
opacity: .55;
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 55%,transparent);
}
50% {
opacity: 1;
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 95%,transparent),0 0 12px -2px color-mix(in oklch,var(--ac-15-live) 80%,transparent);
}
}
.ac-15__cta {
min-height: 46px;
margin-top: 6px;
padding: 0 18px;
border: 1px solid var(--ac-15-line);
border-radius: 13px;
background: oklch(1 0 0/.05);
color: var(--ac-15-ink);
font-size: 14px;
font-weight: 640;
font-family: inherit;
cursor: pointer;
transition: background .22s,transform .22s,border-color .22s;
}
.ac-15__cta:hover {
background: oklch(1 0 0/.1);
transform: translateY(-1px);
}
.ac-15__cta:focus-visible {
outline: 2px solid var(--ac-15-live);
outline-offset: 3px;
}
.ac-15__cta--go {
position: relative;
overflow: hidden;
background: var(--ac-15-live);
border-color: transparent;
color: oklch(0.14 0.02 300);
}
.ac-15__cta--go:hover {
background: color-mix(in oklch,var(--ac-15-live) 88%,oklch(1 0 0));
}
.ac-15__ctaglow {
position: absolute;
inset: 0;
pointer-events: none;
background: radial-gradient(60% 140% at 50% 120%,oklch(1 0 0/.55),transparent 70%);
opacity: .3;
animation: ac-15-ctaglow 6s ease-in-out infinite;
}
@keyframes ac-15-ctaglow {
0%,
100% {
opacity: .18;
}
50% {
opacity: .6;
}
}
.ac-15__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
line-height: 1.6;
color: var(--ac-15-mut);
padding: 8px 15px;
border: 1px solid var(--ac-15-line);
border-radius: 99px;
text-align: center;
max-width: min(100%,760px);
}
@media (prefers-reduced-motion: reduce) {
.ac-15 *,
.ac-15 *::before,
.ac-15 *::after {
animation: none !important;
}
.ac-15__halo {
opacity: .7;
}
.ac-15__aura--a {
opacity: .7;
}
.ac-15__aura--b {
opacity: .45;
}
.ac-15__crown {
opacity: .55;
}
.ac-15__card--hero::after {
opacity: .6;
}
.ac-15__ctaglow {
opacity: .4;
}
.ac-15__sheen {
display: none;
}
.ac-15__cta {
transition: none;
}
}
```Here's a working CSS Animated Card from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Ambient Breathing Glow
Source: https://codefronts.com/components/css-animated-cards/ambient-breathing-glow/
The featured-plan card that genuinely breathes. Two counter-phased auras swell and fade on different periods so the light never looks like a single lamp switching on and off; a conic halo travels around the panel edge; a registered hue property sweeps the whole palette 46 degrees, violet through magenta and back; the rim, the crown, the badge and the feature pips all pulse on the same 6-second clock at staggered phases. Everything animated is composited — opacity, scale and one custom property — and a veil layer keeps the copy at full contrast on the brightest frame.
## HTML
```html
<section class="ac-15" aria-label="Ambient breathing glow card demo">
<div class="ac-15__stage">
<div class="ac-15__row">
<article class="ac-15__card">
<p class="ac-15__plan">Starter</p>
<p class="ac-15__price">$0<span>/mo</span></p>
<ul class="ac-15__list" role="list"><li>3 projects</li><li>Community support</li><li>1 GB storage</li></ul>
<button class="ac-15__cta" type="button">Choose Starter</button>
</article>
<article class="ac-15__card ac-15__card--hero">
<span class="ac-15__halo" aria-hidden="true"></span>
<span class="ac-15__aura ac-15__aura--a" aria-hidden="true"></span>
<span class="ac-15__aura ac-15__aura--b" aria-hidden="true"></span>
<span class="ac-15__crown" aria-hidden="true"></span>
<span class="ac-15__veil" aria-hidden="true"></span>
<span class="ac-15__sheen" aria-hidden="true"></span>
<span class="ac-15__flag">Most popular</span>
<div class="ac-15__inner">
<p class="ac-15__plan">Studio</p>
<p class="ac-15__price">$24<span>/mo</span></p>
<ul class="ac-15__list ac-15__list--lit" role="list"><li>Unlimited projects</li><li>Priority support · 4 hr SLA</li><li>250 GB storage</li><li>Custom domains</li></ul>
<button class="ac-15__cta ac-15__cta--go" type="button">Choose Studio<span class="ac-15__ctaglow" aria-hidden="true"></span></button>
</div>
</article>
<article class="ac-15__card">
<p class="ac-15__plan">Scale</p>
<p class="ac-15__price">$96<span>/mo</span></p>
<ul class="ac-15__list" role="list"><li>Everything in Studio</li><li>SSO & audit log</li><li>2 TB storage</li></ul>
<button class="ac-15__cta" type="button">Choose Scale</button>
</article>
</div>
<p class="ac-15__chip" aria-hidden="true">counter-phase auras · @property hue drift · rotating conic halo · phase-lagged rim · 6 s ≈ resting breath</p>
</div>
</section>
```
## CSS
```css
@property --ac-15-h {
syntax: '<number>';
inherits: true;
initial-value: 0;
}
@property --ac-15-spin {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.ac-15,
.ac-15 *,
.ac-15 *::before,
.ac-15 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.ac-15 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
--ac-15-bg: oklch(0.13 0.018 288);
--ac-15-card: oklch(0.185 0.02 288);
--ac-15-ink: oklch(0.97 0.004 280);
--ac-15-mut: oklch(0.70 0.02 288);
--ac-15-acc: oklch(0.76 0.19 308);
--ac-15-acc2: oklch(0.82 0.15 214);
--ac-15-line: oklch(1 0 0/.10);
--ac-15-live: var(--ac-15-acc);
--ac-15-live2: var(--ac-15-acc2);
background: var(--ac-15-bg);
color: var(--ac-15-ink);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
-webkit-font-smoothing: antialiased;
}
.ac-15__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: 26px;
padding: clamp(20px,5vw,58px);
background: radial-gradient(120% 80% at 50% 42%,color-mix(in oklch,var(--ac-15-acc) 9%,transparent),transparent 68%);
}
.ac-15__row {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(220px,1fr));
gap: 16px;
align-items: center;
width: min(100%,900px);
}
.ac-15__card {
position: relative;
display: grid;
gap: 13px;
padding: 24px 22px;
border: 1px solid var(--ac-15-line);
border-radius: 22px;
background: var(--ac-15-card);
}
.ac-15__card--hero {
padding: 0;
border-color: color-mix(in oklch,var(--ac-15-live) 46%,transparent);
background: linear-gradient(180deg,color-mix(in oklch,var(--ac-15-live) 13%,var(--ac-15-card)),var(--ac-15-card) 62%);
isolation: isolate;
--ac-15-live: oklch(0.76 0.19 calc(308 + var(--ac-15-h)));
--ac-15-live2: oklch(0.82 0.15 calc(214 + var(--ac-15-h)));
animation: ac-15-hue 12s ease-in-out infinite;
}
.ac-15__inner {
display: grid;
gap: 13px;
padding: 30px 24px;
position: relative;
z-index: 2;
}
@keyframes ac-15-hue {
0%,
100% {
--ac-15-h: -16;
}
50% {
--ac-15-h: 30;
}
}
.ac-15__halo {
position: absolute;
inset: -16px;
z-index: -3;
border-radius: 32px;
pointer-events: none;
background: conic-gradient(from var(--ac-15-spin),transparent 0 48%,color-mix(in oklch,var(--ac-15-live) 90%,transparent) 68%,var(--ac-15-live2) 82%,transparent 96%);
filter: blur(13px);
opacity: .85;
animation: ac-15-spin 13s linear infinite,ac-15-halo 6s ease-in-out infinite;
}
@keyframes ac-15-spin {
to {
--ac-15-spin: 360deg;
}
}
@keyframes ac-15-halo {
0%,
100% {
opacity: .45;
}
50% {
opacity: 1;
}
}
.ac-15__aura {
position: absolute;
z-index: -2;
border-radius: 50%;
pointer-events: none;
filter: blur(34px);
will-change: transform,opacity;
}
.ac-15__aura--a {
inset: -42% -30%;
background: radial-gradient(closest-side,color-mix(in oklch,var(--ac-15-live) 78%,transparent),transparent 74%);
animation: ac-15-breathe 6s ease-in-out infinite;
}
.ac-15__aura--b {
inset: -24% -46% -50% -20%;
background: radial-gradient(closest-side,color-mix(in oklch,var(--ac-15-live2) 62%,transparent),transparent 76%);
animation: ac-15-breathe-b 8.5s ease-in-out infinite;
}
@keyframes ac-15-breathe {
0%,
100% {
opacity: .34;
scale: .9;
}
50% {
opacity: .92;
scale: 1.1;
}
}
@keyframes ac-15-breathe-b {
0%,
100% {
opacity: .62;
scale: 1.08;
translate: 0 0;
}
50% {
opacity: .22;
scale: .88;
translate: 0 -6%;
}
}
.ac-15__crown {
position: absolute;
inset: 1px 1px auto;
height: 56%;
z-index: -1;
border-radius: 21px 21px 0 0;
pointer-events: none;
background: radial-gradient(120% 100% at 50% 0%,color-mix(in oklch,var(--ac-15-live) 46%,transparent),transparent 70%);
animation: ac-15-crown 6s ease-in-out infinite;
}
@keyframes ac-15-crown {
0%,
100% {
opacity: .28;
}
50% {
opacity: .8;
}
}
.ac-15__veil {
position: absolute;
inset: 1px;
z-index: 1;
border-radius: 21px;
pointer-events: none;
background: linear-gradient(180deg,color-mix(in oklch,var(--ac-15-card) 62%,transparent),color-mix(in oklch,var(--ac-15-card) 88%,transparent) 58%);
}
.ac-15__sheen {
position: absolute;
inset: 1px;
z-index: 3;
border-radius: 21px;
overflow: hidden;
pointer-events: none;
}
.ac-15__sheen::before {
content: '';
position: absolute;
inset: -40% -60%;
background: linear-gradient(104deg,transparent 42%,oklch(1 0 0/.16) 50%,transparent 58%);
translate: -120% 0;
animation: ac-15-sheen 9s cubic-bezier(.4,0,.3,1) infinite;
}
@keyframes ac-15-sheen {
0% {
translate: -120% 0;
}
26% {
translate: 120% 0;
}
100% {
translate: 120% 0;
}
}
.ac-15__card--hero::after {
content: '';
position: absolute;
inset: 0;
z-index: 4;
pointer-events: none;
border-radius: 22px;
box-shadow: inset 0 0 0 1px color-mix(in oklch,var(--ac-15-live) 85%,transparent),inset 0 1px 0 0 oklch(1 0 0/.22);
opacity: .3;
animation: ac-15-rim 6s ease-in-out .9s infinite;
}
@keyframes ac-15-rim {
0%,
100% {
opacity: .22;
}
50% {
opacity: .85;
}
}
.ac-15__flag {
position: absolute;
top: -11px;
left: 50%;
translate: -50% 0;
z-index: 5;
padding: 5px 13px;
border-radius: 99px;
background: var(--ac-15-live);
color: oklch(0.14 0.02 300);
font-size: 11px;
font-weight: 750;
letter-spacing: .09em;
text-transform: uppercase;
white-space: nowrap;
box-shadow: 0 6px 20px -6px color-mix(in oklch,var(--ac-15-live) 90%,transparent);
animation: ac-15-flag 6s ease-in-out infinite;
}
@keyframes ac-15-flag {
0%,
100% {
translate: -50% 0;
box-shadow: 0 6px 20px -8px color-mix(in oklch,var(--ac-15-live) 70%,transparent);
}
50% {
translate: -50% -2px;
box-shadow: 0 10px 28px -6px color-mix(in oklch,var(--ac-15-live) 100%,transparent);
}
}
.ac-15__plan {
font-size: 12px;
font-weight: 700;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--ac-15-mut);
}
.ac-15__card--hero .ac-15__plan {
color: var(--ac-15-live);
}
.ac-15__price {
font-size: clamp(32px,4vw,42px);
font-weight: 700;
letter-spacing: -.045em;
line-height: 1;
font-variant-numeric: tabular-nums;
}
.ac-15__price span {
font-size: .36em;
font-weight: 600;
color: var(--ac-15-mut);
letter-spacing: 0;
}
.ac-15__list {
display: grid;
gap: 9px;
list-style: none;
font-size: 13.5px;
color: var(--ac-15-mut);
line-height: 1.4;
}
.ac-15__list li {
display: flex;
gap: 9px;
align-items: flex-start;
}
.ac-15__list li::before {
content: '';
flex: none;
width: 15px;
height: 15px;
margin-top: 1px;
border-radius: 50%;
background: color-mix(in oklch,var(--ac-15-acc) 22%,transparent);
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-acc) 55%,transparent);
}
.ac-15__list--lit li::before {
background: color-mix(in oklch,var(--ac-15-live) 30%,transparent);
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 75%,transparent);
animation: ac-15-pip 6s ease-in-out infinite;
animation-delay: calc(var(--ac-15-p,0) * .5s);
}
.ac-15__list--lit li:nth-child(2)::before {
--ac-15-p: 1;
}
.ac-15__list--lit li:nth-child(3)::before {
--ac-15-p: 2;
}
.ac-15__list--lit li:nth-child(4)::before {
--ac-15-p: 3;
}
@keyframes ac-15-pip {
0%,
100% {
opacity: .55;
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 55%,transparent);
}
50% {
opacity: 1;
box-shadow: inset 0 0 0 1.5px color-mix(in oklch,var(--ac-15-live) 95%,transparent),0 0 12px -2px color-mix(in oklch,var(--ac-15-live) 80%,transparent);
}
}
.ac-15__cta {
min-height: 46px;
margin-top: 6px;
padding: 0 18px;
border: 1px solid var(--ac-15-line);
border-radius: 13px;
background: oklch(1 0 0/.05);
color: var(--ac-15-ink);
font-size: 14px;
font-weight: 640;
font-family: inherit;
cursor: pointer;
transition: background .22s,transform .22s,border-color .22s;
}
.ac-15__cta:hover {
background: oklch(1 0 0/.1);
transform: translateY(-1px);
}
.ac-15__cta:focus-visible {
outline: 2px solid var(--ac-15-live);
outline-offset: 3px;
}
.ac-15__cta--go {
position: relative;
overflow: hidden;
background: var(--ac-15-live);
border-color: transparent;
color: oklch(0.14 0.02 300);
}
.ac-15__cta--go:hover {
background: color-mix(in oklch,var(--ac-15-live) 88%,oklch(1 0 0));
}
.ac-15__ctaglow {
position: absolute;
inset: 0;
pointer-events: none;
background: radial-gradient(60% 140% at 50% 120%,oklch(1 0 0/.55),transparent 70%);
opacity: .3;
animation: ac-15-ctaglow 6s ease-in-out infinite;
}
@keyframes ac-15-ctaglow {
0%,
100% {
opacity: .18;
}
50% {
opacity: .6;
}
}
.ac-15__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
line-height: 1.6;
color: var(--ac-15-mut);
padding: 8px 15px;
border: 1px solid var(--ac-15-line);
border-radius: 99px;
text-align: center;
max-width: min(100%,760px);
}
@media (prefers-reduced-motion: reduce) {
.ac-15 *,
.ac-15 *::before,
.ac-15 *::after {
animation: none !important;
}
.ac-15__halo {
opacity: .7;
}
.ac-15__aura--a {
opacity: .7;
}
.ac-15__aura--b {
opacity: .45;
}
.ac-15__crown {
opacity: .55;
}
.ac-15__card--hero::after {
opacity: .6;
}
.ac-15__ctaglow {
opacity: .4;
}
.ac-15__sheen {
display: none;
}
.ac-15__cta {
transition: none;
}
}
```How this works
Animating box-shadow repaints the card every frame. Every layer here is instead its own element animating only compositor-friendly properties:
.aura--a { animation: ac-15-breathe 6s ease-in-out infinite }
.aura--b { animation: ac-15-breathe-b 8.5s ease-in-out infinite } /* counter phase */
@keyframes ac-15-breathe { 0%,100%{opacity:.34;scale:.90} 50%{opacity:.92;scale:1.10} }
@keyframes ac-15-breathe-b { 0%,100%{opacity:.62;scale:1.08} 50%{opacity:.22;scale:.88} }Two auras on different periods, moving in opposite directions is what separates breathing from blinking: their sum never repeats on a short loop, so the light appears to move through the card rather than fade in place.
Six seconds with ease-in-out is roughly ten cycles a minute — human resting rate. Under three seconds reads as a notification demanding attention; over ten stops registering as motion at all.
The colour itself is animated, via a registered property that every token derives from:
@property --ac-15-h { syntax: '<number>'; inherits: true; initial-value: 0 }
.card--hero { --ac-15-live: oklch(0.76 0.19 calc(308 + var(--ac-15-h)));
animation: ac-15-hue 12s ease-in-out infinite }
@keyframes ac-15-hue { 0%,100% { --ac-15-h: -16 } 50% { --ac-15-h: 30 } }Both derived tokens must be declared on the same element that carries the animation. An unregistered custom property is substituted at computed-value time on the element where it is declared, so putting --ac-15-live on an ancestor bakes in the ancestor's static hue and the drift silently does nothing. Because inherits: true, the halo, rim, badge, pips and button glow all shift together — one animated number re-tints nine layers. The halo adds a second registered property, an <angle> driving a blurred conic gradient at inset: -16px, so light travels around the outside of the panel on a 13 s orbit that is deliberately coprime with the 6 s breath.
The rim, crown and pips run the same 6 s duration at staggered delays. That lag is the whole trick: light that arrives everywhere at once reads as an opacity change, while light that arrives in sequence reads as a source moving through the object.
Make it yours
- Slow the whole system down together: every duration here is a multiple of the 6 s breath, so scaling them all by the same factor keeps the phase relationships intact.
- Tie the hue range to brand: narrow
--ac-15-hto 0–8 for a disciplined single-hue glow, or widen to 0–60 for a full aurora. Past about 80 it stops reading as one light source. - State-driven rate: 6 s idle, 2.4 s while a background job runs, 1.2 s on error — the card's pulse becomes a status indicator without adding a single new element.
- Hover intensification: shorten the aura duration and raise peak opacity on
:hoverso the card appears to notice you. - Cheaper build: keep only
--aura--aand the rim. That is roughly 70% of the perceived effect for two layers instead of seven.
Gotchas — read before shipping
- A token derived from an animated custom property must be declared on the element the animation runs on.
var()in an unregistered property is substituted at computed-value time where it is declared, not where it is used — declare--liveon the root while animating--hon the card and the colour freezes at the root's value, with no error to tell you. Verify by sampling the derived colour, not the driving number. - Never animate box-shadow, filter: drop-shadow on the card itself, or background-position of a huge gradient in an infinite loop — all of them repaint every frame.
- Blur radii above ~40 px on a large element are expensive on integrated GPUs. Keep the blurred layer small and scale it up instead.
- Infinite animations on a battery-powered device are a real cost. Pause them when off-screen with an IntersectionObserver, or keep them to one hero element per page.
- An infinite pulse near text is a distraction and, for some users, a vestibular trigger — prefers-reduced-motion must stop it completely, not just slow it.
- Keep the glow behind the content (
z-index: -1) andpointer-events: none, or it swallows clicks and washes out contrast. - A negative z-index child paints above its stacking-context root's own background, so an aura inside the card washes the copy at peak brightness even though it is "behind" everything. Put a veil layer between glow and content — the light still reads through it and contrast stays constant across the cycle. Always check the brightest frame, not the average.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Floor set by oklch(), color-mix(), @property as this demo is written. The core technique itself goes back further — Chrome 80+.
Radial gradients, filter: blur, individual transform properties and keyframe loops are Baseline Widely Available. color-mix() and oklch (Chrome 111 / Safari 16.2 / Firefox 113) are used for token derivation with flat fallbacks.