Exploding like buttonOne-line
Qwen3.8 Flash
by QwenReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 9 min 23 s
- Cost
- $0.019
- Output tokens
- 40,109
- Spent thinking
- 32,850 tokens
- Speed
- 71.4 tok/s
- Console errors
- 0
- First token after
- 736 ms
- First visible text after
- 8 min 20 s
- Prompt tokens
- 411
- Code size
- 16.8 KB
- Finish reason
- stop
- Served by
- Alibaba
- Model id
qwen/qwen3.8-flash- Reasoning sent
model default- Max output
- 64,000 tokens
- Generated
- Nov 11, 2026
What it was asked
The prompt
“a "like" button in pure CSS, no JavaScript, that does a crazy animation when you click it”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task. Output rules: - Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block. - Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task. - Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw. - The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar. - Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction. - Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session. - Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing. - The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message. - The code must run with zero errors in the console of the latest Chrome.
Code run-1.html · 606 lines
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS-only Crazy Like Button</title>
<style>
:root {
--text: #eef3ff;
--muted: #aab5d6;
--pink: #ff2d78;
--pink-2: #ff6fae;
--cyan: #7ee8fa;
--yellow: #ffd166;
--purple: #b18cff;
--green: #a0ffae;
}
*, *::before, *::after {
box-sizing: border-box;
}
html {
height: 100%;
}
body {
min-height: 100vh;
min-height: 100svh;
margin: 0;
position: relative;
display: grid;
place-items: center;
padding: 20px;
overflow-x: hidden;
overflow-y: auto;
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
color: var(--text);
background:
radial-gradient(circle at 12% 10%, rgba(110, 38, 150, 0.55), transparent 38%),
radial-gradient(circle at 88% 8%, rgba(0, 122, 170, 0.42), transparent 38%),
radial-gradient(circle at 78% 88%, rgba(255, 45, 120, 0.26), transparent 35%),
linear-gradient(160deg, #040614, #090c22 45%, #13071f);
}
/* Pure CSS state. The checkbox is hidden but focusable. */
.toggle {
position: absolute;
left: 0;
top: 0;
width: 1px;
height: 1px;
margin: 0;
padding: 0;
border: 0;
opacity: 0;
pointer-events: none;
clip-path: circle(0% at 50% 50%);
}
.toggle:focus-visible ~ .card .like {
outline: 3px solid rgba(126, 232, 250, 0.95);
outline-offset: 5px;
}
.card {
position: relative;
width: min(100%, 680px);
padding: clamp(18px, 4vw, 34px);
border-radius: 30px;
background: linear-gradient(180deg, rgba(23, 28, 58, 0.92), rgba(12, 14, 32, 0.84));
border: 1px solid rgba(255, 255, 255, 0.14);
box-shadow:
0 28px 90px rgba(0, 0, 0, 0.52),
0 0 0 1px rgba(255, 255, 255, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
text-align: center;
isolation: isolate;
}
.eyebrow {
display: inline-block;
padding: 6px 12px;
border-radius: 999px;
font-size: 0.76rem;
font-weight: 900;
letter-spacing: 0.14em;
text-transform: uppercase;
color: #ffd9e9;
background: rgba(255, 45, 120, 0.14);
border: 1px solid rgba(255, 93, 146, 0.45);
}
h1 {
margin: 0.5rem 0 0.4rem;
font-size: clamp(1.45rem, 5vw, 2.6rem);
line-height: 1.05;
letter-spacing: -0.03em;
background: linear-gradient(90deg, #fff, #ffd7ee, #9eefff);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.sub {
margin: 0 auto;
max-width: 48ch;
color: var(--muted);
font-size: clamp(0.9rem, 2.5vw, 1.02rem);
line-height: 1.45;
}
.like-zone {
display: flex;
justify-content: center;
margin: clamp(18px, 5vw, 30px) 0 clamp(12px, 3vw, 18px);
}
.like {
position: relative;
display: inline-flex;
align-items: center;
gap: 18px;
width: min(100%, 330px);
min-height: 96px;
padding: 15px 26px 15px 18px;
border-radius: 999px;
cursor: pointer;
user-select: none;
color: #eaf0ff;
background: linear-gradient(150deg, rgba(45, 51, 90, 0.96), rgba(22, 26, 50, 0.96));
border: 1px solid rgba(255, 255, 255, 0.16);
box-shadow:
0 16px 44px rgba(0, 0, 0, 0.38),
inset 0 1px 0 rgba(255, 255, 255, 0.14);
transition:
background 0.28s ease,
border-color 0.28s ease,
box-shadow 0.28s ease,
color 0.28s ease,
transform 0.12s ease;
}
.like:hover {
transform: translateY(-2px);
border-color: rgba(255, 126, 182, 0.58);
box-shadow:
0 22px 56px rgba(255, 45, 120, 0.22),
inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.toggle:not(:checked) ~ .card .like:active {
transform: scale(0.965);
}
.toggle:checked ~ .card .like {
color: #fff;
background: linear-gradient(135deg, #ff2d78, #ff71ae 46%, #8f1247);
border-color: rgba(255, 255, 255, 0.35);
box-shadow:
0 24px 66px rgba(255, 45, 120, 0.48),
0 0 0 1px rgba(255, 255, 255, 0.14),
inset 0 1px 0 rgba(255, 255, 255, 0.26);
animation: button-dance 1.95s cubic-bezier(0.2, 0.8, 0.25, 1) infinite;
}
.icon-wrap {
position: relative;
width: 68px;
height: 68px;
flex: 0 0 auto;
display: grid;
place-items: center;
perspective: 800px;
}
.heart {
position: relative;
z-index: 5;
width: 60px;
height: 54px;
background: #8d9bb5;
filter: drop-shadow(0 3px 10px rgba(0, 0, 0, 0.32));
clip-path: path("M30 50 C15 40 3 32 3 20 C3 8 14 4 22 10 C26 13 30 17 30 18 C30 17 34 13 38 10 C46 4 57 8 57 20 C57 32 45 40 30 50 Z");
transition: background 0.28s ease, filter 0.28s ease, transform 0.16s ease;
}
.toggle:checked ~ .card .heart {
background: linear-gradient(135deg, #ff1f5b, #ff74b3 46%, #ffd6e8 72%, #ff2d78);
filter: drop-shadow(0 0 16px rgba(255, 54, 121, 0.75));
animation: heart-crazy 2.05s cubic-bezier(0.16, 0.84, 0.26, 1) infinite;
}
.glow {
position: absolute;
z-index: 1;
left: 50%;
top: 50%;
width: 130px;
height: 130px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0.78);
background: radial-gradient(circle, rgba(255, 73, 134, 0.78), rgba(255, 73, 134, 0) 68%);
filter: blur(16px);
opacity: 0.16;
pointer-events: none;
}
.toggle:checked ~ .card .glow {
animation: glow-pulse 1.95s ease-in-out infinite;
}
.rays {
position: absolute;
z-index: 2;
left: 50%;
top: 50%;
width: 170px;
height: 170px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0.08);
opacity: 0;
pointer-events: none;
background: repeating-conic-gradient(from 0deg, rgba(255, 255, 255, 0.94) 0deg 6deg, transparent 6deg 18deg);
-webkit-mask-image: radial-gradient(circle, rgba(0, 0, 0, 1) 14%, rgba(0, 0, 0, 0) 64%);
mask-image: radial-gradient(circle, rgba(0, 0, 0, 1) 14%, rgba(0, 0, 0, 0) 64%);
}
.toggle:checked ~ .card .rays {
animation: ray-pop 1.9s ease-out 0.02s infinite;
}
.ring {
position: absolute;
z-index: 3;
left: 50%;
top: 50%;
width: 58px;
height: 58px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0.16);
opacity: 0;
pointer-events: none;
will-change: transform, opacity;
}
.r1 { border: 3px solid rgba(255, 105, 159, 0.95); }
.r2 { border: 2px solid rgba(255, 209, 102, 0.92); }
.r3 { border: 1.5px solid rgba(126, 232, 250, 0.9); }
.toggle:checked ~ .card .ring {
animation: ring-burst 1.65s ease-out infinite;
}
.toggle:checked ~ .card .r1 { animation-delay: 0.08s; }
.toggle:checked ~ .card .r2 { animation-delay: 0.36s; }
.toggle:checked ~ .card .r3 { animation-delay: 0.68s; }
.burst {
position: absolute;
inset: 0;
z-index: 4;
pointer-events: none;
}
.burst i {
position: absolute;
left: 50%;
top: 50%;
width: 8px;
height: 8px;
border-radius: 999px;
background: var(--c, #fff);
opacity: 0;
transform: translate(-50%, -50%) scale(0.1);
pointer-events: none;
will-change: transform, opacity;
}
.burst i:nth-child(even) { border-radius: 2px; }
.burst i:nth-child(3n) { width: 7px; height: 7px; }
.burst i:nth-child(4n) { width: 10px; height: 10px; }
.burst i:nth-child(1) { --a: 0deg; --r: 82px; --d: 0s; --c: #ff6fae; }
.burst i:nth-child(2) { --a: 22deg; --r: 96px; --d: .04s; --c: #ffd166; }
.burst i:nth-child(3) { --a: 44deg; --r: 88px; --d: .08s; --c: #ff4d6d; }
.burst i:nth-child(4) { --a: 66deg; --r: 104px; --d: .03s; --c: #7ee8fa; }
.burst i:nth-child(5) { --a: 88deg; --r: 92px; --d: .11s; --c: #fff; }
.burst i:nth-child(6) { --a: 110deg; --r: 110px; --d: .07s; --c: #b18cff; }
.burst i:nth-child(7) { --a: 132deg; --r: 84px; --d: .14s; --c: #ffca3a; }
.burst i:nth-child(8) { --a: 154deg; --r: 98px; --d: .02s; --c: #ff85c1; }
.burst i:nth-child(9) { --a: 176deg; --r: 108px; --d: .09s; --c: #51e5ff; }
.burst i:nth-child(10) { --a: 198deg; --r: 90px; --d: .13s; --c: #a0ffae; }
.burst i:nth-child(11) { --a: 220deg; --r: 102px; --d: .05s; --c: #ff4d8f; }
.burst i:nth-child(12) { --a: 242deg; --r: 94px; --d: .12s; --c: #ffe066; }
.burst i:nth-child(13) { --a: 264deg; --r: 106px; --d: .01s; --c: #7ee8fa; }
.burst i:nth-child(14) { --a: 286deg; --r: 88px; --d: .10s; --c: #ff6fae; }
.burst i:nth-child(15) { --a: 308deg; --r: 100px; --d: .06s; --c: #b18cff; }
.burst i:nth-child(16) { --a: 330deg; --r: 112px; --d: .15s; --c: #fff; }
.burst i:nth-child(17) { --a: 352deg; --r: 86px; --d: .08s; --c: #ffd166; }
.burst i:nth-child(18) { --a: 15deg; --r: 98px; --d: .04s; --c: #ff4d6d; }
.toggle:checked ~ .card .burst i {
animation-name: spark-burst;
animation-duration: 1.45s;
animation-timing-function: ease-out;
animation-delay: var(--d, 0s);
animation-iteration-count: infinite;
}
.flash {
position: absolute;
z-index: 6;
left: 50%;
top: 50%;
width: 110px;
height: 110px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0.18);
background: radial-gradient(circle, rgba(255, 255, 255, 0.92), rgba(255, 180, 220, 0.45) 26%, transparent 66%);
opacity: 0;
pointer-events: none;
mix-blend-mode: screen;
}
.toggle:checked ~ .card .flash {
animation: flash-pop 0.9s ease-out infinite;
}
.copy {
display: grid;
gap: 4px;
text-align: left;
min-width: 108px;
}
.line {
position: relative;
line-height: 1.12;
min-height: 1.12em;
}
.line.count {
color: rgba(236, 242, 255, 0.74);
font-size: clamp(0.82rem, 2.5vw, 0.92rem);
font-weight: 700;
}
.word,
.num {
position: absolute;
left: 0;
top: 0;
white-space: nowrap;
transition: opacity 0.28s ease, transform 0.28s ease;
}
.word {
font-size: clamp(1.18rem, 4vw, 1.55rem);
font-weight: 900;
letter-spacing: -0.02em;
}
.word.on,
.num.on {
opacity: 0;
transform: translateY(8px);
}
.word.off,
.num.off {
opacity: 1;
transform: translateY(0);
}
.toggle:checked ~ .card .word.off {
opacity: 0;
transform: translateY(-8px);
}
.toggle:checked ~ .card .word.on {
opacity: 1;
transform: none;
animation: text-pop 1.8s ease-in-out infinite;
}
.toggle:checked ~ .card .num.off {
opacity: 0;
transform: translateY(-6px);
}
.toggle:checked ~ .card .num.on {
opacity: 1;
transform: none;
animation: text-pop 1.8s ease-in-out 0.12s infinite;
}
.footer {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px 14px;
color: #b5bfd9;
font-size: 0.82rem;
}
.pill {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 7px 12px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.07);
border: 1px solid rgba(255, 255, 255, 0.12);
font-weight: 700;
}
.dot {
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--pink-2);
box-shadow: 0 0 12px var(--pink-2);
animation: dot-pulse 1.6s ease-in-out infinite;
}
.dot.blue {
background: var(--cyan);
box-shadow: 0 0 12px var(--cyan);
}
/* Checked-only full-card energy */
.toggle:checked ~ .card {
animation: card-shake 2.35s ease-in-out infinite;
}
@keyframes card-shake {
0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
22% { transform: translate3d(-2px, 1px, 0) rotate(-0.25deg); }
48% { transform: translate3d(3px, -2px, 0) rotate(0.35deg); }
74% { transform: translate3d(-2px, 2px, 0) rotate(-0.3deg); }
}
@keyframes button-dance {
0%, 100% { transform: translateY(0) rotate(0deg) scale(1); }
20% { transform: translateY(-3px) rotate(-2deg) scale(1.025); }
45% { transform: translateY(2px) rotate(2deg) scale(0.985); }
70% { transform: translateY(-1px) rotate(-1deg) scale(1.02); }
}
@keyframes heart-crazy {
0% {
transform: scale(1) rotate(0deg);
filter: drop-shadow(0 3px 12px rgba(255, 45, 120, 0.45));
}
20% {
transform: scale(1.24) rotate(-26deg);
filter: drop-shadow(0 0 22px rgba(255, 70, 140, 0.85));
}
40% {
transform: scale(0.88) rotate(24deg);
filter: drop-shadow(0 0 14px rgba(255, 70, 140, 0.55));
}
60% {
transform: scale(1.32) rotate(360deg);
filter: drop-shadow(0 0 30px rgba(255, 110, 170, 0.95));
}
80% {
transform: scale(1.02) rotate(360deg);
filter: drop-shadow(0 0 18px rgba(255, 80, 150, 0.62));
}
100% {
transform: scale(1) rotate(360deg);
filter: drop-shadow(0 3px 12px rgba(255, 45, 120, 0.45));
}
}
@keyframes ring-burst {
0% {
transform: translate(-50%, -50%) scale(0.16);
opacity: 0;
}
18% { opacity: 0.95; }
100% {
transform: translate(-50%, -50%) scale(3.1);
opacity: 0;
}
}
@keyframes ray-pop {
0% {
transform: translate(-50%, -50%) scale(0.08) rotate(0deg);
opacity: 0;
}
18% { opacity: 0.85; }
100% {
transform: translate(-50%, -50%) scale(1.85) rotate(130deg);
opacity: 0;
}
}
@keyframes spark-burst {
0% {
transform: translate(-50%, -50%) rotate(var(--a)) translateY(0) scale(0.1);
opacity: 0;
}
12% { opacity: 1; }
55% {
transform: translate(-50%, -50%) rotate(var(--a)) translateY(calc(var(--r) * -0.78)) scale(1.12);
opacity: 1;
}
100% {
transform: translate(-50%, -50%) rotate(var(--a)) translateY(calc(var(--r) * -1.18)) scale(0.1);
opacity: 0;
}
}
@keyframes glow-pulse {
0%, 100% {
transform: translate(-50%, -50%) scale(0.78);
opacity: 0.18;
filter: blur(16px);
}
45% {
transform: translate(-50%, -50%) scale(1.35);
opacity: 0.62;
filter: blur(24px);
}
}
@keyframes flash-pop {
0% {
transform: translate(-50%, -50%) scale(0.18);
opacity: 0;
}
12% { opacity: 0.95; }
100% {
transform: translate(-50%, -50%) scale(2.8);
opacity: 0;
}
}
@keyframes text-pop {
0%, 100% {
transform: translateY(0) scale(1);
}
18% {
transform: translateY(-3px) scale(1.08);
}
42% {
transform: translateY(1px) scale(0.98);
}
}
@keyframes dot-pulse {
0%, 100% { transform: scale(0.8); opacity: 0.72; }
50% { transform: scale(1.25); opacity: 1; }
}
</style>
</head>
<body>
<input id="like" class="toggle" type="checkbox" checked aria-label="Like">
<main class="card">
<span class="eyebrow">Pure CSS · No JavaScript</span>
<h1>Crazy Like Button</h1>
<p class="sub">
Click or tap the heart button. This demo starts in the “liked” state so the CSS-only
explosion is visible immediately.
</p>
<div class="like-zone">
<label for="like" class="like">
<span class="icon-wrap" aria-hidden="true">
<span class="rays"></span>
<span class="glow"></span>
<span class="ring r1"></span>
<span class="ring r2"></span>
<span class="ring r3"></span>
<span class="burst">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
</span>
<span class="heart"></span>
<span class="flash"></span>
</span>
<span class="copy">
<span class="line title">
<span class="word off">Like</span>
<span class="word on">Loved</span>
</span>
<span class="line count">
<span class="num off">1.2k likes</span>
<span class="num on">1.3k likes</span>
</span>
</span>
</label>
</div>
<footer class="footer">
<span class="pill"><span class="dot"></span> CSS :checked triggers the animation</span>
<span class="pill"><span class="dot blue"></span> Keyboard: click page, then press Space</span>
</footer>
</main>
</body>
</html>Reasoning trace (32,850 tokens)
We need answer user's request: generate self-contained web demo. Task: "a 'like' button in pure CSS, no JavaScript, that does a crazy animation when you click it". Output exactly one fenced code block html. Need pure CSS no JavaScript. But demo rules mention games self-playing etc irrelevant. Need ensure animation on click using checkbox trick pure CSS. We can make a like button with hidden checkbox, label styled as button. On check triggers crazy animation: heart pops, particles burst, shockwave, color change, counter increments? CSS-only counter can use label ::before content maybe animation sequence. Need no JS. Need visible on first paint. Could be a page showcasing a giant like button. Since screenshot after 3 sec: if not clicked, should look interesting. We can have button idle with pulsing hint maybe. But crazy animation only when clicked. Need CSS only. Use input[type=checkbox] hidden. label as button. On :checked use sibling selectors to animate elements. For click once toggle; repeated toggles off. Need maybe animation replays only when checked? CSS animation triggered by class change via :checked; unchecking may reset. Good enough. Could use checkbox and label inside? If label wraps input, clicking toggles. But sibling selectors require input and animated elements as siblings. Could structure: <input id="like" class="like__toggle" type="checkbox"> <label for="like" class="like">... heart ... particles ...</label>. For checked animations targeting .like__toggle:checked ~ .like .heart etc. Need input before label. Good.
Need pure CSS: no JS. Maybe use <button>? Can't trigger CSS state without JS unless :active, but animation would only while pressed. Checkbox gives toggle.
Crazy animation: on like: heart scales up, spins, explodes? We can create burst of particles via pseudo-elements? Better have multiple spans for particles. CSS animation: heart pop, shockwave ring, sparkles, rays rotating, text change? Need no JS. Use CSS content maybe "LIKE" -> "LIKED". Can animate label content? Pseudo-element content cannot animate easily, but can switch opacity between two spans. Use .txt-like and .txt-liked, animate opacity when checked. Counter: maybe 1.2k -> 1.3k switch.
Need adapt 1280x800 to 375. Center stage. Use viewport min-height. Background maybe gradient.
Need avoid horizontal scrollbar. Use overflow hidden on body? But page content maybe no scroll. Use overflow-x hidden. Maybe no vertical? For viewport fixed, use body height 100vh and overflow hidden. But if small screens, ensure no scroll? min-height 100svh.
Need ensure animation visible after 3 seconds. If screenshot no interaction, idle state. We can make idle have subtle pulse to invite click, plus maybe title says Click to animate. But "crazy animation when you click" could be shown by automatically clicking? Pure CSS can animate a fake cursor? Could include a demo auto-click illusion? But checkbox cannot be clicked by CSS. We can have a decorative cursor that pulses and maybe button auto animates on hover? But click required for state. Since screenshot no click, if animation only on click, it will be static. However something visible must be interesting: maybe include multiple buttons and one auto-playing using CSS animation independent of click. But task specifically like button crazy animation when click. Could have demo mode auto-click? In sandbox, keyboard/click after user click. But screenshot no interaction. We can make the like button animated automatically as if clicked via CSS by initially checked? But if checked, it shows liked state with crazy animation on load. That's good visible on first paint. But click toggles maybe off/on. Could use default checked checkbox so it performs crazy animation on load and can be clicked to toggle. But then on load it's already liked; clicking unlikes maybe not as fun. Could set animation to play once on load and replay when checked? We can use animation with both idle and checked? To have crazy animation on first paint without JS, set the button in liked state via :checked and trigger animations with delay maybe. But if it's checked initially, CSS animations start on load. Then user clicking will uncheck and maybe animate unlike, click again animate like. That's acceptable. It shows action in screenshot at 3 sec if animation loops? Need ensure not all animations finished by 3 sec. If one-shot 1.2s, screenshot sees final liked state but not crazy. We can make infinite subtle loop while checked (e.g., heart pulses, sparkles) and crazy one-shot on load. Or use animation-delay? On initial checked, animations run. We can keep repeating burst maybe every few seconds while checked to show action. But click animation should happen on state change. We can have while checked an infinite "liked" pulse, but initial burst one-shot may be finished. Could set burst infinite too while checked: repeated crazy. But request when click: could be infinite once clicked. Good.
Need pure CSS animation triggered by :checked. Since input checked initially, we can have the crazy loop on. But if they click again to uncheck, animation stops and resets. Clicking to check again restarts CSS animations because selectors change; good.
Maybe use checkbox with `checked` initial to ensure visible crazy. But user asked click to animate; initial auto is demo. Could say "Click to like / unlike — demo starts liked to show the animation." But if screenshot, title plus animated. Could also include a second button unchecked with "Try it". Need no JS, pure CSS.
Need ensure "crazy" enough: Heart 3D rotate? CSS heart made of two circles and square. On like, heart transforms scale, spin, wobble; burst particles explode outward and fade; shockwave rings expand; confetti rays rotate and scale; label text pops; color changes; counter increment; maybe whole card shakes; maybe a "BOOM" flash.
We can implement particles as multiple spans inside .burst, each with CSS variables for direction and animation delay. Inline style? Allowed? CSS variables inline not JavaScript; okay. But task says pure CSS no JavaScript; inline style with --x not JS, but to keep pure CSS could use nth-child classes with transforms. Simpler: create 12 spans and use nth-child rotate transforms in CSS. Could use --i with inline style? It's still HTML/CSS, not JS. Better pure CSS maybe use classes p1..p12. But many.
We can make 16 particles around using nth-of-type transforms with calc? CSS var inline easier. But no external fonts. Use emoji ❤? But a "like" button with heart shape CSS maybe. Emoji is content, no network. Could use 🤍 and ❤️? But animation of text maybe. Need visual robust. A CSS heart is nice. Emoji might render inconsistent but okay. We can create heart with CSS: two rounded blobs and square. Use transform rotate(-45). Let's design.
Structure:
<body>
<main class="stage">
<div class="card">
<header>
<span class="eyebrow">CSS-only</span>
<h1>Insane Like Button</h1>
<p>Click the heart. No JavaScript. Crazy animation.</p>
</header>
<div class="like-zone">
<input id="like" class="toggle" type="checkbox" checked>
<label for="like" class="like" aria-pressed maybe? label not button but okay>
<span class="ring r1"></span>
<span class="ring r2"></span>
<span class="ring r3"></span>
<span class="glow"></span>
<span class="burst">
<i style="--d:0deg;--p:0"></i>... or classes
</span>
<span class="rays"></span>
<span class="heart">...</span>
<span class="like-copy">
<span class="txt liked">Liked</span>
<span class="txt unliked">Like</span>
<span class="count liked">1.3k</span><span class="count unliked">1.2k</span>
</span>
<span class="flash"></span>
</label>
</div>
</main>
CSS:
:root colors.
.stage center, background gradient maybe animated (no JS). body overflow hidden.
.label: position relative, width min(260px, 68vw), aspect-ratio 1 maybe? Or pill button with heart and text. Crazy animation can be around button. Could center heart with rings. Use flex column, height 180, width 260. background glass, border, shadow.
Heart CSS:
.heart { width:64px; height:56px; position relative; transform: rotate(-45); ... }
.heart::before, ::after { content:''; width:32px; height:32px; border-radius:50%; background:red; position absolute; top:-16px; } before left:-16; after right:-16? Actually heart shape: square rotated, two circles on top and left. If .heart width 32 height32 rotate -45? Pseudo elements circles top/bottom? Standard:
.heart { position:relative; width:60px; height:54px; transform: rotate(-45deg); }
.heart::before, .heart::after { position:absolute; content:''; width:30px; height:30px; background:red; border-radius:50%; }
.heart::before { top:-15px; left:0; }
.heart::after { left:15px; top:0; } But with parent rotate -45. Simpler:
.heart { position:relative; width:48px; height:42px; }
.heart::before, ::after { content:''; position:absolute; width:24px; height:38px; background:red; border-radius:12px 12px 0 0; } before left:24? Actually two lobes: left and right: width24 height38 border-radius top left/right; rotate. Another standard:
.heart { width: 100px; height: 90px; position relative; transform: rotate(-45deg); }
.heart:before, .heart:after { content:""; position:absolute; top:0; left:0; width:50px; height:80px; background: red; border-radius:50px 50px 0 0; transform: translate(-50px,-40px); }
.heart:after { left:50px; transform: translate(-50px,-40px) rotate(90deg); ...}
Maybe easier with mask? Or use SVG? Task output html, can inline SVG heart. But pure CSS animation still. Inline SVG no network. Could use <svg class="heart"> <path fill...> </svg>. That is allowed? It is HTML/SVG, no JS. Pure CSS likely okay. But "pure CSS" maybe means no JS; inline SVG okay? Could be considered not pure CSS. Better CSS heart. But SVG easier robust. Need no external. I'd use CSS heart to adhere. But SVG can have gradient and animation. Yet title "pure CSS, no JavaScript" probably means no JS; inline SVG not CSS? Could be less pure. Use CSS shape.
CSS heart robust:
.heart {
position:relative; width:60px; height:56px; transform: rotate(-45deg) scale(1);
}
.heart, .heart::before, .heart::after { background: var(--like-off); transition? }
.heart::before, .heart::after { content:""; position:absolute; width:60px; height:60px; border-radius:50%; background:inherit; }
.heart::before { top:-30px; left:0; }
.heart::after { top:0; left:30px; }
Wait if parent square rotated -45, children circles create heart? A square of size 60 rotated 45, with circles at top-left? Standard:
.heart { position:relative; width: 80px; height:80px; background:red; transform: rotate(-45deg); }
.heart::before, .heart::after { content:""; width:80px; height:80px; background:red; border-radius:50%; position:absolute; }
.heart::before { top:-40px; left:0; }
.heart::after { left:40px; top:0; }
This gives a heart with square bottom corner. But .heart element square also red; the rotated square with circles. Need no border radius on square? fine. Size can be 40px. It looks like heart. But center point? Use .heart { width:40px;height:40px; background:red; transform: rotate(-45deg); position:relative;} ::before { top:-20px; left:0; width:40;height:40;border-radius:50%;} ::after { left:20px; top:0; width:40;height:40;border-radius:50%;} Then visual heart extends upward and right, not centered. Need translate inside. Use wrapper with flex; .heart-shape { position:relative; width:40px; height:40px; margin:20px; } maybe. To center shape, set wrapper .heart-box with padding? Simpler use emoji 🫀? But CSS heart shape okay.
Alternatively heart using radial gradients on a square: no pseudos? For animation easier? Use clip-path? CSS heart clip-path polygon? Could use:
.heart {
width:90px; height:80px;
background: var(--heart);
clip-path: path("M45 78 C..."); // path animation? no JS. Could define path with no network. But not all browsers? Chrome supports clip-path: path. However maybe overkill.
Inline SVG heart might be better visually. Is inline SVG considered pure CSS? The animation will be CSS. Since no JS, okay. But user requested pure CSS like button; I can keep heart as CSS pseudo to be safe.
Need crazy particles: We can create .particles with spans. Use nth-child to rotate. Example:
.burst span { position:absolute; left:50%; top:50%; width:10px; height:10px; border-radius:50%; background: hsl(var(--h) 100% 60%); transform: rotate(var(--angle)) translate(0) scale(.5); }
When checked: animation: pop 0.7s cubic-bezier(.2,.8,.3,1) infinite; keyframes from translate(0) opacity1 to rotate(var(--angle)) translateX(90px) scale(0) opacity0. Need nth-child set --angle. 20 spans.
Use `.burst i { animation-delay: var(--delay); }`. We can set angle/delay inline style to reduce CSS. Inline CSS variables are pure CSS/HTML. But to avoid JS only okay. We'll use inline styles? Could be allowed. But for pure CSS maybe use nth-child. Use 18 nth-of-type:
.burst span:nth-child(1){--a:0deg;--c:#ff3b7f;--dl:0s;--r:95px;}
... lots. Could be lengthy but okay. Use 16 with angles.
Can also use conic-gradient rays. E.g., .rays { position:absolute; inset:-30%; border-radius:50%; background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.9) 0 6deg, transparent 6deg 18deg); opacity:0; } checked animate spin/scale/fade. Nice.
Shock rings: .ring { position:absolute; inset:0; border-radius:50%; border:3px solid; transform: scale(0); opacity:0; } checked infinite expand with delays. Use heart wrapper maybe circle. Need rings centered around heart. Could use .button { width: 120px; height:120px; display:grid; place-items:center; } rings absolute inset0 with border-radius 50%. Good.
Button layout: Use circular main icon button with text below? Like button maybe rectangular. Crazy animation more in circle. Card includes circular like button plus label. Could have .like button as pill with heart left, text/count. But rings around circle easier. Maybe use circular heart button and below pill label "Like"? The prompt: a "like" button. Could be entire circular button with text inside? Let's design a big pill: heart and text. When liked, whole pill explodes with rings, particles from heart. That is button. Use label `.like` as pill, position relative; `.icon-wrap` contains heart/rings/particles. `.copy` contains Like/Liked and count.
Pill size: width min(300px, 78vw), height ~96px, border-radius 999px. Inside flex row align center gap 18px. `.icon-wrap` width 64 height64 position relative. `.burst` absolute centered at icon-wrap. `.ring` centered around icon wrap not pill.
Use CSS animations while checked. Need keyframes for:
- button shake/pop: .like when checked { animation: like-pop .55s cubic-bezier... infinite? If infinite every 2.2s? We want crazy loop. Use .like: checked animation: like-loop 2.8s ease-in-out infinite. That will pulse scale, tilt, background change? If one-shot maybe. For screenshot, infinite loop. But "crazy animation when you click" could loop while liked; if user unchecks stops.
Maybe on checked, animations:
.heart: heart-pop-loop 1.6s infinite; spin scale; color red.
.ring: ring-burst 1.8s infinite ease-out, delays.
.burst span: spark-burst 1.6s infinite; delays.
.rays: ray-spin 2.8s infinite linear, opacity maybe 0-0.6.
.flash: flash-pulse 1.8s infinite.
.copy liked: text-jump 1.8s infinite; unliked hidden.
.liked state background glow; card shakes subtle.
Need when clicked again (uncheck) maybe unlike animation? Could add :not(:checked) animations? But if not checked after unclicking, it might animate reset? Could have .like:not(:checked) .heart maybe neutral and no crazy. Good.
Potential issue: animations with infinite start on initial checked at load. Fine.
Need CSS variables for colors. Ensure no scrollbar: body margin 0, overflow hidden. But on small height maybe card clipped. Use min-height:100svh, display grid place-items center; padding 24px; overflow hidden. If content taller than 375? Use max sizes. Need adapt gracefully down to 375. Use responsive clamp. If height less than card, overflow hidden might clip. Could allow body overflow auto? Task says no horizontal scrollbar, vertical may be okay? "page must look right in 1280x800 and adapt gracefully down to 375px wide. No horizontal scrollbar." Vertical okay. But sandbox maybe iframe scroll? Use min-height 100svh, overflow-x hidden. Could allow vertical scroll if needed. But at 375x? If height unknown. Use compact card.
Need no external fonts. System font stack.
Need aria/accessibility? Label for input is clickable. Hidden checkbox visually. Use position absolute, opacity 0, pointer-events none? But if visually hidden but accessible, label works. Use .toggle { position:absolute; opacity:0; pointer-events:none; }. Label has tabindex? Input can be focusable with screen readers; use .toggle:focus-visible + .like outline.
Need animation on click? CSS :active? Since checkbox toggles. Also could animate when pressed (:active) immediate scale before checked? For unchecked clicking, :active on label works: .like:active { transform: scale(.96); } But if label active only while pointer down. Good. Use transitions for idle.
Could make unclicking weird: `:checked` animations. If checked initially, to click unlike, animation stops. To click like, restarts.
Need maybe use `animation-play-state`? Not.
Need count switch: use spans `.state-on` and `.state-off`; when checked, on opacity1 animation; off opacity0. But if checked initially, on visible. Use transform translate. Keyframes? Simpler:
.liked { opacity:0; transform: translateY(8px); }
.toggle:checked ~ .like .liked { opacity:1; transform: none; }
.toggle:checked ~ .like .unliked { opacity:0; transform: translateY(-8px); }
Could have counter increment by switch: Like count text `.count-on` content? Use HTML text. Good.
Could animate label content via keyframes: `.toggle:checked ~ .like .liked { animation: pop-text 1.8s infinite; }`.
Need maybe heart color: unliked gray, liked red/pink gradient. `.heart` background currentColor? Use CSS variables on .heart. Could set `--heart-color`. In :checked, .heart { color:#ff1f5a; } .heart::before/::after background currentColor? background: currentColor works. But parent square? .heart background currentColor. So .heart { color: #6b7280; }.
CSS heart shape details. Let's build robust heart inside 64x64 icon wrap. Use `.heart` width:52px;height:52px; position absolute; top:6px? Need center. Let's test mentally. Standard rotated square heart with parent square and two circles. If parent square size 40, circles size 40 at top-left and right? Let's use CSS heart from CSS Tricks:
.heart {
position: relative;
width: 52px;
height: 47.6px;
transform: rotate(-45deg);
background: currentColor;
}
.heart::before, .heart::after {
content: "";
position: absolute;
top: -23.8px;
left: 0;
width: 23.8px;
height: 39.666? Hmm not.
Alternative heart with border-radius:
.heart {
position: relative;
width: 60px;
height: 54px;
}
.heart::before, .heart::after {
position: absolute;
content: "";
left: 30px;
top: 0;
width: 30px;
height: 48px;
background: currentColor;
border-radius: 30px 30px 0 0;
transform: rotate(-45deg);
transform-origin: 0 100%;
}
.heart::after {
left: 0;
transform: rotate(45deg);
transform-origin: 100% 100%;
}
This makes heart? Need check. A known method:
.heart {
position: relative;
width: 100px;
height: 90px;
}
.heart::before, .heart::after {
content: "";
position: absolute;
top: 0;
left: 50px;
width: 50px;
height: 80px;
background: red;
border-radius: 50px 50px 0 0;
transform: translate(-50px, -40px) rotate(-45deg);
}
.heart::after {
left: 0;
transform: translate(0, -40px) rotate(45deg);
border-radius: 50px 50px 0 0;
}
But width/height of wrapper? Let's use exact scaled for 52/48. Maybe easier inline SVG. But if "pure CSS" maybe still use CSS heart from pseudo with border radius. Let's derive.
Heart made from two half-circles on top and a square diamond. Could do:
.heart {
position: relative;
width: 36px;
height: 36px;
background: currentColor;
transform: rotate(-45deg);
}
.heart::before, .heart::after {
content: '';
position: absolute;
width: 36px;
height: 36px;
border-radius: 50%;
background: currentColor;
}
.heart::before { top: -18px; left: 0; }
.heart::after { left: 18px; top: 0; }
This yields heart shape, bounding box extends top/left? Parent rotates -45 around center. Children at top-left? Let's visualize: .heart square 36. Rotate -45 -> diamond. Circles: before at top:-18 left:0 centered at top-left? In unrotated coordinate, before circle top-left corner? after circle top-right? After rotation, circles at upper left/right. The diamond's bottom point. The shape likely heart pointing down. To center visually, set .heart margin: e.g. width/height 36, margin-top 18, margin-left -? We can put inside grid and adjust with transform-origin and translate. Use `.heart-box { width:64px;height:64px; display:grid; place-items:center; } .heart { width:36px;height:36px; transform: rotate(-45deg) translate(6px, -8px)?` Need fine. Could accept slight off center? Need polished.
Maybe use CSS heart with `clip-path: polygon(...)`? Could make heart path easily:
.heart {
width: 60px; height: 54px;
background: currentColor;
clip-path: polygon(50% 100%, 0 35%, 15% 5%, 50% 25%, 85% 5%, 100% 35%);
}
This polygon heart may look jagged? Use `path()` for smooth:
clip-path: path('M50 88 C20 62 0 42 5 22 C10 2 32 2 50 22 C68 2 90 2 95 22 C100 42 80 62 50 88 Z');
width/height 100. Chrome supports path with absolute. This is CSS, no JS. Nice. Use `.heart { width:60px; height:54px; background: currentColor; clip-path: path('M30 47 C12 33 0 22 3 12 C6 1 22 1 30 14 C38 1 54 1 57 12 C60 22 48 33 30 47 Z'); }` Need coordinates within box. Let's define width 60 height 54. Path approximate heart: start bottom tip (30,50), left lobe, top middle, right lobe. Could use SVG path for heart:
M30 50
C10 34 2 24 4 14
C6 4 18 2 25 8
C28 10 30 12 30 14
C30 12 32 10 35 8
C42 2 54 4 56 14
C58 24 50 34 30 50
Z
Need coordinates 60x54. We can set `.heart { width:60px; height:54px; clip-path: path("M30 50 C10 35 1 25 3 15 C5 5 18 2 25 10 C28 13 30 16 30 18 C30 16 32 13 35 10 C42 2 55 5 57 15 C59 25 50 35 30 50 Z"); }` If height 54, bottom 50 okay. Top around 5. Need path coordinates not exceed? Fine. But `clip-path: path()` maybe in latest Chrome. It is pure CSS. This heart can be filled background currentColor. Good. Also can add gradient? background linear-gradient. With clip-path, gradient clipped. Nice. But when rotating, background gradient rotates? transform rotates shape. Good. Could set background radial-gradient? But gradient will be clipped. `background: radial-gradient(...)` maybe not rotate? If rotate, background rotates with element. Fine.
Need use `.heart` inside `.icon-wrap`. Center. Maybe transform-origin center. Use animation rotate. Great.
But if clip-path path string quotes? Use double outside or single inside? In CSS `clip-path: path("...");` okay.
Need ensure no SVG. Good.
Could have heart gradient: unliked gray, liked gradient: `background: linear-gradient(135deg, #ff2d78, #ff7aa8, #ffc5e0);` When currentColor? If gradient not currentColor, need set background for state. Use `.heart { background: #8b95a6; } .toggle:checked ~ .like .heart { background: linear-gradient(...); }`. Good.
Need animation: `.heart` rotate? Since clip-path heart points down? Actually top lobes, bottom tip. If no rotate, heart upright. We can keep transform no rotate for upright. But heart might be not perfectly centered; path coordinates 30,50 bottom, top y5. Good. `width:60px;height:54px; transform: scale(1);`. Could animate rotate for crazy: maybe 0 to 360? If heart rotates while liked, it spins. Use keyframes: scale, rotate, hue. If rotate full 360 maybe not always upright. Crazy? Yes. But liked button maybe spin heart. Could do: heart-bounce with rotate wobble ±18deg, scale, not full spin? Add rays spin. More crazy: heart does 360 flip? Could animate rotate(0) to rotate(360) every 2.4s, scale pop, maybe combined with spin. If heart is clipped, 360 looks okay. But if text copy, maybe heart spinning. Let's set heart animation: `heart-crazy 2.1s ease-in-out infinite` with keyframes: 0 scale(.9) rotate(0), 20 scale(1.25) rotate(-20deg), 40 scale(1) rotate(360deg)? That's chaotic. Could be good. But if continuous rotation, it's a bit weird. Maybe `heart-pop` with jumps and spins 360 each cycle. Need "crazy" not too ugly. Use `transform: rotateY`? CSS 3D: perspective on parent, heart flips? With clip-path, rotateY okay? Could use backface not. 3D flip heart: keyframes rotateY 0 to 360 with scale. Nice. Use `.icon-wrap { perspective: 800px; }` and `.heart { transform-style: preserve-3d? }` not needed. Heart flips horizontally. But gradient only front; when 180 it appears mirrored? Still heart symmetrical. Fine. Could do rotateZ and rotateY.
Crazy elements:
- Button tilt shake: `.toggle:checked ~ .like { animation: like-dance 1.8s infinite; }`
- Background hue shift: keyframes filter hue-rotate? Could use box-shadow.
- `filter: hue-rotate(0) saturate(1)`; animate saturate.
- Maybe entire card: `.toggle:checked ~ .like` can't target parent card. Could wrap input and card as siblings? Use input at top of card, label inside. But target card? Could put input outside card and card as sibling: `input:checked ~ .card { animation shake }`. Structure: body main .card with input and label and maybe `.card`? We can place input inside `.stage` before `.card`, label inside `.card`. But label `for=input` works outside too. For animations: `.toggle:checked ~ .card` target. Need label inside card. So structure:
<main class="card">
<input id="like" ...>
<header ...> maybe sibling? But if header before label? CSS can't select input's preceding siblings. We need input first child before everything: `.card > input.toggle`, then `.content` with header/label. Then `.toggle:checked ~ .content .heart` etc. Also `.toggle:checked ~ .content` can target header/card effects.
Could use `.card` as wrapper, but to shake card use input sibling content. Let's do:
<main class="card">
<input ... checked>
<div class="ui">
<header>...</header>
<div class="like-zone"> label ... </div>
<footer hint>...</footer>
</div>
</main>
Then `.toggle:checked ~ .ui { animation: card-shake infinite }`. Good. Need label inside .ui. Input visually hidden.
But if checked initially, card-shake may be too much. Could subtle.
Need ensure first paint: Title maybe "Click or tap to like". If checked initial, it's Liked. But hint can say `The demo is already showing the effect; click to toggle.` Maybe.
Could also make an auto-hint cursor pulsing near button without JS. Use CSS animation on a fake cursor arrow (clip-path polygon). It moves toward button repeatedly. Nice, but screenshot no interaction. We can include `.cursor-hint` positioned near heart, animated to tap. Pure CSS. It helps show action. If input checked initial, animation already. Add a pointer icon? Use CSS triangle/cursor shape. Or emoji? Could be not pure? Use CSS pseudo shape. But not necessary.
Need maybe `input:checked` can be toggled by label; if we also include a hidden reset? No JS.
Could use CSS `:focus` to animate? Not necessary.
Need output only code block. Need final answer code. Need ensure no errors. Let's design CSS carefully.
Potential issue: `clip-path: path()` requires `path()` with string. In Chrome okay. But if path coordinates and width mismatch. Need heart visible. Could maybe use simple heart with two circles and diamond more compatible? But clip-path path is modern. Task latest Chrome, okay.
Maybe use an inline SVG heart but animate with CSS. User specifically pure CSS. Let's keep CSS. Could also add `@supports not (clip-path: path(...))` fallback with emoji? Not needed but nice. Use `background: currentColor` clip. Add filter drop-shadow to heart.
Particles: Use `<i>` with no content. CSS animation only when `.toggle:checked ~ .ui .burst i`. Each i needs variables. Instead of many nth-child, use inline style `style="--a:0deg;--d:0s;--r:90px;--c:#ff5ea8"` 20. Is inline style allowed? Yes, no JS. Could be seen as CSS. To avoid huge nth-child CSS, use inline styles on spans. But "pure CSS" might allow HTML attributes. Use CSS variables inline. Need no JS. The file remains CSS animation. I'll use inline `style="--a:...;--d:...;--r:...;--c:..."` for 18 particles, simpler. Need no external. Ensure no horizontal from particles? They are inside overflow visible but within viewport. Set `.stage overflow:hidden` to clip. But if animation translates outside card, body overflow hidden prevents scroll.
Rays: `.rays` with repeating-conic-gradient. Set `mask-image: radial-gradient(closest-side, black 40%, transparent 70%)` to make rays fade outward. `-webkit-mask-image` maybe Chrome prefix? Latest supports mask. Use `mask: radial-gradient(...)`. Good. Animation spin + opacity.
Flash: `.flash` absolute inset -80% with radial gradient white; opacity animation.
Glow: `.glow` blurred gradient behind heart.
Button styling: `.like` as label, display inline-flex align center gap, padding, border-radius 999px, background gradient, border. Use backdrop-filter? Could. But ensure no issue. Use `box-shadow`.
Text copy: Use `<span class="copy"><span class="word off">Like</span><span class="word on">Loved</span></span>` maybe. Count `<span class="num off">1.2k</span><span class="num on">1.3k</span>`. When checked, on appears. Animation pop.
Need CSS-only state switch: `.toggle:checked ~ .ui .word.on { opacity:1; transform:... }` etc. Default on hidden.
Need focus styles: `.toggle:focus-visible ~ .ui .like { outline... }`.
Need animation delays for rings/particles. Use variables and keyframes.
Keyframes details:
@keyframes ring-burst {
0% { transform: translate(-50%, -50%) scale(.2); opacity:0; }
15% { opacity:1; }
100% { transform: translate(-50%, -50%) scale(2.6); opacity:0; }
}
Rings absolute center in icon-wrap: left:50%; top:50%; width:60%; height:60%; border-radius:50%; border:3px solid var(--ring-color). transform uses translate to center. Need ensure ring stays square. Use width:70px height70px, translate.
Particles:
@keyframes spark-burst {
0% { transform: translate(-50%, -50%) rotate(var(--a)) translateY(0) scale(.2); opacity:0; }
12% { opacity:1; }
60% { transform: translate(-50%, -50%) rotate(var(--a)) translateY(calc(var(--r) * -1)) scale(1); opacity:.95; }
100% { transform: translate(-50%, -50%) rotate(var(--a)) translateY(calc(var(--r) * -1.35)) scale(.15); opacity:0; }
}
Actually rotate then translateY negative moves outward along angle? If rotate(a) then translateY(-r) rotates upward? The transform order: rotate angle applied after translate center; translateY negative along rotated y axis. Fine. If angle 0 moves up. Use angles 0..330. Good.
Use `.burst i { position:absolute; left:50%; top:50%; width:8px;height:8px;border-radius:999px;background:var(--c); transform: translate(-50%,-50%) scale(.2); opacity:0; }` checked animate.
Ray spin:
.rays { position:absolute; width:180px; height:180px; left:50%; top:50%; transform: translate(-50%,-50%) scale(0); border-radius:50%; background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.85) 0 7deg, transparent 7deg 18deg); opacity:0; -webkit-mask-image: radial-gradient(circle, black 12%, transparent 68%); mask-image: ...; }
Checked animation `ray-pop 1.8s infinite`: 0 scale(0) opacity 0 rotate(0), 20 scale(.7) opacity .6, 100 scale(1.6) opacity 0 rotate(90deg). Could use rotate.
Glow:
.glow { width:140px;height:140px; border-radius:50%; background: radial-gradient(circle, rgba(255,60,120,.55), rgba(255,60,120,0) 60%); filter blur; opacity:0; transform scale(.6); } checked animate glow-pulse.
Heart:
.heart { width:54px;height:50px; background:#8593a8; clip-path: path(...); transition: background .35s, filter .35s; }
Checked: background linear-gradient; filter drop-shadow. Animation heart-crazy. Use keyframes:
@keyframes heart-crazy {
0% { transform: rotate(0deg) scale(1); filter hue-rotate(0) saturate(1); }
18% { transform: rotate(-16deg) scale(1.18); }
36% { transform: rotateY(180deg) scale(1.02); }
54% { transform: rotateY(360deg) rotate(10deg) scale(1.22); }
72% { transform: rotate(0) scale(.95); }
100% { transform: rotate(0) scale(1); }
}
But transform with rotateY and rotateZ? In CSS, `transform: rotateY(180deg) scale(1.02);` order okay. Need perspective for rotateY. `.heart` inside `.icon-wrap` with `perspective: 900px`? But perspective on parent. However if `.heart` animates transform, perspective on `.heart`? Use `.heart { transform-style: preserve-3d? }` not necessary. Parent `.icon-wrap { perspective: 700px; }`. Keyframe rotateY makes 3D.
Filter hue-rotate may conflict with drop-shadow? Set drop-shadow separately? Could animate `filter: drop-shadow(...) hue-rotate(...)`.
Maybe simpler: heart pulses and rotates Z:
@keyframes heart-crazy {
0% { transform: translateZ(0) scale(.96) rotate(0); }
15% { transform: scale(1.25) rotate(-25deg); }
30% { transform: scale(.85) rotate(25deg); }
45% { transform: scale(1.4) rotate(360deg); }
60% { transform: scale(1) rotate(0); }
100% { transform: scale(1) rotate(0); }
}
But rotate 360 from 0 to? At 45 full spin. Could be crazy. Need heart not too jumpy. Maybe use infinite 2.2s.
Button dance:
@keyframes like-dance {
0%,100% { transform: translateY(0) rotate(0); }
25% { transform: translateY(-4px) rotate(-3deg); }
50% { transform: translateY(2px) rotate(3deg); scale(1.03); }
75% { transform: translateY(-2px) rotate(-2deg); }
}
But `.like` is flex label; applying animation transform could interfere with active transitions. Fine.
Card shake:
@keyframes card-shake { subtle }
Text pop:
@keyframes text-pop { 0 scale 1, 15 scale 1.08, 100 scale 1 }.
Maybe add confetti small squares in background? Could be nice. But no need.
Need ensure animations with toggling off/on restart. If `.toggle:not(:checked)` no animation. When unchecking, elements revert to hidden via animation removal. That's okay. If checking again, animations restart. But if `.toggle` checked initially, animation starts. If user clicks label, input becomes unchecked. But the checkbox toggles state; label not `<button>`, still accessible. Need maybe keyboard: If user clicks iframe then focuses input? The hidden input can be focused? Use `.toggle` visually hidden but not display none; can be focused. Press space toggles. Need `.toggle` accessible: position absolute with size 1px? If pointer-events none but focusable? Use opacity:0; position absolute; width:1px; height:1px; margin:-1px; border:0; outline:none; but it can receive focus? Yes if not display none. But pointer events none maybe doesn't matter label click. For keyboard focus, use `.toggle:focus-visible ~ .ui .like { outline: ... }`. Good.
Need avoid alert. Good.
Potential issue: Since input initially checked, if user wants to see click from unliked, they can click to unlike. Fine. If screenshot at 3s shows animation. Need maybe set animation delay so at 3s mid-animation. With infinite loops starting at 0, at 3s maybe mid. Good.
Potential performance: Many filters blur etc. Should be okay.
Need no JS text? Could include `<noscript>`? Not needed.
Need maybe CSS-only counter increment using CSS counters? Could animate count number? Not necessary.
Let's compose file.
HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS-only Crazy Like Button</title>
<style>...</style>
</head>
<body>
<main class="card">
<input id="like" class="toggle" type="checkbox" checked aria-label="Like">
<div class="ui">
<header class="header">
<span class="eyebrow">PURE CSS · NO JS</span>
<h1>Crazy Like Button</h1>
<p>Click or tap the button to toggle the explosion. Demo starts in the liked state so the animation is visible.</p>
</header>
<div class="like-zone">
<label for="like" class="like">
<span class="icon-wrap" aria-hidden="true">
<span class="rays"></span>
<span class="glow"></span>
<span class="ring r1"></span>
<span class="ring r2"></span>
<span class="ring r3"></span>
<span class="burst">
<i style="--a:0deg;--r:82px;--d:0s;--c:#ff4d8f"></i>
...
</span>
<span class="heart"></span>
<span class="flash"></span>
</span>
<span class="copy">
<span class="line">
<span class="word off">Like</span>
<span class="word on">Loved</span>
</span>
<span class="line count">
<span class="num off">1.2k likes</span>
<span class="num on">1.3k likes</span>
</span>
</span>
<span class="shimmer"></span>
</label>
</div>
<footer class="footer">
<span class="hint"><span class="cursor"></span> pointer-events: CSS only</span>
<span class="status"><span class="dot"></span> animations loop while liked</span>
</footer>
</div>
</main>
</body>
</html>
Need cursor hint maybe animated. `.cursor` CSS shape arrow: width 16 height 16? Could use polygon clip-path of cursor. Use border? Could be unnecessary; maybe footer hint. But if use `.cursor`, pure CSS. Let's design simple pointer icon via clip-path polygon: `width:18px;height:24px; background:white; border:2px solid #21253a; clip-path: polygon(0 0, 100% 55%, 55% 58%, 72% 100%, 40% 86%, 28% 100%, 16% 93%, 28% 78%, 0 60%)`? Might be messy. Could use emoji? No JS but emoji okay? To avoid external, unicode. But pure CSS? Text is HTML. Use `<span class="cursor" aria-hidden="true">👆</span>`? Emojis render maybe. Could add animation. But if pure CSS, text emoji okay? Hmm.
Maybe remove fake cursor to reduce complexity.
Footer hints can be static. Screenshot will see animated button and text.
Need particles variables: 16-20. Let's generate 18. Angles 0,20,...340? Need delays varied. Radii 70-110. Colors pink, yellow, cyan, violet, white, red. Inline styles long but okay.
CSS:
* { box-sizing:border-box }
html, body { height:100%; }
body { margin:0; font-family: system-ui, ...; color: #e8ecff; background: radial-gradient(...); min-height:100svh; display:grid; place-items:center; overflow-x:hidden; }
.card { width:min(94vw, 760px); padding:clamp(16px, 4vw, 34px); background: rgba(18,22,45,.72); border:1px solid rgba(255,255,255,.12); border-radius:28px; box-shadow: ...; overflow:hidden; position:relative; }
Maybe use backdrop-filter saturate? Could but performance. Add `.ui` grid.
Need input hidden: `.toggle { position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; left:-9999px; }` But if left -9999, focus scroll? Could cause horizontal? Body overflow hidden. Use `appearance:none`? Better:
.toggle { position:absolute; width:1px; height:1px; margin:-1px; padding:0; border:0; opacity:0; clip-path: circle(0%); pointer-events:none; }
But focus? clip-path maybe prevents visual. Fine.
But if label inside `.ui`, target `.toggle:checked ~ .ui .heart` works. Good.
Header typography:
h1 font-size clamp(1.4rem, 4vw, 2.35rem); margin:8px 0; letter-spacing.
p max-width 52ch; color rgba.
eyebrow pill.
Like button:
.like-zone { display:flex; justify-content:center; margin-top: clamp(18px, 5vw, 30px); }
.like { position:relative; display:inline-flex; align-items:center; gap:18px; padding: 16px 28px 16px 20px; border-radius: 999px; background: linear-gradient(145deg, rgba(38,44,85,.95), rgba(20,24,50,.95)); border:1px solid rgba(255,255,255,.15); box-shadow: 0 18px 50px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.15); cursor:pointer; user-select:none; transition: transform .15s, border-color .25s, background .25s, box-shadow .25s; min-height:96px; overflow:visible; }
.like:hover { transform: translateY(-2px); box-shadow... }
.like:active { transform: scale(.97); }
Toggle checked .like: background gradient with pink; border-color #ff5c9f; box-shadow glow.
.icon-wrap { position:relative; width:64px; height:64px; display:grid; place-items:center; perspective:800px; flex:0 0 auto; }
.heart { width:54px; height:50px; background: #92a0b5; clip-path: path(...); filter: drop-shadow(0 4px 10px rgba(0,0,0,.25)); transition: background .3s, filter .3s; position:relative; z-index:5; }
Checked heart background linear-gradient. filter drop-shadow.
Need path coordinate: Let's create path 60x54. Maybe:
M30 50
C15 40, 3 32, 3 20
C3 8, 14 4, 22 10
C26 13, 30 17, 30 18
C30 17, 34 13, 38 10
C46 4, 57 8, 57 20
C57 32, 45 40, 30 50
Z
In path, C syntax: `C x1 y1, x2 y2, x y`? CSS path uses SVG path grammar: C x1 y1 x2 y2 x y. Need commas optional. Could be long. Let's define:
clip-path: path("M30 50 C15 40 3 32 3 20 C3 8 14 4 22 10 C26 13 30 17 30 18 C30 17 34 13 38 10 C46 4 57 8 57 20 C57 32 45 40 30 50 Z");
Within width 60 height 54. Coordinates x 0..60, y 0..54. Good. But top y 4, bottom 50. Shape centered in 60x54; width:54, height:50? If width 54 height 50 but path coordinates assume 60x54? Need scale? If `clip-path: path()` coordinates are absolute in element's coordinate system? Path uses `path()` in user units; for element with size 54x50, path coordinates 60x54 will be clipped not scaled? Actually path coordinate system is px from top-left, not scaled by element size. If element width 54, path extends to 57, may clip. Set `.heart { width:60px; height:54px; }` to match path. Good. Icon-wrap 64. Fine.
`.copy` flex column. `.word.on`, `.num.on` absolute? Need switch without layout jump. Could make each line position relative and stack states absolute. `.line { position:relative; display:block; height:1.25em; } .word,.num { position:absolute; inset:0; }`. Off and on same size. Text left align. Use font-weight. `word.on` initial opacity 0 transform translateY(8px); `word.off` opacity1. When checked, on opacity1; off 0. Add animation to on. Good.
Line height: maybe 1.1rem; `.copy` text align left.
`.count { color rgba; font-size .85rem; }`.
`.shimmer`: absolute over button, background linear-gradient 110deg transparent 30% white 50% transparent 70%, transform translateX(-120%), opacity maybe .2; on checked animate slide. Good.
`.like { overflow:hidden }`? But rings/particles outside button need overflow visible. If shimmer inside button and overflow hidden for shimmer? Could set shimmer only inside and mask? Maybe use `.shimmer` with overflow hidden not needed if animation translate outside and pointer-events none. If overflow visible, shimmer may overflow. But button radius? Set `.shimmer { border-radius: inherit; overflow:hidden? }` not. Use `.like` overflow:hidden would clip bursts. So don't overflow hidden. To shimmer only inside, set `.shimmer { left: -100%; }` and use `clip-path: inset(0 round 999px)`? Or put shimmer with opacity and width 140%, transform translate from -100% to 100; overflow may go outside. Since `.like` overflow hidden would clip burst. We can remove shimmer or keep outside? If burst outside, overflow visible. Shimmer sliding across entire card could be okay. But maybe outside button visible. Not problem if subtle. Alternatively use `.like` not overflow hidden, shimmer absolute inset with border-radius and transform; it may spill slightly but okay? Better not use shimmer.
Need flash inside icon-wrap, absolute inset -50%, pointer-events none, mix-blend? Use `mix-blend-mode: screen`; background radial white. On checked animate. Good.
Need rings and burst z-index relative to heart. `z-index:3` etc. Heart z-index 5.
Keyframes: Need only run when checked. Use `.toggle:checked ~ .ui .heart { animation: heart-crazy 2.05s ease-in-out infinite; }` etc.
Potential issue: If animations infinite and `transition` on `.like` transform, animation overrides transform. Good.
Card shake while checked: `.toggle:checked ~ .ui { animation: ui-wobble 2.4s ease-in-out infinite; }` But `.ui` contains text, wobble might be too much. Use `.card` cannot be target because input inside card before `.ui`; input sibling `.ui` only. If we want card shake, set `.toggle:checked ~ .ui` transform? That animates entire inner content, card border remains. Could be okay. Or place card outside input? Structure body: `<input>` then `<main class="card">` then label inside. But label for input works if input is previous sibling of card. Then `.toggle:checked ~ .card { animation shake }`. Need focus styles. Let's use body direct child input then card. That may be easier. But need card sibling. Structure:
<body>
<input id="like" class="toggle" type="checkbox" checked>
<main class="card">
<div class="ui">
label...
</div>
</main>
But the label must be descendant of `.card`, and `.toggle:checked ~ .card .like` works. But `.card` not `.ui`. Good. However body grid place-items center with input hidden. Need card as child. But if input first child and card second, body grid might place input? It's hidden absolute. Fine.
For focus: `.toggle:focus-visible ~ .card .like`. Good.
Header can be in card. Let's do that. Need body display grid place-items center; input absolute hidden. Card position relative. Good.
CSS selectors:
.toggle { position:absolute; opacity:0; pointer-events:none; left:50%; top:50%; width:1px; height:1px; }
Card:
.toggle:checked ~ .card { animation: card-shake 2.6s ease-in-out infinite; }
.toggle:checked ~ .card .like { background..., border...; animation: button-dance... }
.toggle:checked ~ .card .heart { ... }
Need `.toggle:checked ~ .card .burst i` etc. Good.
But if card animation transform, child transforms? Parent transform creates containing block but okay.
Potential issue: `.card` shake could move fixed viewport causing overflow? Body overflow hidden. Subtle enough.
Need ensure `input:checked ~ .card` target; input is direct sibling. Good.
Need label `for` matches id.
Accessibility: The input is not inside label but associated. Good.
Now keyframes:
@keyframes card-shake { 0%,100% { transform: translate3d(0,0,0) rotate(0); } 12% { transform: translate3d(-3px,1px,0) rotate(-.4deg); } 28% { transform: translate3d(4px,-2px,0) rotate(.6deg); } 52% { transform: translate3d(-2px,2px,0) rotate(-.5deg); } 78% { transform: translate3d(3px,-1px,0) rotate(.35deg); } }
@keyframes button-dance { 0%,100% { transform: scale(1) rotate(0); } 18% { transform: scale(1.035) rotate(-1.8deg); } 36% { transform: scale(.985) rotate(1.6deg); } 62% { transform: scale(1.025) rotate(-1deg); } }
@keyframes heart-crazy {
0% { transform: scale(.94) rotate(-3deg); }
16% { transform: scale(1.18) rotate(-18deg); }
30% { transform: scale(.86) rotate(24deg); }
44% { transform: scale(1.22) rotate(0deg); }
58% { transform: scale(1) rotateY(180deg); }
72% { transform: scale(1.1) rotateY(360deg); }
100% { transform: scale(.94) rotate(0); }
}
But combining rotateY and scale; at 72 rotateY 360, heart visible. Might be too crazy but okay. If rotateY 360 and gradient mirrored? fine. Need perspective on icon-wrap; but if heart has clip-path, rotateY with no preserve-3d? It will render. At 90 deg invisible? Could appear flip. Maybe set keyframes with rotate3d to avoid disappearing. Better rotateZ and slight rotateY:
0% rotateX(0) rotateY(0) scale(.96)
25% rotateZ(-24deg) scale(1.22) rotateY(18deg)
45% rotateZ(30deg) scale(.88) rotateY(-18deg)
65% rotateZ(360deg) scale(1.34) rotateY(0deg)
100% rotateZ(0) scale(1)
But rotating 360 while rotateY small. Good.
Could use `transform: rotate(0) scale(1)`; keyframe 45 360deg. Need avoid abrupt? It rotates. Let's define:
@keyframes heart-crazy {
0% { transform: rotate(-4deg) scale(.96); }
18% { transform: rotate(18deg) scale(1.2); }
34% { transform: rotate(-22deg) scale(.9); }
52% { transform: rotate(360deg) scale(1.32); }
68% { transform: rotate(360deg) scale(1.02); }
100% { transform: rotate(360deg) scale(.96); }
}
But ending at 360 same as 0. This spins each cycle. Good. Add perspective? Not needed. Maybe rotateY tilt:
`transform: rotate(18deg) rotateY(20deg) scale(1.2)`. Need preserve? okay.
Let's make heart bounce/spin:
@keyframes heart-crazy {
0% { transform: rotate(0deg) scale(1); filter: drop-shadow(0 3px 12px rgba(255,45,120,.45)) hue-rotate(0deg); }
15% { transform: rotate(-18deg) scale(1.18); }
30% { transform: rotate(22deg) scale(.92); }
45% { transform: rotate(360deg) scale(1.32); }
60% { transform: rotate(360deg) scale(1.08); }
75% { transform: rotate(390deg) scale(1.02); }
100% { transform: rotate(360deg) scale(1); }
}
At 75 beyond 360. Good.
Need filter keyframes if default? If set filter only 0/100? We can animate filter separately? Use `filter` in keyframes. But background checked state. Fine. However `.heart` default has filter. Animation filter overrides. Good.
@keyframes ring-burst {
0% { transform: translate(-50%,-50%) scale(.15); opacity:0; }
15% { opacity:1; }
70% { opacity:.35; }
100% { transform: translate(-50%,-50%) scale(2.65); opacity:0; }
}
Rings have width 48px height48px? Need expand enough. Use `--s`? We'll set width:44px; height:44px; border-width 3px. Delays .1 .35 .7.
@keyframes spark-burst {
0% { transform: translate(-50%,-50%) rotate(var(--a)) translateY(0) scale(.1); opacity:0; }
12% { opacity:1; }
55% { transform: translate(-50%,-50%) rotate(var(--a)) translateY(calc(var(--r) * -0.78)) scale(1.1); opacity:1; }
100% { transform: translate(-50%,-50%) rotate(var(--a)) translateY(calc(var(--r) * -1.15)) scale(.1); opacity:0; }
}
Note rotate then translateY moves outward along rotated -Y axis. Good.
@keyframes ray-pop {
0% { transform: translate(-50%,-50%) scale(.1) rotate(0); opacity:0; }
18% { opacity:.75; }
70% { opacity:.25; }
100% { transform: translate(-50%,-50%) scale(1.9) rotate(140deg); opacity:0; }
}
@keyframes glow-pulse {
0%,100% { transform: scale(.75); opacity:.22; filter: blur(18px); }
35% { transform: scale(1.35); opacity:.55; filter: blur(26px); }
}
Need filter blur always? Use keyframes with blur.
@keyframes flash-pop {
0% { transform: translate(-50%,-50%) scale(.2); opacity:0; }
10% { opacity:.9; }
100% { transform: translate(-50%,-50%) scale(2.8); opacity:0; }
}
@keyframes text-pop {
0%,100% { transform: translateY(0) scale(1); }
15% { transform: translateY(-3px) scale(1.07); }
35% { transform: translateY(1px) scale(.98); }
}
State switch opacity: Could just set `.toggle:checked ~ .card .word.on` opacity and animation. Need transitions? Good.
`.word.on` hidden default: `opacity:0; transform: translateY(7px);` When checked: `opacity:1; transform:none; animation:text-pop 1.85s ... infinite;` `.word.off` default opacity 1. When checked: `opacity:0; transform: translateY(-7px);`. Similarly num.
Need `.line` height to accommodate. Use display grid? `.line { position:relative; }`. Text absolute inset 0; width. Good.
Need `.like` layout: icon-wrap then copy. Use flex. Copy width maybe 110. On small screens, text size clamp. Use `.copy { min-width:105px; }`.
Need `.icon-wrap` centered. If animation transforms heart, rings may be positioned relative. Good.
Particles inline styles: Need 20. Let's choose:
<i style="--a:0deg;--r:78px;--d:0s;--c:#ff6fae"></i>
<i style="--a:22deg;--r:95px;--d:.06s;--c:#ffd166"></i>
... 16? Use 18 angles.
Delays stagger .0 to .22.
Radii: 72,88,102,96.
Colors: #ff6fae,#ff4d6d,#ffca3a,#fff,#7ee8fa,#b18cff,#ff85c1,#51e5ff,#ffe066,#a0ffae.
Could also have small hearts? Use `i` with heart clip? Could set `.burst i` shape random? Maybe `clip-path` square? To be more crazy, alternate heart and circle. Use nth-child odd? Since inline, CSS can style `.burst i:nth-child(odd) { border-radius:2px; transform? }` But keyframe transform overrides. Could set width/height, border-radius: 999px for circles, square for even. `:nth-child(even) { border-radius:0; rotate:45deg? }` not. Could set `clip-path: path('...')`? Too many. But circles and tiny squares okay: use `.burst i:nth-child(even) { border-radius:2px; }` but keyframes use scale only. Good.
Need `.burst i` default hidden: `opacity:0; transform: translate(-50%,-50%) scale(.1);` checked animation. Since animation uses transform, no issue. If not checked, hidden. Good.
Need `.rings` default hidden? `.ring { opacity:0; transform: translate(-50%,-50%) scale(.2); }` checked animation. Good.
Need `.rays` default hidden. `.flash` default hidden. `.glow` default subtle maybe opacity .15. Checked pulse.
Hover before checked? If checked initial no. But if unchecked, hover could show neutral pulse. Add `.card .like:hover .heart { transform: scale(1.06); }` But if checked animation overrides. Fine. Need maybe hover changes heart gray to pink outline. Good.
Focus outline: `.toggle:focus-visible ~ .card .like { outline: 3px solid #7ee8fa; outline-offset: 4px; }`.
Need no JavaScript at all. Good.
Let's craft CSS in detail.
Potential issue: `overflow:hidden` on `.card` clips bursts outside card. Better card `overflow: visible`? But if card has background border radius, elements inside can overflow. But body overflow hidden. If card overflow visible, okay. But `.card` background with border-radius; children can overflow. Maybe set `.card { overflow: hidden; }` would clip particles outside card, undesirable. Keep overflow: visible. But header shadows maybe okay. If card has box-shadow, no issue. Use no overflow hidden. If using backdrop-filter on card? okay.
Need body overflow-x hidden. If animation transforms card rotate, no horizontal scrollbar due overflow-x hidden. Use `overflow: hidden` on html/body? Vertical? Could set `html,body{height:100%; overflow:hidden;}` to prevent any scroll. But if viewport 375x600 and card taller? Could clip. Maybe use `body { min-height:100svh; overflow-x:hidden; overflow-y:auto; }`. Horizontal hidden. But if body overflow-y auto and card transform rotate might not horizontal. Fine.
Need ensure no horizontal scrollbar from card width min(94vw, 720px). Good.
Potential issue: `input` hidden left/top absolute in body may affect grid? Use `position:fixed`? Let's set `.toggle { position:absolute; inset:0 auto auto 0; width:1px;height:1px; opacity:0; pointer-events:none; }` But absolute relative to body? If body has `position:relative`. Set body position relative. Fine. Or `clip:rect(0,0,0,0)`. Use `clip-path: inset(50%)` to hide. But if absolute, may not affect layout. Good.
Maybe use `<input>` inside label? No, for checked siblings we need input before card. If input is before card, label for works. But if user clicks label, toggles. If keyboard focus on input, not visible? But input is first body child, focus-visible works. Good.
Need ensure initial state checked. If user wants to see click animation from off, they can click. But with checked, the heart is liked. The prompt maybe "when you click it"; initial liked might be confusing. Could include "demo starts liked". Good.
Could also add two labels? Not needed.
Let's write final HTML.
Need test mentally no syntax errors.
CSS variables:
:root {
--bg1:#070a18; --bg2:#171447; --bg3:#ff2d78; --text:#eef3ff; --muted:#a9b3d1;
--off:#8b98b5; --like:#ff2d78;
}
body background radial-gradient(circle at 20% 10%, #2a174d 0, transparent 40%), radial-gradient(circle at 80% 15%, #093055 0, transparent 45%), linear-gradient(#050714,#0a0d24 50%, #10051e); maybe. Use `background-attachment: fixed`? not necessary.
.card background: rgba(15,18,40,.72), border. Could add `box-shadow: 0 30px 80px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.1)`.
.header h1: `background: linear-gradient(90deg,#fff,#ffd7ee,#aeeaff); -webkit-background-clip:text; color:transparent;` Good. But if background-clip not? fine.
.eyebrow: pill border pink.
.like: background transition. Checked `.toggle:checked ~ .card .like { background: linear-gradient(135deg,#ff2d78,#ff75b8 35%,#6a1b4d 100%); color:white; border-color: rgba(255,255,255,.3); box-shadow: 0 18px 55px rgba(255,45,120,.45), inset...; }`
Text color? `.copy` color white when checked. Use `.word` color. Good.
But if `.like` checked animation `button-dance` transform, active transition. Fine.
`.icon-wrap`: width 68 height 68, perspective 800.
`.heart`: width:58px; height:52px; clip-path path using coordinates maybe adjust to 58/52. Simpler define with width:60;height:54. Use path coords 60x54. Icon-wrap 68. Good.
`.heart {
background:#8b98b5;
clip-path: path("M30 50 C15 40 3 32 3 20 C3 8 14 4 22 10 C26 13 30 17 30 18 C30 17 34 13 38 10 C46 4 57 8 57 20 C57 32 45 40 30 50 Z");
filter: drop-shadow(0 2px 8px rgba(0,0,0,.3));
transition: background .3s, filter .3s;
}
`
Need maybe path top lobes too high? It starts bottom tip 30,50. Top center 30,18. Good. But path may not close? It has two cubic curves from top center to right lobe and back to bottom. Good. Could look heart. If not, acceptable.
Maybe use background `conic-gradient`? no.
`.ring` width 54 height54 left top 50. Use `border:3px solid rgba(255,120,170,.9); box-shadow:0 0 20px;` r1 pink, r2 yellow? Use different colors. `.ring.r1 { border-color: rgba(255,111,174,.95); }` r2 rgba(255,209,102,.9), r3 rgba(126,232,250,.9). Delays in checked: r1 .12s, r2 .42s, r3 .72s.
`.rays` width:170;height:170. `.rays { position:absolute; left:50%; top:50%; width:170px; height:170px; border-radius:50%; transform: translate(-50%,-50%) scale(.1); opacity:0; background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.95) 0deg 6deg, transparent 6deg 17deg); -webkit-mask-image: radial-gradient(circle, rgba(0,0,0,1) 16%, rgba(0,0,0,0) 62%); mask-image: radial-gradient(circle, rgba(0,0,0,1) 16%, rgba(0,0,0,0) 62%); }`
Checked: `animation: ray-pop 1.85s cubic-bezier(.16,.84,.26,1) infinite;` Maybe `animation-delay:.05`.
`.glow` width130 height130 background radial-gradient(circle, rgba(255,70,130,.8), transparent 65%); border-radius:50%; filter blur(16px); opacity:.25; transform: scale(.8). Checked animation glow-pulse.
`.flash` width 120 height120 background radial-gradient(circle, white 0, rgba(255,255,255,.5) 22%, transparent 65%); mix-blend:screen; opacity 0; transform scale .2; checked animation flash-pop duration .55s? For loop maybe delay .1, duration 1.85? If flash every cycle, use same as heart with 1.85. Or shorter but infinite with delay. If flash duration .55 infinite, it will flash multiple times within cycles? Better `animation: flash-pop .85s ease-out infinite;`. Good.
`.burst i` default hidden. For checked: `animation: spark-burst 1.5s ease-out var(--d) infinite;` Need delay and infinite? If animation shorthand with delay after? `animation: spark-burst 1.5s ease-out var(--d) infinite backwards;` The order: name duration timing-function delay iteration-count. Use `animation: spark-burst 1.5s ease-out var(--d) infinite;` But CSS animation shorthand order can be flexible? Typically name duration timing-function delay iteration-count direction fill-mode play-state. `var(--d)` in delay position okay if name, duration, timing-function, delay. We can write longhand to avoid confusion:
`.toggle:checked ~ .card .burst i { animation-name: spark-burst; animation-duration: 1.5s; animation-timing-function: ease-out; animation-delay: var(--d); animation-iteration-count: infinite; }`
Good. Similarly rings:
`.toggle:checked ~ .card .ring { animation-name: ring-burst; ... }`
Delays using class:
`.r1{--delay:.12s}`? Could set variables and use shorthand with var. Simpler set delays via class.
Need `.burst i { transform-origin:center; }` Good.
Need `.like` pointer-events? label works. But input hidden pointer-events none. `.toggle:checked ~ .card .like` etc.
Need maybe `prefers-reduced-motion`: Should reduce? Task wants animation. But we can include media query to reduce infinite but keep on load? Might be good. But if reduce motion, screenshot? Not. Could include: `@media (prefers-reduced-motion: reduce) { .toggle:checked ~ .card .heart, ... { animation-iteration-count: 1; } }` But not necessary. It may show static if reduced. But in standard Chrome not reduced. Could add but keep first animation. If reduced motion at 3s? No. Better not, or set one-shot. The evaluation uses default likely. Could include `prefers-reduced-motion` to be nice but it might disable crazy loop if environment has reduce? Usually not. Add only to shorten? Could be safe.
Need ensure CSS no errors: `clip-path: path(...)` quotes inside style. Good.
Potential issue: `mask-image` with `-webkit-mask-image` may not need prefix. Use both.
Potential issue: `-webkit-background-clip:text; color:transparent;` works Chrome. Good.
Potential issue: label text absolute overlapping might not align? Use `.copy { display:grid; gap:2px; min-width:106px; } .line { position:relative; display:block; } .word, .num { position:absolute; inset:0; white-space:nowrap; }` Since `.line` has no height unless contains text? Absolute children don't set height. Need `.line` define height using line-height. If line has absolute children, height 0. Could instead keep both in grid: `.copy { display:grid; gap:4px; } .line { position:relative; line-height:1.15; min-height:1.15em; }` Good. `.word.off`, `.word.on` absolutely fill. They don't affect layout because parent min-height. Count parent min-height. Good. Need text sizes. `.word { font-size: clamp(1.25rem,3.5vw,1.6rem); font-weight:900; letter-spacing:.01em; } .num { font-size: .9rem; }`.
Potential issue: `.word` absolute inset 0 with text vertical center? Use display flex align center? If absolute, line-height can vertically center. But text baseline top? Set `.word, .num { position:absolute; left:0; top:0; }` and line-height matching. If parent min-height equals line-height, text at top. To vertically center within line if line-height set, use `display:block`. Good.
Need `.copy` color white maybe.
Could animate count switch. `.num.on` text "1.3k likes" maybe width bigger? `.line.count { min-width:90px; }`. Off and on may differ length; absolute left 0. Good.
Could use CSS counter to increment but not necessary.
Need `.like` width not shrink text. `.copy { text-align:left; }`.
Potential issue: `.toggle:checked ~ .card .word.on { transform:none; animation:text-pop ... }` But `animation` sets transform; initial transition. Good.
Need `.toggle:checked ~ .card .word.off { opacity:0; transform:translateY(-10px); transition: opacity .35s, transform .35s; }` Use transition. Good.
Need `.like:active .heart` maybe? Since checked animation overrides transform on .heart. `.like:active` can scale button, but `.like` when checked has `button-dance` overriding transform. If we want click feel on checked, animation transform overrides active. Could not. But okay. Maybe remove button-dance to allow active? But need crazy loop. Could make animation only on icon-wrap? Button not animating transform, then active scale works. But if button not transform, card has shake. Hmm. For click feedback, `.like:not(:checked):active` scale. If checked, dance. Good.
Need if initial checked, screenshot button dance; if user clicks to unlike, animation stops, button uses idle. Good.
Could make click animation (when toggling from unchecked) immediate even if user had unchecked before. If they click to check, CSS state changes and animation begins. Good.
Need maybe `:has`? No.
Potential issue: Because checkbox is checked initially, animation starts on load. If user clicks to uncheck, all animations stop. Then click to check, they restart. Good.
Let's think of "pure CSS, no JavaScript" but HTML inline styles. Some might object to inline style variables? It's still CSS, no JS. If strict pure CSS, maybe use classes. But inline style is okay. Could avoid by using nth-child. However final answer likely okay. To be safer, maybe no inline style? But many variables. We can use nth-child in CSS. The user specifically "pure CSS" might be interpreted as no HTML? That's impossible. CSS-only demo uses HTML checkbox and CSS. Inline style not JavaScript but maybe less pure? It's style. We can keep variables inline, but to be more pure CSS, use `.burst i:nth-child(1)` etc. But that makes CSS long. Since code can be long. Maybe better to use nth-child and custom properties defined in CSS, not inline. Let's do nth-child to emphasize pure CSS. For 18 particles, write CSS blocks. It will be lengthy but okay. Need no inline styles. The HTML can just `<i></i>` repeated 18 times. Good. Let's do that. The output can be long but within limits. Need no inline style. CSS variables per nth-child. Could be:
.burst i:nth-child(1) { --a:0deg; --r:86px; --d:0s; --c:#ff6fae; }
...
This is pure CSS. Good.
Similarly ring delays classes already.
Need generate 18 nth-child with angles. Could also use nth-child(4n) color etc? But want variety. Let's list:
1 angle 0, r 82, d 0, c #ff6fae
2 20, 96, .04s, #ffd166
3 40, 88, .08s, #ff4d6d
4 60,102, .03s, #7ee8fa
5 80,92,.11s,#fff
6 100,108,.07s,#b18cff
7 120,84,.14s,#ffca3a
8 140,98,.02s,#ff85c1
9 160,110,.09s,#51e5ff
10 180,88,.13s,#a0ffae
11 200,102,.05s,#ff4d8f
12 220,94,.12s,#ffe066
13 240,106,.01s,#7ee8fa
14 260,90,.10s,#ff6fae
15 280,100,.06s,#b18cff
16 300,112,.15s,#fff
17 320,86,.08s,#ffd166
18 340,98,.04s,#ff4d6d
Good.
Could use `.burst i:nth-child(odd)` heart shape? But no. Maybe `.burst i:nth-child(4n) { width:10px;height:10px; }` etc.
Need ensure no horizontal from `.burst i` variables? No.
Maybe include small heart particles via `clip-path: path` for even? Could be too long. Add `:nth-child(4n+1) { border-radius:0; clip-path: polygon(0 20%, 20% 0, 50% 0, 100% 30%, 100% 70%, 50% 100%, 20% 100%, 0 50%); }` not. Keep circles/squares:
`.burst i:nth-child(even) { border-radius:2px; }`
`.burst i:nth-child(3n) { width:7px; height:7px; }`
Nice.
Need `.like` background default and checked. Use `transition: transform .18s, background .28s, border-color .28s, box-shadow .28s`. But animation transform overrides. For hover, use `.like:hover` if not checked? Could use `.card .like:hover` anyway. If checked animation overrides transform? Yes. But hover box-shadow/background can apply if not transform? Animation only transform. Good.
Need `.toggle:checked ~ .card .like { animation: button-dance 1.95s ... infinite; }` Maybe with delay? Good.
Need `.toggle:checked ~ .card .icon-wrap` maybe spin? No.
Need `.toggle:checked ~ .card .heart { color: var(--like); background: linear-gradient(140deg, #ff1f5b, #ff74b3 42%, #ffe3ef 78%, #ff2d78); animation: heart-crazy 2.05s ease-in-out infinite; }`
Background gradient with clip. Good.
Need `.like` when checked text color: `.toggle:checked ~ .card .copy { color:white; }`
Potential issue: `.toggle:checked ~ .card .like` animation may override hover scale. Fine.
Need `.eyebrow` maybe pulse? Not necessary.
Need maybe status dot pulsing always to show life. `.dot { width:9px;height:9px;border-radius:50%; background:#ff6fae; box-shadow:0 0 12px; animation: dot-pulse 1.6s infinite; }`.
Need footer hint: `<span class="hint">CSS-only checkbox · no JavaScript</span>`.
Potential problem: The demo starts checked; but prompt says when click. If screenshot at 3 sec shows animation due initial checked. But if they expect unclicked static? It's okay because "something meaningful visible". However title maybe "Click to animate" but button already liked. Could have a second unclicked "cold start" button? But no JS, could have a second label not checked? Maybe include a small note. But if checked initially, clicking toggles off and on. To make it clearly "when you click", we could also include CSS `:active` animation that happens on click regardless? Like `@keyframes press-pop` on `.like:active`. But checkbox toggles; for first click from unliked, animation could start on check. If initial unchecked, screenshot static. Need initial checked for visible. Could include both: main button checked, and "start unliked"? Not needed.
Maybe set initial checked but also use CSS `animation` that triggers with each click? Since checkbox toggles, it will. Good.
Need maybe prevent double animation if checked initially and user clicks? Fine.
Potential issue: `clip-path: path()` with string uses SVG path; if coordinates use commas? Use spaces. Good. Some Chrome versions require no `Z`? Fine.
Let's consider exact heart path visually: Coordinates:
M30 50 bottom.
C15 40 3 32 3 20: left side down to left lobe.
C3 8 14 4 22 10: top-left lobe.
C26 13 30 17 30 18: middle valley? From 22,10 to 30,18 curve.
Then C30 17 34 13 38 10: valley to top-right? Wait path after 30,18 to 38,10; C30 17 34 13 38 10 okay.
C46 4 57 8 57 20: top-right lobe.
C57 32 45 40 30 50: right side down to bottom.
Z.
Should look heart. Top center y 18, lobes top y4, bottom y50. Good.
Need maybe add a subtle background heart outline? Good.
Let's write CSS fully.
Potential issue: `filter: hue-rotate` in heart-crazy keyframes may change gradient weird. Maybe no hue rotate. Keep drop-shadow. Keyframes filter:
`filter: drop-shadow(0 0 14px rgba(255,60,120,.7)) saturate(1.3);` at 0, `... saturate(1.5) brightness(1.08)` at peak. But animation filter can override. Good.
@keyframes heart-crazy {
0% { transform: scale(.96); filter: drop-shadow(0 3px 10px rgba(0,0,0,.35)) saturate(1.1); }
15% { transform: rotate(-18deg) scale(1.2); filter: drop-shadow(0 0 20px rgba(255,60,120,.85)) saturate(1.35); }
30% { transform: rotate(20deg) scale(.88); }
45% { transform: rotate(180deg) scale(1.34); }
60% { transform: rotate(360deg) scale(1.06); }
75% { transform: rotate(384deg) scale(1.12); }
100% { transform: rotate(360deg) scale(.96); filter: ... }
}
But if no transform in 30 keyframe, filter defaults? Need set all? Not all properties need. It interpolates. Better include filter 0,45,100. Simpler omit filter in keyframes, use `filter` in state and maybe animate `filter` separate? Use `animation: heart-crazy, heart-glow` two animations? Can have multiple: `animation: heart-crazy 2s infinite, heart-glow 2s infinite;` But one animation easier. Could not animate filter. Drop-shadow static. Good.
Need heart rotate 360 each cycle; transform origin center. Good.
Potential issue: `.heart` default has transform scale(1) maybe transition, animation overrides. Good.
Button dance keyframes transform may conflict with `.like:active`. Could use `.like:not(:checked)` active? But `.like` not sibling to checked. Use `.toggle:checked ~ .card .like` animation; active scale may not override? Animation overrides. Fine. For unchecked hover/active use `.toggle:not(:checked) ~ .card .like:active`. Good.
Maybe use `will-change: transform` on animated elements for performance. Add.
Need no errors in CSS var names. `--a`, `--r`, `--d`. In keyframes calc with var: `calc(var(--r) * -0.78)` okay if --r has px. Need ensure spaces around * okay? `calc(var(--r) * -0.78)` valid. Good.
Need `.burst i` transform keyframes: translate -50%, -50% to center. Then rotate and translateY. Works. `translateY(calc(var(--r) * -1))` moves outward along rotated axis. Good.
Need `.rays` uses mask-image; if unsupported, may show full circle. Could still. Maybe add `-webkit-mask-image` before `mask-image`. Good.
Potential issue: `.rays` repeating-conic-gradient may not animate scale? transform includes translate and rotate. Good.
Need ring transform center with scale: default `.ring { left:50%; top:50%; width:62px;height:62px; transform: translate(-50%,-50%) scale(.2); }` keyframes same. Good.
Need `.icon-wrap` overflow visible? default. `.burst` z-index 4, rings z-index 3, heart z-index 5, rays z-index 2, glow z-index1, flash z-index6.
Need label click target: `.like` cursor pointer. Input pointer-events none, label pointer events auto.
Need if hidden input `left:-999px` and body overflow-x hidden, okay.
Let's produce final code. Need one fenced html. Ensure no JS. No external resources. Use `<script>`? No.
Potential issue: If `input` is before card but outside body? It will be a grid item. Body grid place-items center, input absolute so not affect. Set `.toggle { position:absolute; left:0; top:0; opacity:0; pointer-events:none; width:1px;height:1px; margin:0; padding:0; border:0; clip-path: circle(0%); }`. Good.
Potential issue: With `clip-path: circle(0%)` on input, focus ring? Input has outline none. Good.
Need maybe add `aria-label`. Good.
Potential issue: `.card` sibling selector uses `~` input sibling; yes.
Potential issue: `transition` on `.toggle:checked ~ .card .like` background and animation. Fine.
Let's write final CSS with comments minimal.
Need ensure code fits. Let's draft:
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS-only Crazy Like Button</title>
<style>
:root { ... }
*, *::before, *::after { box-sizing: border-box; }
html, body { min-height:100%; }
body { ... }
.toggle { ... }
.card { ... }
...
@keyframes ...
</style>
</head>
<body>
<input id="like" class="toggle" type="checkbox" checked aria-label="Like">
<main class="card">
<header>...</header>
<div class="like-zone">
<label for="like" class="like">
<span class="icon-wrap" aria-hidden="true">
<span class="rays"></span>
<span class="glow"></span>
<span class="ring r1"></span>
<span class="ring r2"></span>
<span class="ring r3"></span>
<span class="burst">
<i></i> ... 18
</span>
<span class="heart"></span>
<span class="flash"></span>
</span>
<span class="copy">
<span class="line title">
<span class="word off">Like</span>
<span class="word on">Loved</span>
</span>
<span class="line count">
<span class="num off">1.2k likes</span>
<span class="num on">1.3k likes</span>
</span>
</span>
</label>
</div>
<footer>...</footer>
</main>
</body>
</html>
```
Need `.line.title { min-height... }`.
Maybe include `aria-live`? no.
Need 18 `<i></i>`. Count. Use exactly 18.
Now CSS details:
```
body {
margin:0;
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
background: ...;
color: var(--text);
display: grid;
place-items:center;
padding: 20px;
overflow-x:hidden;
overflow-y:auto;
position:relative;
}
```
Card:
```
.card {
position:relative;
width:min(94vw, 680px);
padding: clamp(18px,4vw,34px);
border-radius:30px;
background: linear-gradient(180deg, rgba(24,28,58,.9), rgba(12,14,34,.82));
border:1px solid rgba(255,255,255,.14);
box-shadow: 0 24px 80px rgba(0,0,0,.52), inset 0 1px 0 rgba(255,255,255,.08);
text-align:center;
isolation:isolate;
}
```
Maybe use `overflow: visible`. Good.
Header:
```
.eyebrow { display:inline-block; padding:6px 12px; border-radius:999px; font-size:.78rem; font-weight:800; letter-spacing:.14em; color:#ffd8e9; background:rgba(255,45,120,.14); border:1px solid rgba(255,93,146,.4); }
h1 { margin:.45rem 0 .4rem; font-size:clamp(1.45rem,4.5vw,2.55rem); line-height:1.05; background:linear-gradient(90deg,#fff,#ffd7ee,#9eefff); -webkit-background-clip:text; background-clip:text; color:transparent; }
p { margin:0 auto; max-width:48ch; color:var(--muted); font-size:clamp(.92rem,2.6vw,1.02rem); line-height:1.45; }
```
Like zone:
```
.like-zone { display:flex; justify-content:center; margin: clamp(18px,5vw,30px) 0 clamp(10px,3vw,16px); }
.like {
position:relative;
display:inline-flex;
align-items:center;
gap:18px;
padding: 15px 28px 15px 18px;
border-radius: 999px;
background: linear-gradient(150deg, rgba(44,50,88,.95), rgba(22,26,50,.95));
border:1px solid rgba(255,255,255,.16);
color: #e8edff;
box-shadow: 0 16px 42px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.14);
cursor:pointer;
user-select:none;
transition: background .28s ease, border-color .28s ease, box-shadow .28s ease, transform .12s ease;
min-width:240px;
min-height:96px;
}
.like:hover { transform: translateY(-2px); border-color:rgba(255,126,182,.55); box-shadow: 0 20px 50px rgba(255,45,120,.25), ... }
.toggle:not(:checked) ~ .card .like:active { transform: scale(.96); }
```
Need if hover transform conflict with checked dance; okay.
Checked state:
```
.toggle:checked ~ .card .like {
background: linear-gradient(135deg, #ff2d78, #ff71ae 45%, #9a144d);
border-color: rgba(255,255,255,.35);
color:#fff;
box-shadow: 0 22px 58px rgba(255,45,120,.5), 0 0 0 1px rgba(255,255,255,.12), inset 0 1px 0 rgba(255,255,255,.25);
animation: button-dance 1.95s cubic-bezier(.2,.8,.25,1) infinite;
}
.toggle:checked ~ .card .copy { color:#fff; }
```
But `.copy` already color? We set. Good.
Icon-wrap:
```
.icon-wrap { position:relative; width:68px; height:68px; flex:0 0 auto; display:grid; place-items:center; perspective:800px; }
.heart { width:60px; height:54px; position:relative; z-index:5; background:#8d9bb5; clip-path: path(...); filter: drop-shadow(0 2px 8px rgba(0,0,0,.3)); transition: background .28s, filter .28s, transform .16s; }
.toggle:checked ~ .card .heart { background: linear-gradient(135deg,#ff1f5b,#ff74b3 45%,#ffd6e8 70%,#ff2d78); filter: drop-shadow(0 0 16px rgba(255,54,121,.7)); animation: heart-crazy 2.05s cubic-bezier(.2,.8,.25,1) infinite; }
```
Rings:
```
.ring { position:absolute; left:50%; top:50%; width:58px; height:58px; border-radius:50%; opacity:0; transform: translate(-50%,-50%) scale(.18); pointer-events:none; }
.r1 { border:3px solid rgba(255,105,159,.95); }
.r2 { border:2px solid rgba(255,209,102,.92); }
.r3 { border:1.5px solid rgba(126,232,250,.9); }
.toggle:checked ~ .card .ring { animation: ring-burst 1.65s ease-out infinite; }
.toggle:checked ~ .card .r1 { animation-delay:.08s }
.toggle:checked ~ .card .r2 { animation-delay:.36s }
.toggle:checked ~ .card .r3 { animation-delay:.68s }
```
Rays:
```
.rays { position:absolute; left:50%; top:50%; width:170px; height:170px; border-radius:50%; opacity:0; transform: translate(-50%,-50%) scale(.1); pointer-events:none; background: repeating-conic-gradient(...); z-index:2; mask-image: radial-gradient(...); -webkit-mask-image: ... }
.toggle:checked ~ .card .rays { animation: ray-pop 1.9s ease-out .02s infinite; }
```
Glow:
```
.glow { position:absolute; left:50%; top:50%; width:130px;height:130px; border-radius:50%; transform:translate(-50%,-50%) scale(.78); background: radial-gradient(circle, rgba(255,73,134,.75), rgba(255,73,134,0) 68%); filter: blur(16px); opacity:.18; z-index:1; pointer-events:none; }
.toggle:checked ~ .card .glow { animation: glow-pulse 1.95s ease-in-out infinite; }
```
Glow-pulse keyframes transform includes translate? Need set full transform. `0%,100% { transform: translate(-50%,-50%) scale(.78); opacity:.18; filter:blur(16px);} 45% { transform: translate(-50%,-50%) scale(1.35); opacity:.6; filter:blur(24px); }`. Good.
Flash:
```
.flash { position:absolute; left:50%; top:50%; width:110px;height:110px;border-radius:50%; background: radial-gradient(circle, rgba(255,255,255,.92), rgba(255,180,220,.45) 26%, transparent 66%); opacity:0; transform:translate(-50%,-50%) scale(.2); mix-blend-mode:screen; pointer-events:none; z-index:6; }
.toggle:checked ~ .card .flash { animation: flash-pop .82s ease-out infinite; }
```
Burst:
```
.burst { position:absolute; inset:0; z-index:4; pointer-events:none; }
.burst i { position:absolute; left:50%; top:50%; width:8px;height:8px;border-radius:999px; background:#fff; opacity:0; transform: translate(-50%,-50%) scale(.1); pointer-events:none; }
.burst i:nth-child(even) { border-radius:2px; }
.burst i:nth-child(3n) { width:7px; height:7px; }
.burst i:nth-child(4n) { width:10px; height:10px; }
.toggle:checked ~ .card .burst i { animation: spark-burst 1.45s ease-out infinite; }
... nth-child variables.
```
Copy:
```
.copy { display:grid; gap:4px; text-align:left; min-width:104px; }
.line { position:relative; line-height:1.12; min-height:1.12em; }
.line.count { min-height:1.12em; color:rgba(235,240,255,.75); }
.word,.num { position:absolute; left:0; top:0; white-space:nowrap; transition: opacity .28s, transform .28s; }
.word { font-weight:900; font-size:clamp(1.15rem,4vw,1.55rem); letter-spacing:.01em; }
.word.on, .num.on { opacity:0; transform: translateY(8px); }
.word.off, .num.off { opacity:1; transform: translateY(0); }
.toggle:checked ~ .card .word.off { opacity:0; transform: translateY(-8px); }
.toggle:checked ~ .card .word.on { opacity:1; transform:none; animation: text-pop 1.8s ease-in-out infinite; }
.toggle:checked ~ .card .num.off { opacity:0; transform: translateY(-6px); }
.toggle:checked ~ .card .num.on { opacity:1; transform:none; animation: text-pop 1.8s .12s ease-in-out infinite; }
```
Need shorthand animation with delay? Longhand maybe.
Footer:
```
.footer { display:flex; flex-wrap:wrap; justify-content:center; gap:10px 18px; color:#b5bfd9; font-size:.82rem; }
.pill { display:inline-flex; align-items:center; gap:8px; padding:7px 12px; border-radius:999px; background:rgba(255,255,255,.07); border:1px solid rgba(255,255,255,.12); }
.dot { width:9px;height:9px;border-radius:50%; background:#ff6fae; box-shadow:0 0 12px #ff6fae; animation: dot-pulse 1.6s ease-in-out infinite; }
.dot.green { background:#55f5a5; box-shadow:0 0 12px #55f5a5; }
```
Keyframes:
```
@keyframes card-shake { ... }
.toggle:checked ~ .card { animation: card-shake 2.35s ease-in-out infinite; }
```
Need apply. But card also contains everything. Good.
```
@keyframes button-dance { ... }
```
```
@keyframes heart-crazy { ... }
```
```
@keyframes ring-burst { ... }
```
Rings have width 58, scale 2.8 may extend 162px, fits body. Good.
```
@keyframes spark-burst { ... }
```
```
@keyframes ray-pop { ... }
```
```
@keyframes glow-pulse { ... }
```
```
@keyframes flash-pop { ... }
```
```
@keyframes text-pop { ... }
```
```
@keyframes dot-pulse { 0%,100%{transform:scale(.8);opacity:.7;} 50%{transform:scale(1.2);opacity:1;} }
```
Reduced motion optional:
```
@media (prefers-reduced-motion: reduce) {
.toggle:checked ~ .card .heart, .toggle:checked ~ .card .ring, .toggle:checked ~ .card .burst i, .toggle:checked ~ .card .rays, .toggle:checked ~ .card .glow, .toggle:checked ~ .card .flash, .toggle:checked ~ .card .word.on, .toggle:checked ~ .card .num.on, .toggle:checked ~ .card .like, .toggle:checked ~ .card, .dot { animation-iteration-count: 1 !important; animation-duration:.65s !important; }
}
```
But if reduce, first paint after 3s may not animate if one-shot ended. But if screenshot after 3s and reduce? Could still show final liked state. That's okay. But to be safe maybe not include; evaluation likely no reduce. Could include but keep initial delay? not.
Potential issue: Since input checked initially, `animation: card-shake infinite` on `.card` may cause box-shadow etc. If body has `overflow-y:auto`, shake may create horizontal? overflow-x hidden. Good.
Need no external. Good.
Let's ensure nth-child variable CSS not too much. For each nth-child, set variables. Could combine in one block:
```
.toggle:checked ~ .card .burst i:nth-child(1) { --a:0deg; --r:82px; --d:0s; --c:#ff6fae; }
```
But variables need default maybe on `.burst i`. Use variables in animation; if no checked? Not used. For checked, variables set. Good. For all particles, variables set. Could also define on `.burst i` default then nth-child overrides. But each nth-child enough. Need animation shorthand? We'll set `animation-delay: var(--d);` in checked block. If variables defined. Good.
CSS:
```
.toggle:checked ~ .card .burst i {
animation-name: spark-burst;
animation-duration: 1.45s;
animation-timing-function: ease-out;
animation-delay: var(--d, 0s);
animation-iteration-count: infinite;
}
```
Variables set in nth-child blocks. Good.
Need colors background for particles: `background: var(--c, #fff);`. Good.
Potential issue: `--c` not set before checked, default. Good.
Maybe define nth-child blocks under `.burst i:nth-child(n)`, not under checked, to always have variables. Good.
Let's write all 18.
```
.burst i:nth-child(1){--a:0deg;--r:82px;--d:0s;--c:#ff6fae}
...
```
Need no semicolons? okay.
Potential issue: `--r` px used in calc, okay.
Need maybe animation of `.burst i` uses `animation-fill-mode: both` to apply hidden before delay? With infinite and delay, during delay uses backwards? If not, element stays default hidden. Default hidden anyway. Good. `animation-fill-mode: none` okay. At 0% opacity 0.
Potential issue: With infinite and delay, after each iteration, next starts immediately? `animation-delay` only first iteration. Good.
Need `.burst i` transform hidden default: `transform: translate(-50%, -50%) scale(.1); opacity:0;`. During animation, transform overridden. Good.
Potential issue: `animation: text-pop` with transform might override transition transform none. Good.
Potential issue: `.line.count` min-height and text absolute. Good.
Need maybe button width changes between Like/Loved/Likes? Since both absolute, layout stable. Count lengths maybe "1.3k likes" vs "1.2k likes" same length. Good.
Potential issue: On small screens, button min-width 240 may exceed 375? 240 okay. But padding + icon 68 gap 18 copy 104 = 240 + 62 = 302. On 375, card padding 18 -> available 339; min-width 240 okay. Use max width? `.like { width:min(320px, 100%); }`? For center. Set `.like { width:min(320px, 100%); justify-content:flex-start; }`. Then on 375 okay. Use min-width. `.copy min-width:96px`. Good.
Need if 375 viewport and card text p, button, footer fits height? Body overflow-y auto. Good.
Potential issue: `.card` width min(94vw, 680px). Good.
Potential issue: body padding 20, if 375 width, card width 352. Button width 320. Good.
Need no horizontal scrollbar from box-shadow? box-shadow doesn't affect scroll. Transform rotation? Body overflow-x hidden.
Let's consider final answer should only be code block. No commentary. Good.
Double-check syntax:
`background-clip: text;` with `color: transparent` for h1. If unsupported, may look transparent? Chrome supports. Good.
`clip-path: path("M30 50 C15 40 3 32 3 20 C3 8 14 4 22 10 C26 13 30 17 30 18 C30 17 34 13 38 10 C46 4 57 8 57 20 C57 32 45 40 30 50 Z");` The syntax for path uses absolute coordinates; commas not required but spaces. Good. Some browsers might not parse due to no commas between control points? SVG path grammar: C requires 6 numbers, whitespace okay. Good.
`background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.92) 0 6deg, transparent 6deg 18deg);` valid.
`mask-image: radial-gradient(circle, rgba(0,0,0,1) 14%, rgba(0,0,0,0) 64%);` valid. Need `-webkit-mask-image`. Good.
Potential issue: `animation: ray-pop 1.9s ease-out .02s infinite;` In shorthand, timing then delay okay? `animation: name duration timing-function delay iteration-count;` Yes if first duration, second time is delay. Good. To be safe use longhand? It's okay. Maybe use `animation: ray-pop 1.9s ease-out .02s infinite;` valid. For `.glow`: `animation: glow-pulse 1.95s ease-in-out infinite;` valid. `.flash`: `.82s ease-out infinite;`. `.word.on`: `animation: text-pop 1.8s ease-in-out infinite;`. Good. `.num.on`: `animation: text-pop 1.8s ease-in-out .12s infinite;` If order: after timing function, first time duration already set, second time delay. Need format `animation: text-pop 1.8s ease-in-out .12s infinite;` valid. Could avoid with longhand for delayed. But shorthand with two times first duration second delay. Good.
Need `.toggle:checked ~ .card .r1 { animation-delay: .08s; }` works with shorthand? yes overrides.
Need `.toggle:checked ~ .card .burst i { animation-delay: var(--d, 0s); }` If shorthand not used? We'll use longhand for burst to be safe. Good.
Potential issue: `will-change: transform, opacity;` on many elements. fine.
Let's write burst longhand:
```
.toggle:checked ~ .card .burst i {
animation-name: spark-burst;
animation-duration: 1.45s;
animation-timing-function: ease-out;
animation-delay: var(--d, 0s);
animation-iteration-count: infinite;
}
```
Need `animation-fill-mode: none;` default. Good.
Potential issue: `.burst i` no `--d` maybe default. Good.
Need `.ring` animation with `animation-delay` class after shorthand. Good.
Need `.toggle:checked ~ .card .rays { animation: ray-pop 1.9s cubic-bezier(.18,.84,.25,1) .02s infinite; }` okay.
Need `.toggle:checked ~ .card .glow { animation: glow-pulse 1.95s ease-in-out infinite; }`.
Need `.toggle:checked ~ .card .flash { animation: flash-pop .9s ease-out infinite; }`.
Need `.toggle:checked ~ .card .heart { animation: heart-crazy 2.05s ... infinite; }`.
Need keyframes transform for heart: If `rotate(360deg) scale(1.3)` and default `.heart` has `transform`? Good. But heart has `clip-path`, rotates. Maybe heart bounding box 60x54 within 68; rotating scale 1.34 -> 80x72 still inside icon-wrap? It may overflow into copy. But pointer-events none? Heart pointer events? label, heart not interactive. Overflow visible okay. It might cover text? z-index? `.heart` z-index5, copy maybe z-index2? `.icon-wrap` relative, copy sibling. If heart extends beyond icon-wrap, could overlap copy but pointer events none? Heart is span pointer events auto? Add `pointer-events:none` to decorative spans so clicks go to label? `.icon-wrap` can have pointer-events:none, label still. Since label's descendants default pointer events; clicking heart toggles anyway because label click. Fine. But visual overlap? Maybe okay. Could scale max 1.22 to fit. Use 1.28. Icon wrap 68, heart 60, scale 1.22 -> 73, slight. Fine.
Keyframes heart-crazy:
```
@keyframes heart-crazy {
0% { transform: rotate(-4deg) scale(.96); }
16% { transform: rotate(-22deg) scale(1.2); }
32% { transform: rotate(20deg) scale(.88); }
52% { transform: rotate(280deg) scale(1.28); }
70% { transform: rotate(360deg) scale(1.06); }
84% { transform: rotate(380deg) scale(1.12); }
100% { transform: rotate(360deg) scale(.96); }
}
```
This rotates from 280 to 360, overshoots to 380 back to 360? From 84 to 100 goes back to 360. Might look jitter. Maybe simpler:
```
@keyframes heart-crazy {
0% { transform: scale(.96) rotate(0deg); }
15% { transform: scale(1.22) rotate(-25deg); }
30% { transform: scale(.9) rotate(28deg); }
45% { transform: scale(1.3) rotate(0deg); }
60% { transform: scale(1) rotate(360deg); }
75% { transform: scale(1.12) rotate(360deg); }
100% { transform: scale(.96) rotate(360deg); }
}
```
But 45 to 60 rotates 360. Good. It jumps? rotate 0 to 360 linear ease, okay. But scale at 45 1.3, then rotates. Fine. Maybe use:
```
0: scale(1) rotate(0)
20: scale(1.25) rotate(-28deg)
40: scale(.88) rotate(26deg)
60: scale(1.32) rotate(360deg)
80: scale(1) rotate(360deg)
100: scale(1) rotate(360deg)
```
End at 360 same start. Good. This is smooth-ish.
Need `filter` animation? Could add in keyframes:
```
0%,100% { filter: drop-shadow(0 3px 10px rgba(255,50,120,.55)); }
60% { filter: drop-shadow(0 0 28px rgba(255,80,150,.95)); }
```
But if transform keyframes and filter keyframes with percentages, need ensure filter at 100. Fine. Let's include to make glow.
```
@keyframes heart-crazy {
0% { transform: scale(1) rotate(0deg); filter: drop-shadow(0 3px 12px rgba(255,45,120,.45)); }
20% { transform: scale(1.24) rotate(-26deg); filter: drop-shadow(0 0 22px rgba(255,70,140,.8)); }
40% { transform: scale(.88) rotate(24deg); filter: drop-shadow(0 0 14px rgba(255,70,140,.55)); }
60% { transform: scale(1.32) rotate(360deg); filter: drop-shadow(0 0 30px rgba(255,110,170,.95)); }
80% { transform: scale(1.02) rotate(360deg); filter: drop-shadow(0 0 18px rgba(255,80,150,.6)); }
100% { transform: scale(1) rotate(360deg); filter: drop-shadow(0 3px 12px rgba(255,45,120,.45)); }
}
```
End rotate 360 = 0 visually. Good.
Button dance keyframes:
```
@keyframes button-dance {
0%,100% { transform: translateY(0) rotate(0deg) scale(1); }
20% { transform: translateY(-3px) rotate(-2deg) scale(1.025); }
45% { transform: translateY(2px) rotate(2deg) scale(.985); }
70% { transform: translateY(-1px) rotate(-1deg) scale(1.02); }
}
```
Good.
Card shake subtle:
```
@keyframes card-shake {
0%,100% { transform: translate3d(0,0,0) rotate(0); }
22% { transform: translate3d(-2px,1px,0) rotate(-.25deg); }
48% { transform: translate3d(3px,-2px,0) rotate(.35deg); }
74% { transform: translate3d(-2px,2px,0) rotate(-.3deg); }
}
```
Ring burst:
```
@keyframes ring-burst {
0% { transform: translate(-50%, -50%) scale(.16); opacity:0; }
18% { opacity:.95; }
100% { transform: translate(-50%, -50%) scale(3.1); opacity:0; }
}
```
Width 58*3.1=180. Good.
Ray pop:
```
@keyframes ray-pop {
0% { transform: translate(-50%, -50%) scale(.08) rotate(0deg); opacity:0; }
18% { opacity:.85; }
100% { transform: translate(-50%, -50%) scale(1.85) rotate(130deg); opacity:0; }
}
```
Rays 170*1.85=314. Might overflow card horizontally? Card width up to 680, button centered; okay. On small screens 375, ray 314 maybe slightly beyond card but body overflow hidden. Good.
Flash:
```
@keyframes flash-pop {
0% { transform: translate(-50%, -50%) scale(.18); opacity:0; }
12% { opacity:.95; }
100% { transform: translate(-50%, -50%) scale(2.8); opacity:0; }
}
```
Text pop:
```
@keyframes text-pop {
0%,100% { transform: translateY(0) scale(1); }
18% { transform: translateY(-3px) scale(1.08); }
42% { transform: translateY(1px) scale(.98); }
}
```
Dot pulse.
Need `.toggle:checked ~ .card .like` background and animation. But `.like` is child inside card; `.card` has animation transform, `.like` also. Parent transform plus child transform okay.
Need `.toggle:checked ~ .card .word.on` transform? It has animation `text-pop`, which uses transform translateY. Initial `.word.on` transition transform. Good.
Need if input unchecked after initial, `word.on` hidden, `word.off` visible. Good.
Need status pills: `<span class="pill"><span class="dot"></span> CSS state: checked</span>` maybe. Since checked initially, status could show checked. But no JS to update state text. Could include two pills: `.dot` neutral? If static text "demo starts liked". Not update. That's okay. Maybe avoid status that says state? Could say "checkbox toggles CSS state". Use dot pulse. Good.
Could include a small "Click to toggle" always. Good.
Need maybe if user unchecks, the button says Like, but demo text says starts liked. Good.
Potential issue: If checkbox unchecked, `.toggle:checked ~ .card` animations removed; `.card` transform reverts. Good.
Potential issue: Some animations on decorative elements have `pointer-events:none`. Good.
Potential issue: `label` is not a button for screen readers. Input has role? Could add `role="button"`? Not needed. Maybe `<label ... role="button">`? But then input? Simpler. Good.
Potential issue: Since input is before card and body grid, card is grid item. Hidden input has `position:absolute`, out of flow, body still grid? If input absolute not grid item? It is removed from flow? Absolutely positioned out of flow, so body grid has card only. Good.
Potential issue: `html, body { height: 100% }` and `body min-height:100svh`. Good.
Potential issue: `@media (prefers-reduced-motion)` with `!important` may make screenshot static at 3s. Could be bad if evaluation uses reduced motion? Probably not. If include, it may hide animation at screenshot if system reduced. Better omit or set iterations to 1 but delay maybe still active at 3s? If duration .65, ended. Bad. So don't include. Or include but still infinite? Not. We can omit for demo.
Potential issue: `mask-image` might cause elements not visible? If mask unsupported, rays full circle; okay.
Need final answer with one fenced html. Let's produce code. Ensure no `script` tag. Good.
Let's double-check nth-child count: We'll add 18 `<i></i>` exactly. Count in HTML: maybe write one per line, 18.
Particles CSS:
```
.burst i:nth-child(1) { --a: 0deg; --r: 82px; --d: 0s; --c: #ff6fae; }
.burst i:nth-child(2) { --a: 22deg; --r: 96px; --d: .04s; --c: #ffd166; }
...
```
Angles: 0,22,44,66,88,110,132,154,176,198,220,242,264,286,308,330,352,15? 18 covers. Use variety. Need `--d` as string with leading dot `.04s`; valid. Good.
Radii: 82,96,88,104,92,110,84,98,108,90,102,94,112,86,100,95,105,90. Colors: repeated. Good.
Need `.burst i` size maybe 8; colors. Good.
Potential issue: `--r: 104px` in keyframe `translateY(calc(var(--r) * -1.18))` -> -122.72px. Good.
Need `.burst` default z-index. Good.
Potential issue: If `--d` variables only on nth-child not checked, okay. Good.
Need maybe `.burst i:nth-child(5n) { width:6px; height:12px; border-radius:999px; }` etc to vary. Good.
Potential issue: `.like` has `min-height:96px`; icon-wrap 68; padding vertical 15 = 98. Good.
Potential issue: On checked, `like` dance transform scale might cause overflow? okay.
Potential issue: Body `background` may have gradient fixed? okay.
Potential issue: Use `100svh` unsupported? Latest Chrome supports. Good.
Potential issue: `.card` width min(94vw, 680px); if body padding 20, total 94vw + 40? Actually body padding reduces available but card min uses vw, could be wider than content area? Body `padding:20px`, card width `min(94vw,680)` means at 375 card 352, body content width 335 (375-40). Card overflow 17px causing horizontal? But overflow-x hidden. But visual card maybe clipped. Better use `width: min(100%, 680px)` with max-width 680 and `margin: auto`. Body grid place-items center and padding. Use `.card { width: min(100%, 680px); }`. Since body padding 20, card fits. Use `width:min(100%, 680px);` not `94vw`. Good. On desktop, max 680. At 375, 335. Good.
Potential issue: Card padding 34 at 375? clamp min 18. Good.
Need `.like` width `min(100%, 320px)` maybe but flex center. If `.like` inline-flex with width, good.
Potential issue: `.like` overflow visible; decorative elements can extend outside. Card not overflow hidden. Good.
Potential issue: `.rays` and burst may cover header? z-index? Header not positioned, but `.like-zone` later, stacking? `.card` position relative isolation; children order header then like-zone then footer. Like-zone has higher position? Since absolute rays inside `.icon-wrap` with z-index 2 but stacking context maybe `.icon-wrap` relative, above header? Header is before, if positioned? Header not positioned; later elements with transform create stacking context? Animation transforms create stacking context. Should be above. Fine.
Potential issue: `.rays` with `mix-blend`? no.
Potential issue: `backdrop-filter` not used. Good.
Let's consider if there is any JavaScript. None.
Potential issue: The prompt says "Games must start in self-playing demo mode..." irrelevant. But our page has animation auto. Good.
Potential issue: `input` checked may not trigger animation if browser starts with checked? CSS `:checked` matches and animations start on load. Yes.
Potential issue: Clicking label toggles; if user clicks, checked state becomes unchecked; but the input initially checked so the "like" button is already liked. They might think click does un-like animation? The animation stops; not as crazy. But second click restarts. Maybe better initial unchecked but include a CSS "auto demo" overlay that shows button liked? Could create an `:indeterminate`? no. Could include separate auto animation not dependent on checked? For screenshot, we can animate an identical "demo heart" that is always crazy via CSS independent of checkbox, and the real button when clicked also animates. But user asks "a like button" singular. If initial unchecked and static, screenshot not crazy. Initial checked better.
Maybe make first click (from checked to unchecked) still have some animation? Could add `transition` and maybe `.toggle:not(:checked) ~ .card .heart` animates `unlike-settle` once? But if not checked, animation would run continuously because state not checked. Could add a separate animation on `:not(:checked)` that is subtle; but after load, not checked? Since initial checked, if unchecked, it will animate continuously unlike, maybe not desired. Could use `:not(:checked)` with one-shot? CSS animation starts whenever element is not checked (including load after unchecking), so continuous. Not. Could set initial unchecked but use `:hover` animation? Not click. So initial checked is best.
Could have `input` checked but add a label for reset? Maybe two checkboxes? No.
Maybe use a CSS `animation` on `.like` itself that always runs when not interacting (like demo) to show a fake explosion via pseudo, and click state adds different. But too complex. Initial checked sufficient.
Need ensure screenshot at 3 sec: all loops period around 2s, so mid animation. Good.
Potential issue: The heart-crazy ends rotate 360; from 0 to 20 to 40 to 60 etc. At 3s with duration 2.05, mid. Good.
Potential issue: `.burst i` duration 1.45 and delays; at 3s active. Good.
Potential issue: `.ray-pop` duration 1.9 with delay .02, active. Good.
Potential issue: `.card-shake` 2.35 active. Good.
Potential issue: `flash-pop .9s infinite` might be frequent; okay.
Let's check code syntax for keyframe with var: In spark-burst, use `translateY(calc(var(--r) * -.72))`? Multiplying by negative number no space? `calc(var(--r) * -0.72)` valid. `--r: 82px` -> -59px. Good. At 100 `* -1.18`. Need if angle rotate around center, translate along rotated axis. Good. But transform order: `translate(-50%,-50%) rotate(var(--a)) translateY(-...) scale`. If rotate before translate, translation along rotated coordinate. Good. The center translate remains before rotate; transforms apply right to left? CSS transform list applies from left to right? Actually matrices multiply left to right: element first translate center, then rotate, then translateY along local axes. Good.
Potential issue: `.ring` width 58; transform uses translate. Keyframes include translate same. Good.
Potential issue: `.r1` etc have delays but ring default transform hidden; animation fill mode none; before first delay, element hidden (default). Good.
Potential issue: If `.toggle:checked` removed, animation stops abruptly and default opacity 0. Good.
Potential issue: `.toggle:focus-visible ~ .card .like { outline: ... }`. Since input hidden, focus ring on like. Good. But input hidden with pointer-events none and clip; can it focus? Yes. Keyboard Tab to input. Space toggles. Good.
Potential issue: If user clicks on heart, label toggles. Good.
Potential issue: `.icon-wrap` `perspective` but heart transform not 3D except no rotateY. Fine.
Potential issue: `background: linear-gradient` for heart with `clip-path` and filter drop-shadow; the drop-shadow follows clipped shape? Yes filter applied after clip. Good.
Potential issue: Path clipping may not show due to no `background` size? The background gradient fills element box and clip cuts. Good.
Potential issue: If path unsupported, heart invisible. Could fallback? Add `@supports not (clip-path: path('M0 0')) { .heart { width:60px;height:60px;border-radius:50%; } }` But if path unsupported in old browsers; latest Chrome. Not needed. But for safety could use an emoji fallback? But path is CSS. Could add `content: '❤'`? no.
Need maybe `aria-hidden` on icon-wrap. Good.
Potential issue: The title says pure CSS no JavaScript, but HTML `input` is used. Good.
Let's produce final code. Ensure code block exactly ```html. No extra. Need final answer only. Oververbosity default 9 but output code only per rules. Good.
Double-check 18 i tags:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18. We'll write them on lines maybe each. Count in CSS too. Good.
Let's write CSS nth-child for all:
```
.burst i:nth-child(1) { --a:0deg; --r:82px; --d:0s; --c:#ff6fae; }
.burst i:nth-child(2) { --a:22deg; --r:96px; --d:.04s; --c:#ffd166; }
...
```
Need if `--d:.04s` valid. Good.
Maybe use `.5s`? Fine.
Need variable default in `.burst i`: `background: var(--c, #fff);` Good.
Need animation longhand for burst uses `animation-delay: var(--d, 0s);`. Good.
Need if `--d` not defined in default, fallback. Good.
Potential issue: In shorthand `animation: text-pop 1.8s .12s ease-in-out infinite` if first time duration second delay but timing after? It's okay but to be safe for `.num.on` longhand? We can use shorthand `animation: text-pop 1.8s ease-in-out .12s infinite;` order name duration timing delay iteration. That is valid. But some parsers expect duration before timing? Actually `animation: play 3s ease-in 1s infinite reverse both running;` first time is duration, second is delay. If timing function after duration and before delay, fine. So `animation: text-pop 1.8s ease-in-out .12s infinite;` valid. Good.
Need `.toggle:checked ~ .card .num.on { animation: text-pop 1.8s ease-in-out .12s infinite; }` Good.
Potential issue: `.r1 { animation-delay: .08s; }` after ring animation shorthand. Good.
Potential issue: `.rays { animation: ray-pop 1.9s ease-out .02s infinite; }` Good.
Potential issue: `.toggle:checked ~ .card .heart { animation: heart-crazy 2.05s cubic-bezier(.16,.84,.26,1) infinite; }` Good.
Potential issue: `cubic-bezier(.16,.84,.26,1)` valid. Good.
Potential issue: Body has `overflow-y:auto`, if card shake transform could create scrollbar? overflow-x hidden; vertical maybe. Fine. But at 1280x800 no vertical. At 375 maybe card height 550? fits. Good.
Potential issue: Use `svh` unit. Latest Chrome. Good. Could use `100vh` fallback? `min-height: 100vh; min-height: 100svh;` Good.
Need final code. Ensure no `script`. Good.
Let's produce.