Exploding like buttonOne-line
MiniMax M3.1 Flash
by MiniMaxReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 38.6 s
- Cost
- $0.0043
- Output tokens
- 7,097
- Spent thinking
- 1,439 tokens
- Speed
- 186.8 tok/s
- Console errors
- 0
- First token after
- 623 ms
- First visible text after
- 11.8 s
- Prompt tokens
- 541
- Code size
- 14.0 KB
- Finish reason
- stop
- Served by
- Fireworks
- Model id
minimax/minimax-m3.1-flash- Reasoning sent
{"effort":"low"}- 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 · 304 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Crazy Pure-CSS Like Button</title>
<style>
*{box-sizing:border-box}
html,body{height:100%}
body{
margin:0;
display:grid;
place-items:center;
overflow:hidden;
font-family:"Segoe UI",system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;
background:
radial-gradient(1200px 700px at 20% 10%, #2b1b52 0%, transparent 60%),
radial-gradient(900px 700px at 85% 85%, #0e3b58 0%, transparent 60%),
#080814;
color:#e9e9f5;
-webkit-tap-highlight-color:transparent;
}
.stage{
position:relative;
width:min(440px,94vw);
padding:34px 26px 30px;
border-radius:28px;
background:linear-gradient(160deg,rgba(255,255,255,.10),rgba(255,255,255,.03));
border:1px solid rgba(255,255,255,.14);
box-shadow:0 30px 80px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.25);
backdrop-filter:blur(14px);
text-align:center;
isolation:isolate;
}
.stage.shake{animation:shake .6s cubic-bezier(.36,.07,.19,.97) both}
@keyframes shake{
10%,90%{transform:translate(-2px,1px) rotate(-.4deg)}
20%,80%{transform:translate(4px,-2px) rotate(.6deg)}
30%,50%,70%{transform:translate(-7px,2px) rotate(-.9deg)}
40%,60%{transform:translate(7px,-1px) rotate(.9deg)}
}
.title{font-size:13px;letter-spacing:.28em;text-transform:uppercase;opacity:.55;margin:0 0 6px}
h1{margin:0 0 6px;font-size:26px;font-weight:800;letter-spacing:-.5px}
.sub{margin:0 0 26px;font-size:14px;opacity:.6;line-height:1.5}
input#like{position:absolute;opacity:0;width:1px;height:1px;pointer-events:none}
.btnzone{position:relative;height:132px;display:grid;place-items:center}
/* ---- the button ---- */
.btn{
position:relative;z-index:6;
display:inline-flex;align-items:center;gap:12px;
padding:14px 26px 14px 20px;
border-radius:999px;
cursor:pointer;
color:#ff5c8a;
background:rgba(255,92,138,.12);
border:1.5px solid rgba(255,92,138,.45);
font-weight:700;font-size:16px;letter-spacing:.2px;
box-shadow:0 8px 26px rgba(255,60,110,.28), inset 0 1px 0 rgba(255,255,255,.2);
transition:transform .18s cubic-bezier(.2,1.4,.4,1), background .25s, color .25s, border-color .25s, box-shadow .25s;
user-select:none;
}
.btn:hover{transform:translateY(-2px) scale(1.04)}
.btn:active{transform:translateY(1px) scale(.96)}
.btn .heart{width:30px;height:30px;display:block;filter:drop-shadow(0 0 8px rgba(255,70,110,.6))}
.btn .heart svg{width:100%;height:100%;display:block;fill:currentColor}
.n{display:inline-block;position:relative}
.n b{font-weight:800}
.n .off,.n .on{transition:opacity .25s}
.n .on{position:absolute;left:0;top:0;opacity:0}
#like:checked ~ .btnzone .n .off{opacity:0}
#like:checked ~ .btnzone .n .on{opacity:1}
/* ---- checked state ---- */
#like:checked ~ .btnzone .btn{
color:#fff;
background:linear-gradient(135deg,#ff3d71,#ff7a18);
border-color:rgba(255,255,255,.55);
box-shadow:0 12px 40px rgba(255,70,110,.6), inset 0 1px 0 rgba(255,255,255,.4);
}
#like:checked ~ .btnzone .btn .heart{animation:pop .7s cubic-bezier(.2,1.6,.3,1)}
@keyframes pop{
0%{transform:scale(1) rotate(0)}
25%{transform:scale(.55) rotate(-14deg)}
50%{transform:scale(1.5) rotate(10deg)}
70%{transform:scale(.9) rotate(-6deg)}
85%{transform:scale(1.12) rotate(3deg)}
100%{transform:scale(1) rotate(0)}
}
/* ---- rainbow conic burst behind ---- */
.burst{
position:absolute;z-index:1;width:220px;height:220px;border-radius:50%;
background:conic-gradient(from 0deg,#ff2d55,#ff9f1c,#ffe600,#39ff88,#00d9ff,#7b5cff,#ff2d55);
-webkit-mask-image:radial-gradient(circle,#000 32%,rgba(0,0,0,.35) 55%,transparent 72%);
mask-image:radial-gradient(circle,#000 32%,rgba(0,0,0,.35) 55%,transparent 72%);
opacity:0;transform:scale(.2);
}
#like:checked ~ .btnzone .burst{animation:burst 1s cubic-bezier(.1,.8,.3,1) forwards}
@keyframes burst{
0%{opacity:.95;transform:scale(.2) rotate(0deg)}
60%{opacity:.8}
100%{opacity:0;transform:scale(2.6) rotate(160deg)}
}
/* ---- shockwave rings ---- */
.ring{
position:absolute;z-index:3;width:110px;height:110px;border-radius:50%;
border:3px solid rgba(255,120,160,.9);opacity:0;
}
.ring.r2{border-color:rgba(255,220,80,.9)}
.ring.r3{border-color:rgba(120,220,255,.9);border-width:2px}
#like:checked ~ .btnzone .r1{animation:ring .85s ease-out forwards}
#like:checked ~ .btnzone .r2{animation:ring .95s .08s ease-out forwards}
#like:checked ~ .btnzone .r3{animation:ring 1.05s .16s ease-out forwards}
@keyframes ring{
0%{opacity:.95;transform:scale(.2)}
70%{opacity:.35}
100%{opacity:0;transform:scale(3.4)}
}
/* ---- particle burst ---- */
.particles{position:absolute;z-index:5;inset:0;pointer-events:none}
.particle{
position:absolute;top:50%;left:50%;
width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;
background:var(--c);
box-shadow:0 0 12px var(--c);
opacity:0;
}
.particle.sq{border-radius:3px;width:9px;height:14px;margin:-7px 0 0 -4px}
.particle.star{width:0;height:0;background:none;border-radius:0;margin:-9px 0 0 -9px;
box-shadow:none;
border-left:9px solid transparent;border-right:9px solid transparent;border-bottom:18px solid var(--c);
}
#like:checked ~ .btnzone .particle{animation:fly .95s cubic-bezier(.12,.7,.3,1) forwards}
@keyframes fly{
0%{opacity:0;transform:rotate(var(--a)) translateX(0) scale(.2) rotate(0deg)}
15%{opacity:1}
70%{opacity:1}
100%{opacity:0;transform:rotate(var(--a)) translateX(var(--d)) scale(.15) rotate(320deg)}
}
/* ---- floating hearts ---- */
.floaters{position:absolute;z-index:5;inset:0;pointer-events:none}
.fh{
position:absolute;left:50%;top:42%;width:22px;height:22px;margin-left:-11px;
color:var(--c);opacity:0;
}
.fh svg{width:100%;height:100%;fill:currentColor;filter:drop-shadow(0 0 8px var(--c))}
#like:checked ~ .btnzone .fh{animation:float 1.5s ease-out forwards}
@keyframes float{
0%{opacity:0;transform:translate(0,0) scale(.4) rotate(0)}
20%{opacity:1}
100%{opacity:0;transform:translate(var(--x),var(--y)) scale(1.05) rotate(var(--r))}
}
/* ---- LIKED! word ---- */
.liked{
position:absolute;z-index:7;left:50%;top:50%;
transform:translate(-50%,-50%);
font-size:34px;font-weight:900;letter-spacing:2px;
background:linear-gradient(90deg,#fff,#ffd166,#ff5c8a,#8ec5ff,#fff);
-webkit-background-clip:text;background-clip:text;color:transparent;
white-space:nowrap;opacity:0;pointer-events:none;
}
#like:checked ~ .btnzone .liked{animation:word 1.15s cubic-bezier(.2,1.5,.4,1) forwards}
@keyframes word{
0%{opacity:0;transform:translate(-50%,-50%) scale(.2) rotate(-12deg)}
30%{opacity:1;transform:translate(-50%,-90%) scale(1.25) rotate(6deg)}
60%{transform:translate(-50%,-120%) scale(1) rotate(-3deg)}
100%{opacity:0;transform:translate(-50%,-200%) scale(.9) rotate(0)}
}
/* ---- confetti rain ---- */
.confetti{position:absolute;z-index:4;inset:-30px;pointer-events:none;overflow:visible}
.cf{
position:absolute;top:-20px;left:var(--x);width:8px;height:15px;border-radius:2px;
background:var(--c);opacity:0;
}
#like:checked ~ .confetti .cf{animation:fall var(--dur) var(--dl) cubic-bezier(.3,.6,.5,1) forwards}
@keyframes fall{
0%{opacity:1;transform:translateY(-20px) rotate(0)}
100%{opacity:0;transform:translateY(340px) rotate(760deg)}
}
/* ---- screen flash ---- */
.flash{position:absolute;inset:0;z-index:8;border-radius:28px;pointer-events:none;opacity:0;
background:radial-gradient(circle at 50% 55%,rgba(255,255,255,.85),rgba(255,80,140,.35) 35%,transparent 70%)}
#like:checked ~ .flash{animation:flash .55s ease-out forwards}
@keyframes flash{0%{opacity:.9}100%{opacity:0}}
/* ---- avatars ---- */
.avatars{display:flex;justify-content:center;align-items:center;margin-top:26px;gap:0}
.av{
width:38px;height:38px;border-radius:50%;margin-left:-10px;
border:3px solid #14142a;box-shadow:0 6px 16px rgba(0,0,0,.4);
background:var(--g);display:grid;place-items:center;
font-size:15px;font-weight:800;color:#fff;
transition:transform .2s;
}
.av:first-child{margin-left:0}
.av.more{background:linear-gradient(135deg,#ff3d71,#ff9f1c);font-size:12px}
#like:checked ~ .avatars .av{animation:bounceIn .5s cubic-bezier(.2,1.6,.4,1) both}
#like:checked ~ .avatars .av:nth-child(2){animation-delay:.06s}
#like:checked ~ .avatars .av:nth-child(3){animation-delay:.12s}
#like:checked ~ .avatars .av:nth-child(4){animation-delay:.18s}
#like:checked ~ .avatars .av:nth-child(5){animation-delay:.24s}
@keyframes bounceIn{0%{transform:scale(0) translateY(14px)}100%{transform:scale(1) translateY(0)}}
.hint{margin-top:20px;font-size:12.5px;opacity:.5;letter-spacing:.4px}
.pill{
display:inline-block;margin-top:14px;padding:7px 16px;border-radius:999px;
font-size:12px;letter-spacing:.16em;text-transform:uppercase;font-weight:700;
background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);opacity:.7;
}
@media (max-width:420px){
h1{font-size:22px}
.stage{padding:26px 18px 24px}
.liked{font-size:27px}
}
</style>
</head>
<body>
<div class="stage" id="stage">
<input type="checkbox" id="like">
<p class="title">Pure CSS</p>
<h1>Like this post</h1>
<p class="sub">No JavaScript. Just a checkbox and a lot of keyframes.<br>Tap the button — try it twice.</p>
<div class="btnzone">
<div class="burst"></div>
<div class="ring r1"></div>
<div class="ring r2"></div>
<div class="ring r3"></div>
<div class="particles">
<span class="particle" style="--a:0deg;--d:120px;--c:#ff2d55"></span>
<span class="particle sq" style="--a:24deg;--d:140px;--c:#ff9f1c"></span>
<span class="particle" style="--a:48deg;--d:110px;--c:#ffe600"></span>
<span class="particle star" style="--a:72deg;--d:150px;--c:#39ff88"></span>
<span class="particle" style="--a:96deg;--d:125px;--c:#00d9ff"></span>
<span class="particle sq" style="--a:120deg;--d:145px;--c:#7b5cff"></span>
<span class="particle" style="--a:144deg;--d:115px;--c:#ff2d55"></span>
<span class="particle star" style="--a:168deg;--d:150px;--c:#ffd166"></span>
<span class="particle" style="--a:192deg;--d:125px;--c:#00d9ff"></span>
<span class="particle sq" style="--a:216deg;--d:140px;--c:#39ff88"></span>
<span class="particle" style="--a:240deg;--d:110px;--c:#ff9f1c"></span>
<span class="particle star" style="--a:264deg;--d:150px;--c:#ff2d55"></span>
<span class="particle" style="--a:288deg;--d:120px;--c:#7b5cff"></span>
<span class="particle sq" style="--a:312deg;--d:145px;--c:#ffe600"></span>
<span class="particle" style="--a:336deg;--d:115px;--c:#00d9ff"></span>
</div>
<div class="floaters">
<span class="fh" style="--c:#ff3d71;--x:-95px;--y:-125px;--r:-25deg"><svg viewBox="0 0 24 24"><path d="M12 21s-7.5-4.7-9.6-9.2C.6 8 2.2 4.6 5.4 3.6 7.5 3 9.6 3.6 12 6c2.4-2.4 4.5-3 6.6-2.4 3.2 1 4.8 4.4 3 8.2C19.5 16.3 12 21 12 21z"/></svg></span>
<span class="fh" style="--c:#ffd166;--x:92px;--y:-138px;--r:22deg;animation-delay:.08s"><svg viewBox="0 0 24 24"><path d="M12 21s-7.5-4.7-9.6-9.2C.6 8 2.2 4.6 5.4 3.6 7.5 3 9.6 3.6 12 6c2.4-2.4 4.5-3 6.6-2.4 3.2 1 4.8 4.4 3 8.2C19.5 16.3 12 21 12 21z"/></svg></span>
<span class="fh" style="--c:#7b5cff;--x:-58px;--y:-160px;--r:-14deg;animation-delay:.16s"><svg viewBox="0 0 24 24"><path d="M12 21s-7.5-4.7-9.6-9.2C.6 8 2.2 4.6 5.4 3.6 7.5 3 9.6 3.6 12 6c2.4-2.4 4.5-3 6.6-2.4 3.2 1 4.8 4.4 3 8.2C19.5 16.3 12 21 12 21z"/></svg></span>
<span class="fh" style="--c:#00d9ff;--x:60px;--y:-118px;--r:30deg;animation-delay:.24s"><svg viewBox="0 0 24 24"><path d="M12 21s-7.5-4.7-9.6-9.2C.6 8 2.2 4.6 5.4 3.6 7.5 3 9.6 3.6 12 6c2.4-2.4 4.5-3 6.6-2.4 3.2 1 4.8 4.4 3 8.2C19.5 16.3 12 21 12 21z"/></svg></span>
<span class="fh" style="--c:#39ff88;--x:0px;--y:-175px;--r:8deg;animation-delay:.32s"><svg viewBox="0 0 24 24"><path d="M12 21s-7.5-4.7-9.6-9.2C.6 8 2.2 4.6 5.4 3.6 7.5 3 9.6 3.6 12 6c2.4-2.4 4.5-3 6.6-2.4 3.2 1 4.8 4.4 3 8.2C19.5 16.3 12 21 12 21z"/></svg></span>
</div>
<span class="liked">LIKED!</span>
<label class="btn" for="like">
<span class="heart"><svg viewBox="0 0 24 24"><path d="M12 21s-7.5-4.7-9.6-9.2C.6 8 2.2 4.6 5.4 3.6 7.5 3 9.6 3.6 12 6c2.4-2.4 4.5-3 6.6-2.4 3.2 1 4.8 4.4 3 8.2C19.5 16.3 12 21 12 21z"/></svg></span>
<span class="n">
<span class="off"><b>1,204</b> likes</span>
<span class="on"><b>1,205</b> likes</span>
</span>
</label>
</div>
<div class="confetti">
<span class="cf" style="--x:6%;--c:#ff2d55;--dur:1.5s;--dl:0s"></span>
<span class="cf" style="--x:16%;--c:#ffd166;--dur:1.8s;--dl:.05s"></span>
<span class="cf" style="--x:27%;--c:#39ff88;--dur:1.4s;--dl:.12s"></span>
<span class="cf" style="--x:38%;--c:#00d9ff;--dur:1.7s;--dl:.02s"></span>
<span class="cf" style="--x:49%;--c:#7b5cff;--dur:1.6s;--dl:.1s"></span>
<span class="cf" style="--x:60%;--c:#ff9f1c;--dur:1.9s;--dl:.18s"></span>
<span class="cf" style="--x:71%;--c:#ff2d55;--dur:1.45s;--dl:.06s"></span>
<span class="cf" style="--x:82%;--c:#ffe600;--dur:1.75s;--dl:.14s"></span>
<span class="cf" style="--x:92%;--c:#00d9ff;--dur:1.55s;--dl:.09s"></span>
<span class="cf" style="--x:34%;--c:#ffd166;--dur:2s;--dl:.22s"></span>
<span class="cf" style="--x:66%;--c:#39ff88;--dur:1.85s;--dl:.26s"></span>
</div>
<div class="flash"></div>
<div class="avatars">
<div class="av" style="--g:linear-gradient(135deg,#ff9f1c,#ff2d55)">A</div>
<div class="av" style="--g:linear-gradient(135deg,#00d9ff,#7b5cff)">B</div>
<div class="av" style="--g:linear-gradient(135deg,#39ff88,#00d9ff)">C</div>
<div class="av" style="--g:linear-gradient(135deg,#ffd166,#ff9f1c)">D</div>
<div class="av more">+3</div>
</div>
<div class="hint">State lives in a hidden checkbox — click again to unlike.</div>
<div class="pill">0 bytes of JavaScript</div>
</div>
</body>
</html>Reasoning trace (1,439 tokens)
Build a pure CSS like button with crazy animation. No JS. Use checkbox hack for toggle state.
Design: a heart button that when clicked, explodes with particles, rings, confetti, text "LIKED!", floating hearts, color burst, shake, etc.
Let's make a nice card with the button. Use a hidden checkbox + label.
Animation triggering: use CSS animations with `animation` on sibling elements triggered by `:checked`. Need restarts: use `animation` that plays on checked; toggling off and on restarts.
Let me construct:
```html
<div class="stage">
<input type="checkbox" id="like" class="sr">
<div class="wrap">
<label for="like" class="btn">
<svg heart/>
<span class="count">1,204</span>
</label>
... particles
</div>
</div>
```
Since checkbox must be before siblings for `~` selector. Place input at top of stage, then all elements siblings.
Particles: 12 spans radiating with different angles via CSS variables set inline style (style="--a:30deg"). Inline styles are fine (pure CSS means no JS).
Crazy animation:
- heart scales and rotates
- radial shockwave rings expand
- 14 particles burst outward
- confetti strips fall
- floating hearts rise
- badge "LIKED!" pops
- background radial burst
- card shakes
- screen flash
Also add a hover state, and non-checked default state with a subtle pulse.
Count text: keep static "1,204"; on liked show "1,205". Use two spans, opacity swap.
Let's write it carefully.
Keyframes burst for particles: from transform translate(0,0) rotate(0) scale(0) to translate(cos*dist) etc. Use --a and --d; compute with cos/sin in calc: `calc(var(--d) * cos(var(--a)))` — trig functions supported in modern Chrome (cos/sin in calc since Chrome 111). Should be fine but safer: precompute per particle with transform: rotate(var(--a)) translateX(var(--d)) applied to element then animate opacity/scale. Simpler: each particle is a span with `transform: rotate(var(--a)) translateX(var(--d))`. Animate from scale(0) to scale(1) keeping the transform? Animation on transform overrides. Instead: outer element handles rotation/translate statically? Animation must move it.
Approach: particle element has animation `p` where keyframes use `translate(0) rotate(var(--a)) translateX(var(--d))`. Since transform in keyframes can use var with rotate: `transform: rotate(var(--a)) translateX(calc(var(--d)*1))`. Keyframes:
```
@keyframes p {
0% { transform: rotate(var(--a)) translateX(0) scale(.2); opacity:0 }
40% { opacity:1 }
100% { transform: rotate(var(--a)) translateX(var(--d)) scale(.1); opacity:0 }
}
```
with --d like 120px. Plus the particle itself small circle colored. Good, no trig needed.
But rotate(var(--a)) translateX(dir) – particle moves outward at angle a. Good.
Also confetti: strips falling with rotate.
Floating hearts: rising with wobble.
Shockwave rings: ::before/::after on a .rings div scaling.
Also a big "burst" background: a div with radial-gradient that scales and fades.
Also starburst lines? Let's include a "sparkle" set.
Let's write HTML.
Also need "click to start" not needed since no keyboard.
Card shake: animation on .card when checked.
Text "LIKED!" floating up.
Also clicking again unlikes — animations reverse/restart.
Let me also make the heart SVG with fill change via CSS on checked.
Write code.
For accessibility, label for checkbox.
Layout: centered stage, gradient background, card with title, button, count, avatars row.
Let me produce final HTML.
Details of heart: use SVG path with heart shape:
`<svg viewBox="0 0 24 24"><path d="M12 21s-7.5-4.7-9.6-9.2C.6 8 2.2 4.6 5.4 3.6 7.5 3 9.6 3.6 12 6c2.4-2.4 4.5-3 6.6-2.4 3.2 1 4.8 4.4 3 8.2C19.5 16.3 12 21 12 21z"/></svg>` fine.
Animation on heart svg: pop with rotate jiggle.
Add "boom" flash overlay across stage.
Let me write the CSS fully.
```css
*{box-sizing:border-box}
body{margin:0;height:100vh;display:grid;place-items:center;font-family:system-ui...;background:#0b0b1a; overflow:hidden}
.stage{position:relative;width:min(420px,92vw);padding:40px 28px;...}
```
I'll make card with glassy look.
Particles markup: 16 spans in .particles, each with style="--a:22.5deg;--d:130px;--c:#ff4d6d". Actually generate inline styles manually for 16 angles: 22.5*k.
Colors alternate.
Confetti: 10 strips with --x offsets and --dl.
Let me just write it.
Also a ring element with border.
Flash: .flash div with background radial gradient, animation.
Ensure "crazy": add multiple rings with different delays, rainbow ring, spinning conic burst behind button, screen shake.
Conic burst: .burst with background conic-gradient with rainbow, mask radial circle, scale up + rotate fast while fading. Nice.
Let's write final.
Also show count increment: two spans .n1/.n2 overlapping, toggle opacity.
Avatar row: circles with gradients and a "+3" avatar that pops.
Let me write code now.
Keyframes shake card: translate combos.
Ok, output.
One thing: the .burst conic gradient rotated. Use `background: conic-gradient(from 0deg, red, orange, ...)`, border-radius 50%, mask-image radial-gradient(circle, black 40%, transparent 70%) — use -webkit-mask too.
Burst animation: from scale(.3) rotate(0) opacity .9 to scale(2.2) rotate(140deg) opacity 0.
Fine. Write.
For float hearts rising, need position absolute above button with animation float 1.4s forwards.
Let's finalize code.