Models 44

GLM 5.3

by Z.aiReasoningClean
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
12 min 31 s
Cost
$0.118
Output tokens
60,051
Spent thinking
51,938 tokens
Speed
80.1 tok/s
Console errors
0
First token after
1.4 s
First visible text after
11 min 26 s
Prompt tokens
356
Code size
22.1 KB
Finish reason
stop
Served by
Decart
Model id
z-ai/glm-5.3
Reasoning sent
{"effort":"max"}
Max output
943,718 tokens
Generated
Nov 12, 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 · 450 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Like it. Loudly. — a pure-CSS like button</title>
<style>
/* =====================================================================
   A LIKE BUTTON — 100% CSS. There is no <script> on this page. At all.
   The whole trick: one <input type="checkbox"> + :checked + a truly
   unreasonable number of @keyframes.
   ===================================================================== */

:root{
  --heart: path("M50 86C26 66 4 48 4 26.5C4 13 15 3 28 3C37.6 3 45.6 8.4 50 17.5C54.4 8.4 62.4 3 72 3C85 3 96 13 96 26.5C96 48 74 66 50 86Z");
  --pink:#ff2d6f; --pink-soft:#ff5c8a; --gold:#ffc24b; --violet:#7c5cff;
}

*{box-sizing:border-box;margin:0;padding:0}
html{color-scheme:dark;overflow-x:hidden}
body{
  min-height:100vh;overflow-x:hidden;
  background:#0d0a1e;color:#efeaff;
  font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  -webkit-font-smoothing:antialiased;
}
::selection{background:var(--pink);color:#fff}

/* the man behind the curtain */
#like{position:fixed;top:0;left:0;width:1px;height:1px;opacity:0;pointer-events:none}

/* ============ scene / ambient background ============ */
.scene{
  position:relative;z-index:1;min-height:100vh;
  display:flex;flex-direction:column;align-items:center;
  justify-content:center;justify-content:safe center;
  gap:26px;padding:44px 18px 80px;
}
.bg{
  position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;
  background:
    radial-gradient(900px 520px at 78% -10%, #1d1546 0%, rgba(29,21,70,0) 62%),
    radial-gradient(820px 620px at 10% 110%, #171040 0%, rgba(23,16,64,0) 58%),
    #0d0a1e;
}
.blob{position:absolute;border-radius:50%;filter:blur(80px)}
.b1{width:44vw;height:44vw;min-width:340px;min-height:340px;background:var(--pink);opacity:.30;top:-12%;left:-10%;animation:blobdrift 19s ease-in-out -4s infinite alternate}
.b2{width:38vw;height:38vw;min-width:300px;min-height:300px;background:#5a45ff;opacity:.28;top:16%;right:-12%;animation:blobdrift 23s ease-in-out -11s infinite alternate-reverse}
.b3{width:40vw;height:40vw;min-width:320px;min-height:320px;background:#ff8a3d;opacity:.16;bottom:-16%;left:34%;animation:blobdrift 27s ease-in-out -18s infinite alternate}

/* faint hearts drifting up forever (the page breathes before you click) */
.floaters{position:absolute;inset:0}
.f{
  position:absolute;bottom:-70px;left:var(--x);opacity:0;
  width:calc(100px * var(--sc,.14));height:calc(90px * var(--sc,.14));
  animation:rise var(--t,15s) linear var(--dl,0s) infinite;
}
.f:nth-of-type(1){--x:8%; --t:15s;  --dl:-2.5s; --sc:.16; --c:rgba(255,92,138,.17)}
.f:nth-of-type(2){--x:19%; --t:19s;  --dl:-11s;  --sc:.11; --c:rgba(255,194,75,.14)}
.f:nth-of-type(3){--x:33%; --t:12.5s;--dl:-5s;   --sc:.20; --c:rgba(255,92,138,.13)}
.f:nth-of-type(4){--x:50%; --t:17s;  --dl:-13s;  --sc:.13; --c:rgba(150,120,255,.15)}
.f:nth-of-type(5){--x:66%; --t:14s;  --dl:-8s;   --sc:.18; --c:rgba(255,92,138,.10)}
.f:nth-of-type(6){--x:81%; --t:18s;  --dl:-4s;    --sc:.12; --c:rgba(255,194,75,.12)}
.f:nth-of-type(7){--x:92%; --t:13s;  --dl:-9.5s; --sc:.15; --c:rgba(255,92,138,.15)}

/* the tiny heart shape, reused everywhere */
.mh{display:block;width:100px;height:90px;clip-path:var(--heart);background:var(--c,var(--pink))}
.f .mh{transform:scale(var(--sc,.14));transform-origin:0 0}

/* ============ header ============ */
.head{position:relative;z-index:1;text-align:center;max-width:680px;padding:0 6px}
.overline{font-size:11px;font-weight:700;letter-spacing:.34em;text-transform:uppercase;color:var(--pink-soft);margin-bottom:14px}
h1{font-size:clamp(2.2rem,6vw,3.7rem);font-weight:800;letter-spacing:-.035em;line-height:1.05;color:#f4efff;margin-bottom:14px}
h1 em{
  font-style:normal;
  background:linear-gradient(92deg,#ff5c8a 10%,#ff9a3d 55%,#ffc24b 90%);
  -webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent;
}
.sub{font-size:15px;line-height:1.65;color:#9a90bb;max-width:52ch;margin:0 auto}
.head code,.foot code{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.85em;
  background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.06);
  padding:1px 6px;border-radius:6px;color:#cbbaff;
}

/* ============ the card (the whole card is the <label>) ============ */
.card{
  position:relative;z-index:1;
  display:flex;flex-direction:column;align-items:center;gap:18px;
  padding:44px 58px 36px;border-radius:32px;
  background:#191231;border:1px solid rgba(255,255,255,.07);
  box-shadow:0 40px 90px -30px rgba(0,0,0,.75);
  cursor:pointer;user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;
  transition:transform .5s cubic-bezier(.22,1.2,.36,1),border-color .5s ease,box-shadow .5s ease;
}

/* the button core: circle + every effect layer anchored to it */
.core{position:relative;width:150px;height:150px}
.circle{
  position:absolute;inset:0;z-index:4;border-radius:50%;
  background:#241c3f;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.06);
  display:grid;place-items:center;
  transition:transform .18s ease,box-shadow .55s ease;
}
.card:active .circle{transform:scale(.93)}
.circle::after{ /* idle "come click me" pulse */
  content:"";position:absolute;inset:-10px;border-radius:50%;
  border:2px solid rgba(255,255,255,.3);pointer-events:none;
  animation:ping 2.8s cubic-bezier(.2,.6,.35,1) infinite;
}

/* the heart, drawn with a single clip-path, stacked in layers */
.hpos{
  position:relative;width:100px;height:90px;
  filter:drop-shadow(0 10px 24px rgba(255,45,111,0)) drop-shadow(0 0 60px rgba(255,45,111,0));
  transition:filter .5s ease;
}
.heart-wrap{position:absolute;inset:0;transform-origin:50% 62%;animation:heartbeat 3s ease-in-out infinite}
.heart{position:absolute;inset:0;clip-path:var(--heart)}
.h-outline{background:#716a92;transition:background .25s ease,opacity .18s ease}
.card:hover .h-outline{background:#c9c0e8}
.h-cut{background:#241c3f;transform:scale(.88)}                    /* carves the outline */
.h-fill{
  background:
    radial-gradient(60% 60% at 32% 26%, rgba(255,255,255,.38), rgba(255,255,255,0) 62%),
    linear-gradient(160deg,#ff7eb3 0%,#ff2d55 55%,#c9184a 100%);
  transform:scale(0);transform-origin:50% 82%;
  transition:transform .55s cubic-bezier(.3,1.85,.45,1);           /* springy fill/unfill */
}
.h-shine{
  background:linear-gradient(100deg,rgba(255,255,255,0) 40%,rgba(255,255,255,.95) 50%,rgba(255,255,255,0) 60%);
  background-size:300% 100%;background-position:0% 0;opacity:0;
}

/* ============ effect layers (all fired by :checked) ============ */
.boom{
  position:absolute;left:50%;top:50%;width:560px;height:560px;margin:-280px 0 0 -280px;
  border-radius:50%;z-index:1;pointer-events:none;opacity:0;transform:scale(.45);
  background:radial-gradient(circle closest-side,rgba(255,77,140,.55),rgba(255,77,140,.16) 46%,rgba(255,77,140,0) 72%);
}
.rays{
  position:absolute;left:50%;top:50%;width:320px;height:320px;margin:-160px 0 0 -160px;
  border-radius:50%;z-index:2;pointer-events:none;opacity:0;transform:scale(.2);
  background:repeating-conic-gradient(rgba(255,190,215,.9) 0deg 5deg,rgba(255,190,215,0) 5deg 16deg);
  -webkit-mask:radial-gradient(closest-side,#000 24%,transparent 72%);
          mask:radial-gradient(closest-side,#000 24%,transparent 72%);
}
.rings{position:absolute;inset:0;z-index:3;pointer-events:none}
.rings i{
  position:absolute;left:50%;top:50%;width:150px;height:150px;margin:-75px 0 0 -75px;
  border-radius:50%;border:3px solid;opacity:0;transform:scale(.5);
}
.rings i:nth-of-type(1){border-color:var(--pink)}
.rings i:nth-of-type(2){border-color:var(--gold)}
.rings i:nth-of-type(3){border-color:rgba(255,255,255,.85)}

.burst{position:absolute;inset:0;z-index:6;pointer-events:none}
.burst i{position:absolute;left:50%;top:50%;opacity:0;transform:translate(-50%,-50%) scale(0)}
.burst .c{width:11px;height:11px;border-radius:50%;background:var(--c,var(--pink))}
.burst .t{width:6px;height:18px;border-radius:3px;background:var(--c,var(--gold))}
.burst .s{width:16px;height:16px;background:var(--c,#fff);clip-path:polygon(50% 0,61% 39%,100% 50%,61% 61%,50% 100%,39% 61%,0 50%,39% 39%)}
.burst .mh{--s:.16}
.burst i:nth-of-type(1) {--tx:150px; --ty:0px;    --c:var(--pink)}
.burst i:nth-of-type(2) {--tx:169px; --ty:62px;   --rot:260deg;  --c:var(--gold)}
.burst i:nth-of-type(3) {--tx:103px; --ty:87px;   --rot:180deg;  --c:#fff}
.burst i:nth-of-type(4) {--tx:82px;  --ty:143px;  --rot:120deg;  --c:var(--pink);   --dl:.03s}
.burst i:nth-of-type(5) {--tx:25px;  --ty:143px;  --c:var(--gold)}
.burst i:nth-of-type(6) {--tx:-30px; --ty:172px;  --rot:-300deg; --c:var(--pink)}
.burst i:nth-of-type(7) {--tx:-24px; --ty:138px;  --rot:-160deg; --c:var(--pink-soft)}
.burst i:nth-of-type(8) {--tx:-153px;--ty:54px;   --rot:-140deg; --c:var(--pink-soft);--dl:.05s}
.burst i:nth-of-type(9) {--tx:-141px;--ty:0px;    --c:#fff}
.burst i:nth-of-type(10){--tx:-127px;--ty:-46px;  --rot:340deg;  --c:var(--violet)}
.burst i:nth-of-type(11){--tx:-132px;--ty:-109px; --rot:200deg;  --c:var(--gold)}
.burst i:nth-of-type(12){--tx:-72px; --ty:-126px; --rot:160deg;  --c:var(--gold);   --dl:.04s}
.burst i:nth-of-type(13){--tx:-28px; --ty:-158px; --c:var(--pink)}
.burst i:nth-of-type(14){--tx:24px;  --ty:-138px; --rot:-260deg; --c:#fff}
.burst i:nth-of-type(15){--tx:30px;  --ty:-172px; --rot:-200deg; --c:var(--gold)}
.burst i:nth-of-type(16){--tx:75px;  --ty:-130px; --rot:-120deg; --c:#c81d5e;      --dl:.06s}
.burst i:nth-of-type(17){--tx:126px; --ty:-106px; --c:var(--violet)}
.burst i:nth-of-type(18){--tx:136px; --ty:-49px;  --rot:300deg;  --c:var(--pink-soft)}

.emo{position:absolute;inset:0;z-index:7;pointer-events:none}
.emo span{
  position:absolute;left:50%;top:50%;display:block;font-size:30px;line-height:1;
  opacity:0;transform:translate(-50%,-50%) scale(0);
}
.emo span:nth-child(1){--tx:-120px;--ty:-105px;--dl:.02s}
.emo span:nth-child(2){--tx:115px; --ty:-115px;--dl:.07s}
.emo span:nth-child(3){--tx:150px; --ty:10px;  --dl:.12s}
.emo span:nth-child(4){--tx:-150px;--ty:25px;  --dl:.17s}
.emo span:nth-child(5){--tx:-70px; --ty:-140px;--dl:.22s}
.emo span:nth-child(6){--tx:70px;  --ty:120px;  --dl:.27s}

.plusone{
  position:absolute;left:50%;top:-2px;z-index:8;pointer-events:none;
  font-size:19px;font-weight:800;color:var(--gold);
  text-shadow:0 2px 12px rgba(255,194,75,.5);
  opacity:0;transform:translate(-50%,12px) scale(.5);
}

/* ============ caption (Like/Liked · 1,024/1,025) ============ */
.caption{display:flex;align-items:center;gap:9px;font-size:15px;margin-top:2px}
.swap{display:grid;overflow:hidden}
.swap>span{grid-area:1/1;display:block;line-height:1.35;white-space:nowrap;
  transition:transform .45s cubic-bezier(.22,.9,.32,1.12),opacity .3s ease}
.swap .b{transform:translateY(112%);opacity:0}
.word .a{color:#bdb3dc;font-weight:600}
.word .b{color:var(--pink-soft);font-weight:700}
.count{font-variant-numeric:tabular-nums}
.count .a{color:#8f86ad}
.count .b{color:var(--gold);font-weight:700}
.sep{color:#665e86}

.hint{position:relative;z-index:1;display:grid;text-align:center;font-size:13px;color:#837aa4}
.hint>span{grid-area:1/1;transition:opacity .35s ease,transform .35s ease}
.hint .b{opacity:0;transform:translateY(8px)}

.foot{
  position:absolute;bottom:16px;left:0;right:0;z-index:1;text-align:center;
  font-size:11.5px;color:#8f86ad;padding:0 14px;letter-spacing:.02em;
}

/* ============ full-screen confetti & emoji rain ============ */
.rain{position:fixed;inset:0;z-index:80;overflow:hidden;pointer-events:none}
.drop{position:absolute;top:-8%;left:var(--x);opacity:0}
.drop i{display:block;font-style:normal;font-size:var(--fs,24px);line-height:1}
.drop.t i{width:9px;height:16px;border-radius:2px;background:var(--c,var(--pink))}
.rain .drop:nth-of-type(1) {--x:6%; --fs:26px;--dur:1.3s; --dl:.02s;--sw:44px; --spin:340deg}
.rain .drop:nth-of-type(2) {--x:14%;--c:var(--pink);  --dur:1.15s;--dl:.12s;--sw:-52px;--spin:-420deg}
.rain .drop:nth-of-type(3) {--x:24%;--fs:20px;--dur:1.45s;--dl:.05s;--sw:60px; --spin:520deg}
.rain .drop:nth-of-type(4) {--x:33%;--fs:24px;--dur:1.2s; --dl:.18s;--sw:-42px;--spin:-300deg}
.rain .drop:nth-of-type(5) {--x:44%;--c:var(--gold);  --dur:1.05s;--dl:.08s;--sw:56px; --spin:460deg}
.rain .drop:nth-of-type(6) {--x:52%;--fs:28px;--dur:1.35s;--dl:0s;  --sw:-60px;--spin:-380deg}
.rain .drop:nth-of-type(7) {--x:61%;--c:var(--violet);--dur:1.15s;--dl:.22s;--sw:46px; --spin:400deg}
.rain .drop:nth-of-type(8) {--x:70%;--fs:22px;--dur:1.25s;--dl:.1s; --sw:-56px;--spin:-500deg}
.rain .drop:nth-of-type(9) {--x:78%;--fs:26px;--dur:1.1s; --dl:.16s;--sw:50px; --spin:340deg}
.rain .drop:nth-of-type(10){--x:86%;--c:#fff;       --dur:1.3s; --dl:.06s;--sw:-46px;--spin:-460deg}
.rain .drop:nth-of-type(11){--x:93%;--fs:24px;--dur:1.2s; --dl:.13s;--sw:62px; --spin:380deg}
.rain .drop:nth-of-type(12){--x:40%;--fs:18px;--dur:1.5s; --dl:.2s; --sw:-70px;--spin:-350deg}

/* =====================================================================
   THE PARTY — everything below fires the instant the box is :checked
   (and re-fires every time you re-like it, because of course it does)
   ===================================================================== */
#like:checked ~ .scene{animation:shake .55s cubic-bezier(.36,.07,.19,.97) both}
#like:checked ~ .scene .bg{animation:hueflash 1s ease-out}

#like:checked ~ .scene .card{
  transform:translateY(-6px);
  border-color:rgba(255,92,138,.42);
  box-shadow:0 40px 90px -30px rgba(0,0,0,.75),0 0 80px -14px rgba(255,45,111,.5);
}
#like:checked ~ .scene .circle{
  box-shadow:inset 0 0 0 1px rgba(255,92,138,.35),0 0 46px rgba(255,45,111,.55),0 18px 60px -18px rgba(255,45,111,.6);
}
#like:checked ~ .scene .circle::after{animation:none;opacity:0}

#like:checked ~ .scene .h-outline,
#like:checked ~ .scene .h-cut{opacity:0}
#like:checked ~ .scene .h-fill{transform:scale(1)}
#like:checked ~ .scene .h-shine{animation:sweep .8s ease-out .12s forwards}
#like:checked ~ .scene .heart-wrap{
  animation:pop .85s cubic-bezier(.26,1.5,.42,1) both,heartbeat 3s ease-in-out 1.3s infinite;
}
#like:checked ~ .scene .hpos{
  filter:drop-shadow(0 12px 28px rgba(255,45,111,.55)) drop-shadow(0 0 64px rgba(255,45,111,.42));
}

#like:checked ~ .scene .caption{animation:capbounce .6s ease-out}
#like:checked ~ .scene .swap .a{transform:translateY(-112%);opacity:0}
#like:checked ~ .scene .swap .b{transform:translateY(0);opacity:1}
#like:checked ~ .scene .hint .a{opacity:0;transform:translateY(-8px)}
#like:checked ~ .scene .hint .b{opacity:1;transform:translateY(0)}

#like:checked ~ .scene .boom{animation:boomout .95s ease-out forwards}
#like:checked ~ .scene .rays{animation:rayburst .75s ease-out forwards}
#like:checked ~ .scene .rings i:nth-of-type(1){animation:ringout .75s cubic-bezier(.17,.67,.35,1) forwards}
#like:checked ~ .scene .rings i:nth-of-type(2){animation:ringout .85s cubic-bezier(.17,.67,.35,1) .08s forwards}
#like:checked ~ .scene .rings i:nth-of-type(3){animation:ringout 1s   cubic-bezier(.17,.67,.35,1) .17s forwards}
#like:checked ~ .scene .burst i{animation:fly .95s cubic-bezier(.16,.64,.38,1) var(--dl,0s) forwards}
#like:checked ~ .scene .emo span{animation:ringpop 1s cubic-bezier(.2,.75,.35,1) var(--dl,0s) forwards}
#like:checked ~ .scene .plusone{animation:plusrise 1s ease-out .1s forwards}
#like:checked ~ .rain .drop{animation:fall var(--dur,1.2s) cubic-bezier(.3,.45,.6,1) var(--dl,0s) forwards}

/* keyboard users get a party too */
#like:focus-visible ~ .scene .card{outline:3px dashed rgba(255,92,138,.9);outline-offset:5px}

/* ============ keyframes ============ */
@keyframes heartbeat{0%,100%{transform:scale(1)}12%{transform:scale(1.12)}24%{transform:scale(1)}36%{transform:scale(1.07)}48%{transform:scale(1)}}
@keyframes pop{
  0%{transform:scale(.85) rotate(0deg)}
  30%{transform:scale(1.25) rotate(7deg)}
  50%{transform:scale(.9) rotate(-6deg)}
  72%{transform:scale(1.14) rotate(4deg)}
  100%{transform:scale(1) rotate(0deg)}
}
@keyframes sweep{0%{background-position:0% 0;opacity:1}70%{opacity:1}100%{background-position:100% 0;opacity:0}}
@keyframes ringout{0%{transform:scale(.5);opacity:1}100%{transform:scale(2.15);opacity:0}}
@keyframes rayburst{0%{transform:scale(.2) rotate(-10deg);opacity:0}18%{opacity:.9}100%{transform:scale(1.2) rotate(12deg);opacity:0}}
@keyframes boomout{0%{transform:scale(.45);opacity:0}22%{opacity:1}100%{transform:scale(1.08);opacity:0}}
@keyframes fly{
  0%{transform:translate(-50%,-50%) translate(0,0) scale(0) rotate(0deg);opacity:1}
  55%{opacity:1}
  100%{transform:translate(-50%,-50%) translate(var(--tx),var(--ty)) scale(var(--s,1)) rotate(var(--rot,0deg));opacity:0}
}
@keyframes ringpop{
  0%{transform:translate(-50%,-50%) translate(0,0) scale(0) rotate(0deg);opacity:1}
  60%{opacity:1}
  70%{transform:translate(-50%,-50%) translate(calc(var(--tx)*.8),calc(var(--ty)*.8)) scale(1.15) rotate(8deg);opacity:1}
  100%{transform:translate(-50%,-50%) translate(var(--tx),var(--ty)) scale(.5) rotate(-14deg);opacity:0}
}
@keyframes plusrise{
  0%{transform:translate(-50%,12px) scale(.5);opacity:0}
  25%{opacity:1}
  100%{transform:translate(-50%,-62px) scale(1);opacity:0}
}
@keyframes capbounce{0%,100%{transform:scale(1)}40%{transform:scale(1.09)}70%{transform:scale(.97)}}
@keyframes shake{
  0%,100%{transform:translate(0,0) rotate(0deg)}
  10%{transform:translate(-7px,4px) rotate(-.5deg)}
  20%{transform:translate(7px,-5px) rotate(.5deg)}
  35%{transform:translate(-8px,-3px) rotate(-.4deg)}
  50%{transform:translate(8px,4px) rotate(.45deg)}
  65%{transform:translate(-6px,2px) rotate(-.3deg)}
  80%{transform:translate(5px,-3px) rotate(.25deg)}
  90%{transform:translate(-3px,2px) rotate(-.15deg)}
}
@keyframes hueflash{
  0%{filter:hue-rotate(0deg) saturate(1)}
  35%{filter:hue-rotate(-28deg) saturate(1.45)}
  100%{filter:hue-rotate(0deg) saturate(1)}
}
@keyframes fall{
  0%{transform:translate(0,-6vh) rotate(0deg);opacity:1}
  50%{transform:translate(calc(var(--sw,40px)*-1),46vh) rotate(calc(var(--spin,360deg)/2))}
  85%{opacity:1}
  100%{transform:translate(var(--sw,40px),104vh) rotate(var(--spin,360deg));opacity:0}
}
@keyframes rise{
  0%{transform:translate(0,0) rotate(0deg);opacity:0}
  8%{opacity:1}
  25%{transform:translate(26px,-27vh) rotate(10deg)}
  50%{transform:translate(-20px,-54vh) rotate(-9deg)}
  75%{transform:translate(24px,-81vh) rotate(8deg)}
  88%{opacity:1}
  100%{transform:translate(-12px,-108vh) rotate(-7deg);opacity:0}
}
@keyframes blobdrift{from{transform:translate(0,0) scale(1)}to{transform:translate(60px,-42px) scale(1.18)}}
@keyframes ping{0%{transform:scale(1);opacity:.55}75%,100%{transform:scale(1.24);opacity:0}}

/* ============ responsive & kindness ============ */
@media (max-width:540px){
  .scene{gap:20px;padding:32px 12px 64px}
  .card{padding:34px 18px 28px;border-radius:26px}
  .sub{font-size:13.5px}
  .overline{letter-spacing:.26em}
  .emo span{font-size:24px}
  .plusone{font-size:16px}
  .foot{font-size:10.5px}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.15s !important}
}
</style>
</head>
<body>

<!-- the entire engine of this page -->
<input type="checkbox" id="like" aria-label="Like — set off the pure-CSS party">

<div class="scene">
  <div class="bg" aria-hidden="true">
    <span class="blob b1"></span>
    <span class="blob b2"></span>
    <span class="blob b3"></span>
    <div class="floaters" aria-hidden="true">
      <span class="f"><i class="mh"></i></span>
      <span class="f"><i class="mh"></i></span>
      <span class="f"><i class="mh"></i></span>
      <span class="f"><i class="mh"></i></span>
      <span class="f"><i class="mh"></i></span>
      <span class="f"><i class="mh"></i></span>
      <span class="f"><i class="mh"></i></span>
    </div>
  </div>

  <header class="head">
    <p class="overline">✦ 100% css · 0% javascript ✦</p>
    <h1>Like it. <em>Loudly.</em></h1>
    <p class="sub">One checkbox, one label, and an absolutely unreasonable number of <code>@keyframes</code>. Click the heart. Then click it again. It never gets old.</p>
  </header>

  <label class="card" for="like">
    <span class="core">
      <span class="boom" aria-hidden="true"></span>
      <span class="rays" aria-hidden="true"></span>
      <span class="rings" aria-hidden="true"><i></i><i></i><i></i></span>
      <span class="burst" aria-hidden="true">
        <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
        <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
        <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
        <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
        <i class="c"></i><i class="t"></i>
      </span>
      <span class="emo" aria-hidden="true"><span>🎉</span><span>✨</span><span>💖</span><span>🥳</span><span>💯</span><span>🌟</span></span>
      <span class="plusone" aria-hidden="true">+1</span>
      <span class="circle">
        <span class="hpos">
          <span class="heart-wrap">
            <span class="heart h-outline"></span>
            <span class="heart h-cut"></span>
            <span class="heart h-fill"></span>
            <span class="heart h-shine"></span>
          </span>
        </span>
      </span>
    </span>
    <span class="caption">
      <span class="swap word"><span class="a">Like</span><span class="b">Liked</span></span>
      <span class="sep">·</span>
      <span class="swap count"><span class="a">1,024</span><span class="b">1,025</span></span>
    </span>
  </label>

  <p class="hint">
    <span class="a">psst — the heart is clickable ↑</span>
    <span class="b">ok, wow. click again to un-like it ↓</span>
  </p>

  <footer class="foot">0 <code>&lt;script&gt;</code> tags · 1 checkbox · <code>:checked</code> + <code>@keyframes</code> did all of this</footer>
</div>

<div class="rain" aria-hidden="true">
  <span class="drop"><i>🎉</i></span>
  <span class="drop t"><i></i></span>
  <span class="drop"><i>✨</i></span>
  <span class="drop"><i>💖</i></span>
  <span class="drop t"><i></i></span>
  <span class="drop"><i>🥳</i></span>
  <span class="drop t"><i></i></span>
  <span class="drop"><i>💯</i></span>
  <span class="drop"><i>🌟</i></span>
  <span class="drop t"><i></i></span>
  <span class="drop"><i>🎊</i></span>
  <span class="drop"><i>💘</i></span>
</div>

</body>
</html>
Reasoning trace (51,938 tokens)
The user wants a "like" button in pure CSS, no JavaScript, that does a crazy animation when you click it. This means I need to use the `:active` pseudo-class or a checkbox hack (input + label) to trigger the animation. The checkbox hack allows a persistent "liked" state with animations triggered via `:checked`. But `:active` only lasts while the mouse is held down.

Actually, the best pure-CSS approach for a click-triggered animation that plays fully is the checkbox hack: `<input type="checkbox" id="like">` + `<label for="like">`. When checked, we can trigger keyframe animations that play once (animation-fill-mode, etc.). Unchecking and re-checking replays the animation (since the animation is applied when :checked matches, toggling off removes it, toggling on re-applies → restarts).

"Crazy animation" — let's go all out: heart bursts into particles, shockwave rings, confetti, emoji rain, screen shake, count increment (via CSS counters we can increment the displayed number using a counter set on :checked... Actually we can use CSS counters: `counter-increment` on the checked input's siblings? Hmm, counters work in CSS content. We could have the count displayed as `content: counter(likes)` and increment when checked. Let me think: with checkbox hack, we can't easily increment repeatedly since it's a toggle. But we can show "1" vs "0" simply. Or use a counter trick: the input itself can have `counter-increment` when checked, and the label uses that counter in ::after content. Actually counter-increment on the hidden input still counts in the DOM tree. Yes! `input:checked { counter-increment: likes; }` and then `.count::after { content: counter(likes); }`. That works in Chrome. The counter increments each time... wait, no — counter-increment applies once regardless. When checked, it increments by 1; when unchecked, the increment no longer applies so it goes back to 0. So the count toggles between 0 and 1. That's fine — like/unlike.

Actually we could do a cute "13.4K → 13.5K" flip. Simpler: 0 → 1, or show a number that changes.

Design goals:
- Must look great on first paint (screenshot at 3s): a beautiful centered like button with a heart, nice typography, gradient/dark background, maybe floating ambient hearts in background (pure CSS animations).
- Clicking the heart triggers: heart pops (scale bounce, color fill), shockwave rings expanding, particle explosion (many small hearts/dots flying outward via nth-child transforms), confetti rain, background flash, text change, screen shake maybe, and emoji burst like "🎉❤️✨".

All in pure CSS via checkbox hack.

Constraints note: "Games must start in self-playing demo mode" — that's for games; this isn't a game, so no need. But something meaningful visible on first paint: yes, the button itself plus ambient animation.

No JS at all — the requirement explicitly says no JavaScript. So zero <script>. Fine.

Layout: full viewport, dark aesthetic background with animated ambient hearts floating. Center: a card-ish area or just the button standalone. Big heart button. Below: "Like" text and count.

Let me design the explosion:

Structure:
```html
<input type="checkbox" id="like" class="like-input">
<label for="like" class="stage">
  <span class="ring ring-1"></span>
  <span class="ring ring-2"></span>
  <span class="ring ring-3"></span>
  <span class="burst">
    <i></i> × ~14 (particles with nth-child angles)
  </span>
  <span class="heart-wrap">
    <svg heart? or pure CSS heart>
  </span>
  <span class="shock-glow"></span>
</label>
<div class="caption">
  <span class="like-word">Like</span>
  <span class="count"></span>
</div>
```

Wait — the label needs `for="like"`. Elements inside a label also toggle it, fine.

Heart shape: pure CSS heart via rotated squares, or inline SVG. Inline SVG is fine (self-contained, no external). I'll use an SVG path heart for crispness, but CSS heart with pseudo-elements is also "pure CSS" spirit. SVG is still no-JS. I'll use an SVG heart inside the button — actually let me do a CSS heart (two pseudo-elements) to be extra pure? SVG path is cleaner and scales. Either is fine. I'll use an inline SVG heart; it's still pure CSS-driven animation (transitions on the checkbox state). Hmm, the ask is "pure CSS, no JavaScript" — inline SVG markup is HTML, not JS, so it's fine. But to be safe/purist, a CSS heart is a nice flourish. Let me do CSS heart: a span with ::before/::after rotated squares. Classic:

```css
.heart { width: 60px; height: 54px; position: relative; }
.heart::before, .heart::after {
  content:""; position:absolute; width:30px; height:48px; background:currentColor; border-radius: 30px 30px 0 0; top:0;
}
.heart::before { left:30px; transform: rotate(-45deg); transform-origin: 0 100%; }
.heart::after { left:0; transform: rotate(45deg); transform-origin: 100% 100%; }
```

Hmm, the classic heart: container relative, ::before and ::after absolute at top:0, left with 50% offset; rotate ±45deg with transform-origin bottom corners. Let me recall the exact classic recipe:

```css
.heart {
  position: relative;
  width: 100px; height: 90px;
}
.heart::before, .heart::after {
  content: "";
  position: absolute;
  top: 0;
  width: 50px;
  height: 80px;
  background: #ff2d55; /* etc */
  border-radius: 50px 50px 0 0;
}
.heart::before {
  left: 50px;
  transform: rotate(-45deg);
  transform-origin: 0 100%;
}
.heart::after {
  left: 0;
  transform: rotate(45deg);
  transform-origin: 100% 100%;
}
```

Yes, that's the classic CSS heart. Height of lobes = 80px, container width 100px, height 90px (80 * cos45 ≈ 56.6 + ... actually the heart's total height ≈ width after rotation; the classic uses height:90px container with 80px lobes). It works.

But a CSS heart is hard to fill/outline. For like button, we want an outline (unfilled) heart that fills with gradient when liked. Filling a CSS heart with gradient: make both pseudo-elements share a gradient — but gradients on the two lobes won't line up seamlessly. Could use `background: inherit`? Alternative: use the CSS `mask`/`clip-path` on a single element with the heart drawn via... Actually simplest: inline SVG heart with a path, `fill` controlled by CSS, stroke for outline. Gradient fill via `<linearGradient>` works and looks premium. I'll go with SVG — it's HTML markup, no JS, allowed. "Pure CSS" in these prompts means no JS interactivity; SVG shape is fine. But to be extra safe about the "pure CSS" claim, maybe I can even do it with a clip-path heart on a div:

clip-path heart path is complex but doable:
`clip-path: path("M...")` — a heart path like:
`M 50 30 A 20 20 0 0 0 10 30 Q 10 60 50 90 Q 90 60 90 30 A 20 20 0 0 0 50 30 Z` — that's a rough heart. Let me craft: Standard heart path used widely:

`M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z` (Material heart, 24×24 viewBox).

clip-path: path() with that would work: `.heart-shape { width: 90px; aspect-ratio: 24/24? ... }` Actually clip-path path uses pixel coordinates in the element's coordinate space, so with a 90px element I'd need to scale. `clip-path: path()` doesn't scale with element size. I could use `transform: scale()` on an inner element with fixed pixel path. That's fine: inner div 24×24 with clip-path path, scaled 3-4×.

Alternatively use SVG. Honestly SVG is cleanest and definitely acceptable. But the purist flex of a CSS-drawn heart with a gradient fill could use: container heart shape via two pseudo elements, and for the fill, use `background` inherited... Let me think: put gradient on `.heart` itself won't show because .heart has no background (transparent). The two lobes get `background: inherit`? `background: inherit` inherits computed background from parent, which includes gradient with its own sizing relative to the pseudo element — each lobe would restart the gradient. Not seamless.

Better approach for outlined vs filled: two stacked hearts — one "outline" heart (lobes with gradient bg, used when liked), one "gray" heart (when not liked). For outline style (unfilled with border), CSS hearts can't easily have just a border. Instead: use a filled gray heart at low opacity for unliked state (like Twitter's outline... hmm Twitter uses outline). Simple approach: unliked = heart with soft gray/white fill (like a solid outline illusion?) Many like buttons use a solid outline heart. 

Simplest robust approach: use SVG with `fill="none" stroke="currentColor"` for unliked, and on :checked, fill with gradient + pop. With SVG I can also animate `stroke-dasharray` drawing. Let's do:

```html
<svg class="heart" viewBox="0 0 24 24">
  <defs><linearGradient id="hg" ...></defs>
  <path class="heart-outline" d="..."/>
  <path class="heart-fill" d="..."/>
</svg>
```

Hmm wait, but I also want the "clip" trick: fill heart scale from 0 from bottom. With SVG, `transform-origin: 50% 100%` and scaleY(0)→1, `transform-box: fill-box`. Works in Chrome.

OK let me just commit: inline SVG heart with gradient defs. Clean and reliable.

Actually — hold on. Another thought: to really sell "pure CSS", maybe show a small footer note "0 lines of JavaScript". Cute touch. And the whole demo is one HTML file with a giant <style>. Good.

Now, the crazy animation on click. With checkbox :checked, I can run keyframe animations that play once:

1. **Button pop**: scale(0.8) → 1.4 → 0.9 → 1.1 → 1 with cubic-bezier bounce.
2. **Shockwave rings**: 3 rings expanding from center, fading, border rings.
3. **Particle burst**: ~16 particles (small hearts/circles/sparkles) flying outward in different directions with rotation and fade. Use nth-child to set --tx/--ty custom props, then one keyframe uses translate(var(--tx), var(--ty)).
4. **Confetti/emoji rain**: absolute-positioned emoji (🎉💖✨🥳) falling from top across the width. Trigger with animation on :checked.
5. **Screen shake**: animate the whole stage/body with tiny translate/rotate keyframes for 0.5s. Maybe apply to a wrapper to avoid scroll issues.
6. **Flash**: full-viewport radial flash.
7. **Count change**: number ticks from 12,408 to 12,409 — use CSS counters? The counter trick: put `counter-reset: likes` on a container; `input:checked { counter-increment: likes }`... wait, counter-increment on the input increments only while checked → toggles 0/1. To display 12,408 + counter → `content: "12,4" counter(likes) "8"`? That'd show 12,408 → 12,418. Hmm, ugly. Alternative: show a small count like "1.2K" → "1.3K"? Or just show "0"→"1"? Or better: display "+1" popup that floats up and fades — classic like feedback. Yes! A "+1" floats upward from the button and fades — much more charming than a fake counter.

Also could add a real counter with the counter trick toggling 128 → 129: content can't do arithmetic, but I can overlay two numbers and crossfade... overkill. Do the "+1" float. Actually I can ALSO do a counter display: base number as text "128" and when liked, hide it and show "129"? Two spans, crossfade, with a flip animation. That's nice: the count flips up (old number slides up out, new slides in from bottom) — slot-machine style. Let's do that: `.count-old` and `.count-new` stacked; on :checked, old translates up + fades, new comes from below. Neat and pure CSS. But +1 float is more universally readable. I could do both: count "128" flips to "129" AND a "+1" floats. Maybe keep it focused: heart button with label "Like" that becomes "Liked", count flips 128→129, plus all the explosion effects.

Hmm wait — but the flip requires the count to be inside/near the label or a sibling after the input in DOM. With checkbox hack, everything affected must be siblings/descendants reachable by selectors like `#like:checked ~ .stage .count-new`. Fine: put input first, then stage.

Also fun: on un-like (uncheck), a smaller "reverse" animation — heart deflates, particles implode? Keep simple: heart scales down with a wobble, color drains. Nice detail.

Also add **ambient background**: floating hearts drifting up slowly (pure CSS infinite animations) so first paint looks alive. And a subtle animated gradient background. Also maybe a big watermark heart or aurora blobs.

Also **hold detection**: :active adds a slight press scale.

Let me also consider replay: since animations are tied to `:checked`, re-toggling replays them. Good — user can click again for another crazy animation. Mention "click again to unlike... and re-like for more chaos" — maybe a hint text under button: "Pure CSS. Click it. Then click it again. And again."

Let me also add multiple waves of confetti with delays: two confetti layers, second delayed.

Also add "emoji burst": a few emoji that pop around the button in a circle (🥳 ✨ 💖 🎉 ❤️ 💘 🌟 ✨). These fly outward on check.

Structure plan:

```html
<body>
  <div class="scene"> (wrapper for shake)
    <input id="like" type="checkbox">
    <!-- everything keyed off #like:checked ~ ... -->
    <div class="bg"> aurora blobs, floating hearts </div>
    <label class="stage" for="like">
      <span class="flash"></span>
      <span class="ring"></span> ×3 (maybe with different delays via nth-of-type)
      <span class="spark" style="--a:0deg"> ... 
```

Wait: inline style custom props — allowed, it's CSS in style attribute... "CSS in <style>" is the rule for stylesheets; inline style attributes are still CSS, no JS. It's fine. But to keep everything in the stylesheet per the rules ("CSS in <style>"), I can define nth-of-type rules for each particle's angle instead. 16 particles × nth-of-type rules is verbose but doable. Alternatively use style="--a:20deg" inline — hmm, the rules say "Everything must be inline: CSS in <style>, JavaScript in <script>". That's about no external files; inline style attributes are still inline. But to be safe and tidy, I'll use nth-of-type selectors in the stylesheet to assign angles. Actually a slicker trick: use a single keyframe animation and vary per-particle via custom properties set in stylesheet nth-of-type rules. Or even trickier: use `rotate` composition... Simplest maintainable: define classes like `.p1 { --tx: 0px; --ty: -120px; --r: 0deg; --d: 0s; --c: ... }` for each particle in the <style>. That's 16 small rules — fine.

Particles design: small elements with border-radius mix (some circles, some squares rotated = confetti, some tiny hearts via clip-path?). Keep: circles + rounded rects (confetti strips) + a couple of 4-point sparkles via clip-path polygon star. Colors: pink/red/gold/white palette.

Keyframe for particles:
```css
@keyframes fly {
  0% { transform: translate(-50%,-50%) translate(0,0) scale(0) rotate(0); opacity: 1; }
  20% { opacity: 1; }
  100% { transform: translate(-50%,-50%) translate(var(--tx), var(--ty)) scale(1) rotate(var(--rot)); opacity: 0; }
}
```
Positioned at center of stage with left:50%; top:50%.

Rings keyframe:
```css
@keyframes ring {
  0% { transform: translate(-50%,-50%) scale(.2); opacity: .9; }
  100% { transform: translate(-50%,-50%) scale(2.6); opacity: 0; }
}
```

Heart pop keyframes:
```css
@keyframes pop {
  0% { transform: scale(1); }
  30% { transform: scale(.6) rotate(-8deg); }
  45% { transform: scale(1.5) rotate(6deg); }
  60% { transform: scale(.9) rotate(-4deg); }
  75% { transform: scale(1.25) rotate(2deg); }
  100% { transform: scale(1) rotate(0); }
}
```
Applied to heart-wrap on checked, 0.7s.

Heart fill: gradient with animated background-position shine sweep? Could add a "shine" that sweeps across the heart after fill (a white diagonal streak clipped to the heart shape moving across). With SVG that needs a mask... Simpler: overlay heart-shape container with the same clip and a ::before white gradient skewed sweeping. If heart is SVG, overlay a duplicate... Alternative: put heart inside a container with `clip-path` matching the heart shape, then shine div inside. Since I'm using SVG heart, the clip-path route means CSS heart. Hmm.

Let me reconsider: use a CSS-drawn heart where the WHOLE heart is one element via clip-path: path(), so I can fill it with a gradient, add shine overlay inside, scale it, everything. clip-path: path() coordinates are in the element's own coordinate space (pixels, origin top-left of border box). So define heart element as, say, 100×90 px with a path drawn in that space, or 24×24 scaled via transform.

Let me write a nice heart path in a 100×90 box:
Classic: `M50 88 C20 66 2 50 2 28 C2 12 14 2 28 2 C38 2 46 8 50 16 C54 8 62 2 72 2 C86 2 98 12 98 28 C98 50 80 66 50 88 Z`

Let me sanity-check that shape: Start at bottom tip (50,88). Curve up-left to top-left lobe. Left lobe circle-ish: from (2,28) area... The path: M50 88 → C20 66 2 50 2 28: control points (20,66),(2,50) end (2,28) — left side going up. Then C2 12 14 2 28 2: top-left lobe arc. Then C38 2 46 8 50 16: dip to center (50,16). Mirror right side. Then C98 50 80 66 50 88 back to tip. This gives a decent heart. I've seen similar. Let me refine numbers to look plump:

`M50 86 C 26 66, 4 48, 4 27 C 4 13, 15 3, 28 3 C 37 3, 45 8, 50 17 C 55 8, 63 3, 72 3 C 85 3, 96 13, 96 27 C 96 48, 74 66, 50 86 Z`

The center dip at y=17 vs lobe tops at y=3 — dip depth 14px, lobe width ~24px each. Bottom tip at 86. Looks reasonable.

So `.heart { width: 100px; height: 90px; clip-path: path("..."); background: ...; }` But clip-path path() is not responsive to element size — it's in px of the element box. If element is exactly 100×90, path fits. On smaller screens I can scale the element with transform: scale() on a parent — clip stays relative to element, scaled with it. 

For the unliked state: I want an outlined heart. clip-path can't do strokes. Options:
- Unliked state: heart shown at low opacity solid (like pale gray) — solid heart, looks fine (Facebook style is outline; Twitter outline; but solid pale heart is also common — e.g., Instagram uses outline; but plenty of "like" UIs use solid). Hmm, outline looks more "clickable/likable".
- Trick: two stacked heart elements: bottom one gray solid (shown when unliked), and on top the gradient-filled heart scaled from 0 (grows on like). For an outline look when unliked: render a solid heart of the background color (dark) inside a slightly larger solid heart of the outline color → creates outline effect! Outline heart = outer heart (light gray) with inner heart (bg color) on top, offset by border thickness. Then when liked: the fill heart (gradient) scales in on top of everything, outline disappears (opacity 0).

So structure inside stage:
```
<span class="heart-stack">
  <span class="heart h-outline"></span>   <!-- gray heart, z1 -->
  <span class="heart h-cutout"></span>   <!-- bg-colored heart slightly smaller, z2 → makes outline -->
  <span class="heart h-fill"></span>     <!-- gradient heart, scale 0 → 1 on like, z3 -->
  <span class="heart h-shine"></span>    <!-- shine sweep, z4, clipped same -->
</span>
```

Outline via layering: h-outline is the gray heart at scale 1; h-cutout is a heart scaled to ~0.86 with the card/background color — since background behind is a card surface, the cutout color = card bg → looks like an outline heart. This works if the button sits on a solid-color card. I'll put the button on a dark card with solid-ish bg. But I want a pretty gradient background... The button could sit on a "chip/card" with a subtle solid dark bg (#1c1426 or similar). The cutout matches that. There might be a slight mismatch if card has gradient/texture; keep card essentially solid (with maybe a vignette that's subtle enough? Risky — mismatch would show). Keep the card solid, with border + shadow for depth. Fine.

Actually alternative simpler: unliked heart = just the gradient heart at 0 grayscale... no wait: unliked = heart in muted gray fill (solid). It still reads as a like button (solid pale heart). Honestly outline looks better but solid is simpler. Hmm. Let me do outline via the two-layer trick on a solid card — it's more premium. The shine sweep: h-shine is another heart with background: linear-gradient(115deg, transparent 40%, rgba(255,255,255,.9) 50%, transparent 60%), background-size larger, animated background-position on check. Since it's clipped by same heart path, it looks like light sweeping across the heart. But it must sit above h-fill and below nothing... h-shine should only be visible when liked. z-order: h-fill (gradient) then h-shine above it. When unliked, h-shine hidden (opacity 0) and h-fill scale 0.

Also add inner glow: box-shadow won't show with clip-path (clip clips shadows). Use drop-shadow filter on the stack wrapper instead — filter: drop-shadow respects clip-path of children? drop-shadow on the parent of clipped children works (applies to rendered result). Actually applying `filter: drop-shadow(...)` on the element that itself has clip-path clips the shadow too (filter applies after clip? order: clip-path then filter? The filter applies to the element including its clipped shape result — drop-shadow uses the alpha of the element after clipping, so it works! Actually clip-path clips the element's rendering; a filter on the same element... spec order: filter is applied, then clip-path clips the result?? Let me recall: The order is: filter → clip-path → mask? Per CSS spec, clip-path is applied after filter. Hmm. In practice, applying `filter: drop-shadow()` on an element WITH clip-path: the drop-shadow is computed from the element's painted content and then... I remember that clip-path clips the shadow as well when on the same element (the clip applies to the filtered result), so the shadow gets cut. The safe way: wrapper element has drop-shadow filter; child has clip-path. Then wrapper's filter sees the clipped child alpha → shadow of heart shape. Yes, that works (common technique). So `.heart-wrap { filter: drop-shadow(0 10px 30px rgba(255,45,85,.45)) }` toggles stronger on liked.

Now the count flip: "128" → "129". Implement with two stacked spans in a masked box:
```html
<span class="count">
  <span class="digits"><span class="d old">128</span><span class="d new">129</span></span>
</span>
```
Both absolutely stacked; on :checked, `.old` translateY(-100%) fade, `.new` comes from translateY(100%) to 0. With overflow hidden on .count. Nice slot effect.

And "Like" → "Liked" text swap similar (crossfade or slide). And heart color of text changes pink.

Also add a subtle idle animation pre-click: heart gently pulses (scale 1↔1.05, 2s infinite) + a small "tap me" hint. Since screenshot at 3s: idle pulse visible. Add a hint bubble: "no JavaScript — click me!" with an arrow? Cute caption under: "0% JavaScript · 100% CSS". 

Screen shake: apply keyframes to `.scene` (the main wrapper, position fixed inset 0) — translate small amounts, 0.45s, on :checked. Since :checked is the input, selector `#like:checked ~ .scene`? Careful: input must precede scene. Let me structure:

```html
<body>
  <input type="checkbox" id="like">
  <div class="scene"> everything </div>
</body>
```
Then `#like:checked ~ .scene .heart-wrap { animation: pop ... }` etc. All selectors prefix `#like:checked ~ .scene`. To shorten, could put input inside .scene as first child and use `#like:checked ~ ...` for siblings. But label must be associated — label[for] works regardless of position. OK.

Hmm, one consideration: the shake animation on .scene while .scene contains the label — clicking again mid-animation is fine.

Flash: a full-screen radial gradient element inside scene, opacity 0 → on check, keyframe flash 0→.9→0 over .6s. Color: pink-white radial at button position? Just a screen-wide flash from center.

Confetti rain: ~14 elements falling from top with rotate, each with --x left position, delay, color, some are emoji (🎉 ✨ 💖 🥳 💯 👑). Falling keyframe: translateY(-10vh → 110vh) with rotation and sway (use two nested elements? sway via translateX keyframe on child, fall on parent). Simpler: each confetti is a wrapper .drop (falls + sways via keyframes with translateX sin-ish approximations) containing .conf (rotates, colored rect or emoji text). Use emoji directly as .drop content — emoji rendered as text, rotate them. Mix: emoji drops and CSS confetti strips.

Number of DOM elements is getting big but fine.

Big radial "burst" behind heart: a sunburst of rays? Could do a conic-gradient disc that scales+fades on check — looks like a flash burst. `background: repeating-conic-gradient(from 0deg, rgba(255,255,255,.8) 0 6deg, transparent 6deg 18deg)` masked with radial-gradient to fade edges. Scale 0→1.6 opacity→0. That's a cool comic-style burst. Also a plain radial glow disc scaling.

Comic "POW"-style text? Maybe not, keep classy.

Also: heart particles — small hearts flying out using the same clip-path heart shape at small size (e.g., 14×12.6 px). Cute! Mini hearts among confetti burst. Use the same `.heart-path` class with scaled-down... but clip-path path() is fixed px. For mini hearts, define separate clip-path path in small coordinates? clip-path path scales relative to element box? No — path() uses the coordinate system of the element with unit px, not viewBox scaling. So a 100-unit path on a 14px element would extend way beyond (clipped). So each size needs its own path string, OR use transform: scale(0.14) on a 100×90 element. transform scale works: element remains 100×90 (clip fine), then scale(0.14) shrinks visually. But then layout box is 100×90 — position absolutely centered, fine for particles. I'll do that: particles are `.mini` hearts: width 100px height 90px clip-path heart, transform: translate(-50%,-50%) scale(.14) then animate scale up to .2 and translate outward. Manageable.

Alternatively for particles use simple shapes: circles (border-radius 50%), strips (2×10px rounded), and 4-point sparkles via clip-path polygon (px-based, fine at small size: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%) — percentages work in polygon! Great, sparkles via polygon are scalable.)

So particles: circles, sparkle stars (polygon %), strips (confetti). And 2-3 mini hearts with scale trick for charm. 

Emoji pop-around: 6 emoji positioned around the button at angles, hidden (scale 0), on check they pop outward with spring keyframes and fade. Positions via nth-child transform in keyframes using per-child custom props (--tx, --ty) defined in stylesheet.

Let me count the crazy checklist:
1. Heart pops with jelly bounce ✓
2. Outline → gradient fill with shine sweep ✓
3. +1 float ✓ (add)
4. Count 128 → 129 slot flip ✓
5. Like → Liked text morph ✓
6. 3 shockwave rings ✓
7. 18-particle explosion (hearts/circles/stripes/sparkles) ✓
8. Comic conic sunburst ✓
9. Radial glow flash ✓
10. Screen shake ✓
11. Confetti + emoji rain from top ✓
12. Emoji pop ring around button ✓
13. Button glow aura intensifies, card border glows pink ✓
14. Ambient floating hearts background always animating ✓ (pre-click life)
15. Ripple/press on :active ✓

That's a lot — "crazy" delivered. Careful with performance: all transforms/opacity, fine.

Accessibility: input visually hidden (but focusable — keep it focusable for keyboard! Use opacity:0 position absolute, not display:none, so keyboard tab+space works. Add :focus-visible ring on stage: `#like:focus-visible ~ .scene .stage { outline: ... }`. Nice touch. Also `cursor: pointer` on label. Note: the iframe keyboard — user must click first; the prompt's keyboard note applies to games mainly. Label click works with mouse. Also mention hint.

Reduced motion: `@media (prefers-reduced-motion: reduce)` kill animations — good practice, include lightly.

Responsive: stage centered with flex; scale heart down on small screens via clamp on heart-wrap transform scale? Since clip-path fixed px, use `transform: scale(var(--s))` on heart-wrap where --s set via media query (1 at desktop, .7 mobile). But heart-wrap also gets pop animation that sets transform — conflict. Solution: outer sizer element with scale, inner with animation. Structure: `.heart-btn` (the clickable circular button, fixed size clamp()) > `.heart-scale` (media scale) > `.heart-wrap` (pop animation) > hearts. Actually simpler: make the button circle size with clamp() and the heart inside at fixed 100×90 centered with translate(-50%,-50%) scale(...) — set base scale via custom property and multiply in animation keyframes: keyframes would need scale(var(--hs)*...) — can't multiply. So do the two-layer approach: `.heart-fit { transform: scale(var(--fit)); }` wraps `.heart-wrap` which has the pop animation (transform-based keyframes). Keyframes on .heart-wrap override its transform, but .heart-fit keeps its own scale — compounding works. 

Let me define sizes: button circle 150px desktop; heart 100×90 centered. Mobile (<480px): button 120px, --fit: .8. Also caption text sizes clamp.

The card: I'll design the layout as a centered "card" panel? Or button directly on the background with caption below? A card gives the cutout-heart trick a solid bg to match. Let me do: a rounded card (dark, solid `#171226`-ish... wait cutout must match card bg exactly. Card bg: solid #1b1430 or similar; page bg: animated gradient darker (#0b0817). Card border: 1px rgba(255,255,255,.08), shadow, radius 28px, padding 48px 64px. Inside: heart button (circle with subtle inner bg rgba(255,255,255,.04), border), then "Like" + count row below. Hmm, or side by side. Let me do: big circle button; below: "Like" label and count "· 128".

Wait, actually cutout heart color must equal the button circle's bg, since heart sits on the button. Button circle bg: rgba mix over card... The heart sits on the circular button whose bg is rgba(255,255,255,.05) over card #1b1430 → composited color ≈ blend. Compute: card 0x1b1430 = (27,20,48); overlay 5% white: (27*.95+255*.05, ...) = (38.1, 31.5, 57.85) ≈ #261F3A. To be exact, give the button a solid bg color instead: `#241d38` and cutout `#241d38`. But then button over card with slight bg diff looks intentional. Also glow when liked adds luminosity behind heart — cutout edge might mismatch during glow... The glow is behind/around button, on card, not under the heart. Keep glow as aura ring outside the button circle (box-shadow on button: 0 0 60px rgba(pink)) — box-shadow of the circle renders outside; fine.

But careful: if cutout heart = button bg exactly, and button bg is solid #241d38, outline heart = gray heart with #241d38 hole. Good. However — during the "liked" state we keep the outline visible underneath the fill (harmless). Also when shine sweeps it's above fill.

Also hover state: outline heart brightens, button lifts, cursor pointer.

Let me now also think about the "+1" float: positioned near count or above button; on check, animate translateY(-60px) fade with slight rotate. Also maybe multiple "+1"s? One is fine. Could add a burst of tiny "+1"s in different directions — cute! Do 3 with varied directions via nth-child. Eh, keep 1, plus the emoji ring provides the variety.

Confetti rain details: place .rain container fixed inset-0 pointer-events none, containing ~12 .drop elements. Each .drop positioned left: var(--x), top: -8vh; contains emoji text or a strip. Animation on #like:checked: fall 1.4s ease-in with delay var(--dl); keyframe fall { from { transform: translateY(-10vh) rotate(0) } to { transform: translateY(110vh) rotate(var(--spin)) } } with opacity fade at end. Also add sway: child .sway animating translateX ±20px alternate? Nested: .drop (vertical fall) > .sway (horizontal oscillation) > content (spin). Three nested spans each with own animation. That's pretty. Let's do it: drop keyframes translateY; sway keyframes 0/50/100 translateX(-14px/14px/-14px) linear infinite during fall — hmm infinite inside 1.4s finite container is fine (sway runs while parent exists/visible; set sway animation on check with duration .5s infinite; it'll just keep running but parent is off-screen/transparent later; or give sway the same finite duration with several oscillations baked into keyframe percentages). Simpler: bake sway into fall keyframes with translate at 25/50/75% points: translate(x, y) combined with rotate — need per-item x. Use var(--sw) sway amplitude. Keyframes:

```
@keyframes fall {
  0% { transform: translate(0,-12vh) rotate(0turn); opacity: 1 }
  100% { transform: translate(var(--sw), 105vh) rotate(var(--spin)); opacity: .9 }
}
```
Sway won't oscillate but diagonal drift is fine + rotation gives life. Add rotate3d? Keep 2D. Actually I can add a second keyframe stop mid: 50% { transform: translate(calc(var(--sw) * -1), 50vh) rotate(calc(var(--spin)/2)) } — gives a zig-zag. Nice, cheap.

Emoji spin: rotate whole drop (emoji rotates while falling — looks tumbling). Fine.

Drops content: mix of emoji (🎉💖✨🥳💘🌟🎊💯) and CSS strips (width 8px height 14px bg var(--c) radius 2px). Strips rotate — with drop rotation applied, strips tumble. Good.

Also second rain wave delayed .25s? Give each drop its own delay via --dl in nth-child rules. 14 drops with varied --x (in %), --dl (0–.5s), --sw, --spin, colors.

Ambient background: 
- Base: radial gradients + solid deep purple/navy `#0e0a1f`.
- Aurora blobs: two/three large blurred circles (filter: blur(80px)) with slow keyframe float — color pink/purple/blue, opacity .35. Behind everything.
- Floating mini hearts: 8 hearts (scale trick .1–.2) rising slowly from bottom, infinite alternate, opacity .15, various speeds/delays/left positions, slight sway via keyframes. These run from load → alive first paint.
- Grain? skip.
- Title top: small overline "PURE CSS" + heading "The Like Button" + subtitle "No JavaScript. One checkbox. Total chaos." Typography: use system font stack but styled nicely (no external fonts allowed... CDN allowed but keep zero external; use system stack: "A system stack with letter-spacing". For display, maybe `font-family: ui-rounded, 'SF Pro Rounded', system-ui` or Georgia/serif contrast? I'll use a strong geometric look via system-ui with tight tracking and heavy weight; plus a serif italic accent word? Let's do: heading in system-ui 800 with gradient text (pink→orange→gold) — classy. Overline small caps letterspaced pink.

Footer note bottom: "View source: zero <script> tags · powered by :checked" — cute. And hint "click the heart".

Layout: 
- Center column: overline, h1, subtitle, card (button+label), footer note at bottom.
- Vertical: title ~20vh above card. Use flex column center, gap. On 800px height fits.

Now, "crazy" toggling: unchecking triggers unlike: heart deflates (scale to 0 of fill with slight delay), maybe gray particles drop down (rain of gray dots)? Add small "deflate" keyframes: fill scales down with wobble, count flips back, label back to Like, aura fades. The confetti/particles only on check. When unchecking, the check animations reset (since applied only under :checked, removal resets instantly — abrupt). To smooth un-like, add transition on .h-fill transform (transform .35s spring-ish when not animating — but animation overrides transform during check; on uncheck, animation removed → transform transitions from scale(1) to scale(0) via the transition. Since transition property on base state, and animation... when :checked removed, the computed transform goes from animated end (1) to base (0), transition applies. But wait, during check the animation sets scale 1 with fill-mode? The pop animation ends at scale(1) — base checked transform also scale(1). On uncheck, transitions to 0. 

So `.h-fill { transform: scale(0); transform-origin: 50% 80%; transition: transform .3s cubic-bezier(.6,-0.28,.74,.05) }` and `#like:checked ~ .scene .h-fill { transform: scale(1); animation: heartgrow .7s ... }`. heartgrow keyframes go 0→overshoot→1. Wait animation start from 0. When check happens, base checked transform is scale(1) but animation overrides from 0% keyframe — set 0% scale(0) so it grows. Good.

Heart wrap pop on check: animation pop .75s cubic. On uncheck, no transition needed (wrap returns to normal scale 1 — same as base; add small wobble via... skip, the fill shrink is enough. Maybe add a "sad" keyframe on uncheck? Can't detect uncheck with CSS states (no :unchecked pseudo). Alternative: `:not(:checked)` + animation restarts on load only. Skip — acceptable: unlike is instant reset of explosions + smooth fill shrink.

Hmm wait, one more consideration: the shine sweep animation — on check, runs once 0.9s. Good.

The rings and particles: they should animate once per check. When checked stays, animation completed with fill-mode forwards? If forwards keeps opacity 0 end states, fine, they stay invisible. Use `animation: ... both`. When unchecked, animations removed → elements reset to hidden base (opacity 0, scale 0) — instant reset invisible anyway since base states are hidden. 

But replay nuance: toggling check off→on replays because animation re-applies. While staying checked, animations run once. Perfect.

Burst sunburst: conic rays disc 240px, scale .3→1.5, rotate 20deg, opacity .9→0, .7s. Behind heart (z below heart stack, above button bg).

Glow flash full-screen: radial-gradient(closest-side, rgba(255,120,160,.5), transparent 70%) positioned at center of screen (button approx center) — as ::before on scene? Scene is whole viewport so center works if button centered horizontally and roughly centered vertically... The button is below the title, so screen-center flash mismatch. Alternative: put flash centered on the card/stage: a large radial glow behind button (e.g., 900px) that flashes opacity 0→.7→0. That reads as "flash". Plus a subtle screen-wide brightness: apply keyframes to scene background? Skip screen-wide; use big glow behind button + shake. Shake communicates impact enough. Also add a quick white "blink" overlay on card: card::after flashing. Good enough.

Z-index & pointer-events: particles/emoji floats must not block label click — label covers button area; overflow elements around: set pointer-events:none on all effect layers (they're inside label though — inside label clicks anywhere trigger toggle! That's actually fine/good: bigger hit area. But particles flying outside the label bounds: clicks on them toggle the checkbox — harmless/fun). Keep label's clickable area as the button circle visually; label box = stage which might be bigger (to contain particles). Making whole stage toggle is okay — clicking near button toggles. It's fine; but cursor pointer over big empty area might confuse. Set stage size = button area, and put effect layers as siblings of label inside a common .fx wrapper (absolute, pointer-events none), all inside .card. Selectors then: `#like:checked ~ .scene .fx .ring { animation... }`. Fine.

Wait but the caption (Like/liked/count) is separate from label — where? Inside card below button. It changes on :checked via sibling selectors from #like — fine since #like precedes .scene.

The label content: the circle button with hearts. Clicking circle toggles. Also make the whole card clickable? No — keep label = circle. Hmm, users may click the "Like" text expecting toggle. Make label wrap text too? The count/label text: put inside label as well (label can contain all). Let me make the label contain: button circle + caption row. Then .stage is the label (column flex, gap). Effect layers inside .stage absolutely positioned relative to it, pointer-events none (but they're in label — clicks still toggle, fine, they're transparent to events visually anyway). Particles flying outside stage bounds: absolutely positioned children can overflow (stage overflow visible default) — ok. And clicks on the flying particles = inside label = toggles — harmless.

Hmm, one caveat: label with for= on input hidden — clicking label toggles input. Keyboard: input focusable (opacity 0, position fixed). Space toggles. Add focus-visible ring on stage via `#like:focus-visible ~ .scene .stage .circle { outline: 3px solid ...; outline-offset: 4px }`. 

Now the input placement: must precede .scene for `~`. Put it first in body, visually hidden: `position: fixed; opacity: 0; pointer-events: none; width:1px;height:1px` — hmm for focusability keep not display:none. Use `position:absolute; left:-9999px`? Focus scroll jump... Use opacity:0 fixed at top-left, size 1px — fine, no scroll issue (fixed).

Counter idea — do I include CSS counter gimmick? I'll do the flip 128→129 with two spans. Wait, more fun: make the count go "999+" ... static values fine.

Let me write the heart path precisely. I'll test mentally: viewBox-less clip-path path on element 100×90.

Path: `M50 86 C26 66 4 48 4 26.5 C4 13 15 3 28 3 C37.6 3 45.6 8.4 50 17.5 C54.4 8.4 62.4 3 72 3 C85 3 96 13 96 26.5 C96 48 74 66 50 86 Z`

Check symmetry about x=50: left lobe center ~ (28,?) radius 24 → matches right (72). Left side: from (50,86) control (26,66),(4,48) to (4,26.5) — smooth leftward curve. Top-left: (4,26.5) C(4,13)(15,3)(28,3): quarter-ish arc turning the corner. Then (28,3) C(37.6,3)(45.6,8.4)(50,17.5): descends into the notch at (50,17.5). Notch depth: top y=3 vs notch y=17.5 → 14.5 deep. Lobe width 24px radius. Heart width 92, height 83. Plump, standard. 

The clip: `clip-path: path('M50 86C26 66 4 48 4 26.5C4 13 15 3 28 3C37.6 3 45.6 8.4 50 17.5C54.4 8.4 62.4 3 72 3C85 3 96 13 96 26.5C96 48 74 66 50 86Z')`. Element must be exactly width:100px;height:90px. I'll define `.hp { width:100px; height:90px; clip-path: path("...") }` and use for all hearts (fill, cutout, outline, mini). Cutout needs to be smaller to create border: scale(.86) with transform — but transform on clipped element scales clip too (clip applied then transform transforms the rendered result — visually scaled heart). Outline thickness ≈ (1-.86)*~40px ≈ 5.6px around. Use scale(.88) → ~4.8px border. Also cutout slightly translated? scale about center keeps symmetric border. Good: border ~5px.

Outline heart gray: #8f8aa3-ish (muted lavender-gray). On hover: brighter #cfc9dd + drop shadow. On check: outline fades out (opacity 0, .2s) while fill pops in. Actually keep outline under fill — when fill covers it, invisible anyway. But fill is same size as outline → outline's 6% ring edge would peek? Fill scale 1 = same size → covers cutout hole, but the outline ring (the 5px gray band) still shows around the fill — actually that looks GOOD: gradient heart with subtle... no wait, gray band around gradient heart looks like artifact. So fade outline out on check: `#like:checked ~ ... .h-outline, ... .h-cutout { opacity: 0; transition: opacity .15s }`. On uncheck, they return (fade in .3s) — heart becomes outline again. But during fill-shrink transition on uncheck, outline reappears beneath — good crossfade.

Shine: h-shine heart with background: linear-gradient(105deg, transparent 42%, rgba(255,255,255,.95) 50%, transparent 58%), background-size: 250% 100%; base background-position: 120% 0 (off right? we sweep left→right). On check animation shine .8s: from background-position -60% 0? background-position percentages with size 250%: 0% aligns left edges... For sweep: animate background-position from `150% 0`? Let me think: bg-size 250% 100%; positions: 0% → left aligned (gradient centered at left region), 100% → right aligned. The white band at 50% of gradient. With position 0%, band at ~ (50% of 250%) = 125% of element → off right? Element shows left 40% of the 250% image at position 0%... position 0%: image left edge at element left edge; visible region = image [0,40%]; band at 50% not visible. position 100%: image right edge at element right; visible = image [60%,100%]; band at 50% → just off left... hmm band crosses during 0%→100%? At some position p, visible window = [p*150%... p*150%+40%] in image coords... At p: offset = (250-100)*p% = 150p% from left; window [150p, 150p+100] in % of image (image 250 wide, window 100 → visible fraction 40% of image). Band at 125 (image %). Visible when 150p ≤ 125 ≤ 150p+100 → p ∈ [0.166, 0.833]. So animating 0%→100% sweeps band fully. Set keyframes from background-position: 0% 0 to 100% 0. But wait — with clip-path on h-shine and it stacked above h-fill, h-shine must be transparent outside band — yes gradient transparent elsewhere. But h-shine base state opacity 0 (hidden) and animation sets opacity 1 during? Keyframes: 0% {opacity:1; bg-pos 0%} 100% {opacity:1; bg-pos 100%}? Then end state via fill-mode forwards keeps opacity 1?? That'd keep a static band visible... At end, band off-view (outside 0.833) so invisible anyway — band positioned off, fine, but keep forwards with bg-pos 100% → invisible. But safer: 0% {opacity:1} 80% {opacity:1} 100% {opacity:0; bg-pos 100%}. Base opacity 0, animation both. OK.

Also give h-fill gradient: linear-gradient(135deg, #ff9a3d?, ...). Like-button palette: hot pink → crimson → orange? Instagram-ish: #feda75, #fa7e1e, #d62976, #962fbf, #4f5bd5 — too rainbow. Do: `linear-gradient(135deg, #ff5e7e 0%, #ff2d78 45%, #ff471a?? ` Let's pick: #ff8a00 (orange) → #ff2d55 (pink-red) → #d62976? Gradient direction 160deg: top-left light pink #ff9db8 → mid #ff2d55 → bottom #c9184a deep. Add tiny highlight: radial overlay? The shine handles highlight. Fine: `linear-gradient(160deg, #ff7eb3 0%, #ff2d55 55%, #c81d5e 100%)`.

Drop-shadow glow on heart-wrap when liked: `filter: drop-shadow(0 6px 18px rgba(255,45,85,.55)) drop-shadow(0 0 40px rgba(255,45,85,.35))` — transition filter .4s. Filter transition animatable (filter lists interpolate if same length — keep same structure both states: base `drop-shadow(0 6px 18px rgba(255,45,85,0)) drop-shadow(0 0 40px rgba(255,45,85,0))`? For interpolation, same function list. Do that: base two zero-alpha drop-shadows, checked two strong. Transitions smoothly. 

Circle button: 150px, radius 50%, bg #241d38 solid (must match cutout), border 1px rgba(255,255,255,.06), inner shadow inset top light. On checked: border-color pink-ish, box-shadow 0 0 0 1px pink?, plus outer aura `0 10px 40px -10px rgba(255,45,85,.5), 0 0 80px -20px rgba(255,45,85,.4)` transition .5s. On :active: scale .94 quick (transition .05s). Base transition transform .18s.

Wait — the cutout heart color must match the circle's bg exactly — but circle has inset shadow (inner top highlight rgba(255,255,255,.06)) — the cutout sits over that area... inset shadow paints above bg? Box-shadow inset paints above background but below content. The heart elements are content → cover it. Mismatch: cutout solid #241d38 vs circle bg #241d38 + inset highlight ≈ slightly lighter at top. The heart cutout would look a touch darker than surrounding at top. Subtle; inset highlight rgba(255,255,255,.05) small. Alternatively drop inset shadow, use a ::before radial highlight... which also under content. Any gradient under cutout breaks illusion. Option: make cutout heart use same background stack? Can't replicate underlying inset shadow across elements easily. Simplest: circle bg = flat #241d38, NO inset gradient, depth via outer border + drop shadows + top highlight as a separate ::after arc above content? ::after would cover hearts... put highlight as border-top lightness? Keep it flat; modern flat is fine. I'll add a very subtle inner ring: box-shadow inset 0 0 0 1px rgba(255,255,255,.03) — uniform ring, under cutout edges — uniform color change everywhere equally... inset ring is a 1px line at the edge, not under the heart (heart is 100×90 within 150 circle, edges far). Only inset *gradient/shadow spread* under heart matters. inset 0 0 0 1px is only at circumference — safe! Use that for subtle rim. 

Card bg: #17112b? And circle #221b3a slightly lighter. Cutout = #221b3a. 

Hmm wait, actually simpler alternative for outline: use two clip-path layers where outer = gray, inner = same color as circle. Yes that's what we're doing. OK.

Now count flip: "128" and "129". Hmm, or "4,096"→"4,097"? Use 1,024→1,025? Cute: "1,024" → "1,025". Nerd cred. Let's do 1,024 → 1,025.

Also, maybe hide numbers pre-check as "1,024" always shown. Fine.

Text: "Like" (gray) → "Liked" (pink). Implement as two stacked spans sliding vertically (like count). Container fixed width = max of both (~ch). Use inline-block relative container; spans absolute left 0 whitespace nowrap; slide up on check. Width: "Liked" is wider than "Like" — container width should fit the wider: set container width in ch of "Liked" (~5.5ch, font-dependent). Simpler: grid stack: `.swap { display:grid } .swap > span { grid-area: 1/1 }` — both occupy same cell; container sizes to the max. Transforms translateY with overflow hidden? Overflow hidden on grid cell needs a wrapper with fixed height (line-height). Do `.swap { display:grid; overflow:hidden; border-radius: 4px } .swap span { grid-area:1/1; transition: transform .45s cubic-bezier(.2,.7,.2,1), opacity .3s }` old: translateY(0)→-120% + opacity 0; new: from translateY(120%) → 0, opacity 0→1. Height = one line (grid row = tallest content = one span since both in same row? grid-area 1/1 both in row 1 → row height = max span height = single line height). Yes! Grid stacking works cleanly for both count and label swaps.

The +1 float: element near count: "+1", on check animation rise 1.2s: translateY(0→-46px), opacity 0→1→0, scale .6→1. Base opacity 0. Position: absolute right of count or above heart. Place above the count, popping from the count upward. Cute. Maybe two: "+1" and a tiny "❤" rising from the heart too — the mini-heart particles cover that.

Emoji ring: 6 emojis around button at radius ~130px: angles every 60°. nth-child sets --tx/--ty via cos/sin values I hardcode:
angle 0: (130, 0) → tx 130px ty 0... but nicer at varied radius: 
- 🎉 at (-150,-110)
- ✨ at (140,-120)
- 💖 at (160, 20)
- 🥳 at (-160, 30)
- ⭐ at (-90, -150)
- 💯 at (95, 150)? 

Just pick 6 spread positions. Keyframes popout: 0% translate(-50%,-50%) scale(0); 60% scale(1.2); 80% scale(.95); 100% translate(var(--tx),var(--ty)) scale(.4), opacity fade at end: keyframe 0% opacity 1... 70% opacity 1, 100% opacity 0. Duration .9s ease-out, slight delay per child (--dl .05–.2s). Base: opacity 0 scale 0.

Particles (18): mixed shapes. Positions: circle radius ~110–170, hardcode per nth-child. Shapes assigned by class: .c (circle 10px, bg var), .s (sparkle 14px clip polygon), .t (strip 5×16 radius 2, bg var), .mh (mini heart 100×90 scale trick). For mini heart scale trick: `.mh { width:100px;height:90px; clip-path: heart }` and keyframe includes scale: transform: translate(-50%,-50%) translate(var(--tx),var(--ty)) scale(.16) rotate(var(--rot)). Base transform translate(-50%,-50%) scale(0)?? Scale 0→.16 in keyframes: 0% { ... scale(0) } 60% { scale(.18) } 100% { ... scale(.14) }. OK since each shape type gets own keyframes? That multiplies keyframes: fly-circle, fly-strip, fly-spark, fly-heart — 4 keyframe sets, or ONE keyframe using var(--s) end-scale and var(--rot): keyframe `fly`: 0% { transform: translate(-50%,-50%) translate(0,0) scale(0) rotate(0) } 60% { opacity 1 } 100% { transform: translate(-50%,-50%) translate(var(--tx), var(--ty)) scale(var(--s)) rotate(var(--rot)); opacity: 0 }. But mini-hearts have intrinsic 100×90 needing constant scale .16 baked... var(--s) per child: mini heart --s:.16, circle --s:1 (with width 10px). But transform scale applies to the element itself; circles width 10px scale 1 fine; mini hearts need base scale .16 → set --s: .16 and width 100px — but element box 100×90 centered via left/top 50% + translate(-50%,-50%) — correct centering. Then var(--s) .16 keeps them small. So single `fly` keyframe + per-child custom props (--tx, --ty, --s, --rot, --dl, maybe --c color, --d duration). 

Per-child rules: I'll write nth-of-type rules on `.burst i`. 18 rules each ~2 lines. Verbose but fine. Actually I can compress: group children into classes p1..p18? nth-of-type cleaner.

Let me define 18 directions (tx,ty) roughly even circle with jitter, radius 120–190:
1: (0,-150)
2: (40,-140)
3: (-45,-142)
4: (95,-105)
5: (-100,-100)
6: (140,-55)
7: (-148,-48)
8: (155,10)
9: (-160,15)
10: (120,80)
11: (-125,85)
12: (60,135)
13: (-65,140)
14: (15,160)? maybe fewer bottom ones since card below—fine.
15: (-15,-165)
16: (170,-20)
17: (-175,-15)
18: (85,-160)? 

Let me just assign systematically: angles 0..340 step 20°, radius varying 130–185. Compute cos/sin quickly (deg → cos,sin):
0°:1,0
20:.94,.342
40:.766,.643
60:.5,.866
80:.174,.985
100:-.174,.985
120:-.5,.866
140:-.766,.643
160:-.94,.342
180:-1,0
200:-.94,-.342
220:-.766,-.643
240:-.5,-.866
260:-.174,-.985
280:.174,-.985
300:.5,-.866
320:.766,-.643
340:.94,-.342

Screen y-axis down: ty = sin*R (positive down). Radius per particle R: cycle [150,180,135,165,145,175,140,160,150,135,170,145,160,140,175,150,165,145] for 18.

tx = cos*R, ty = sin*R (down positive):
1 R150: (150, 0)
2 R180: (169, 62)
3 R135: (103, 87)
4 R165: (82, 143)
5 R145: (25, 143)
6 R175: (-30, 172)
7 R140: (-24, 138)
8 R160: (-153, 54)
9 R150: (-141, 0)
10 R135: (-127, -46)
11 R170: (-132, -109)
12 R145: (-72, -126)
13 R160: (-28, -158)
14 R140: (24, -138)
15 R175: (30, -172)
16 R150: (75, -130)
17 R165: (126, -106)
18 R145: (136, -49)

Round to ints. Good spread.

Shapes/colors cycle: define classes within burst children order:
children 1..18 types: alternate circle, strip, spark, miniheart pattern: i1 circle pink, i2 strip gold, i3 spark white, i4 mini heart red, i5 circle white, i6 strip pink, i7 spark pink, i8 mini heart pink, i9 circle gold, i10 strip white, i11 spark gold, i12 mini heart white... 18 children, assign via nth-of-type(4n+1) circle, (4n+2) strip, (4n+3) spark, (4n+0) miniheart. Colors via further nth-of-type(6n+k)? Simplify: base color per type + nth-of-type odd/even tint. Use CSS vars per type with a couple overrides. Eh — simplest: give each `i` a color via `--c` in its nth-of-type position rule too (I'm writing 18 rules anyway — add --c and type class there? Type via markup classes instead: `<i class="c"></i>` explicit in HTML — easier to read! I'll write HTML with explicit classes and inline nothing; the per-item --tx etc. in CSS nth-of-type rules. Colors set per type class, overridden occasionally by :nth-of-type rules... Let me just include `--c` inside a few nth-of-type rules for variety. Fine.

Actually cleaner: write the 18 rules with all vars: `--tx, --ty, --rot, --dl, --s? no --s from type class`. Type classes define size/shape/color default; nth-of-type rules define motion vars + maybe --c override for some.

Durations: .9s base, ease: cubic-bezier(.15,.6,.4,1)? For explosive feel use ease-out with slight overshoot? Overshoot on translation outward looks odd; keep ease-out. Add keyframe 25% scale up small... In `fly` keyframe add a mid pop: 0% scale(0), 30% scale(calc(var(--s)*1.35))? calc in keyframes with var works. Let me write:

```css
@keyframes fly {
  0% { transform: translate(-50%,-50%) translate(0,0) scale(0) rotate(0deg); opacity: 1; }
  60% { opacity: 1; }
  100% { transform: translate(-50%,-50%) translate(var(--tx), var(--ty)) scale(var(--s)) rotate(var(--rot)); opacity: 0; }
}
```
Scale interpolates 0→var(--s) linearly-ish with the easing — particles grow while flying. 

Opacity: 0%:1 → stays till 60% → 0 at 100%. Good.

Mini heart --s .16, rot e.g. 120deg spinning.

Now rings: 3 rings, `.rings span` absolute centered, width/height 40px border 3px solid pink, border-radius 50%, keyframe expand: 0% scale(.3) opacity .8 border-width 3px... animate scale to 3.2 and opacity 0, durations .7s/.9s/.9s delays 0/.08/.16. Colors: pink, gold, white. But scale-based expansion from 40px base → final 128px radius — decent. Or make width 220px scale .2→1.4. Whatever; visually expanding rings.

Also a filled radial "puff" disc: `.puff` width 220 circle radial-gradient(rgba(255,120,160,.5), transparent 70%), scale .3→1.6 fade. 

Sunburst: `.burst-rays` 300px, background: repeating-conic-gradient(rgba(255,255,255,.85) 0 4deg, transparent 4deg 16deg), mask radial to soften: `-webkit-mask: radial-gradient(closest-side, #000 30%, transparent 70%)`. Animate scale .2→1.4 rotate 15deg fade. .7s. Only on check.

Ambient float hearts: `.floaters .f` — 7 items, each `.f` contains an inner `.mh`? Reuse mini heart markup: `<i class="mh"></i>` inside floater wrapper? Floater wrapper handles rise animation; inner heart is shape. `.f { position:absolute; bottom:-80px; left: var(--x); animation: rise var(--t) linear infinite; animation-delay: var(--dl); opacity: 0 }` keyframe rise: 0% {transform: translateY(0) scale(.5); opacity:0} 10% {opacity: var(--o)} 90% {opacity: var(--o)} 100% {transform: translateY(-105vh) scale(1.1); opacity: 0}. Inner heart colored rgba(255,255,255,.10) or pink faint. Sway: include translateX wiggle via keyframe steps: 0/25/50/75/100 x offsets ±. But single keyframe controlling both rise and sway: 
```
@keyframes rise {
 0% { transform: translate(0, 0) rotate(0deg); opacity: 0 }
 8% { opacity: var(--o) }
 25% { transform: translate(24px, -27vh) rotate(12deg) }
 50% { transform: translate(-18px, -53vh) rotate(-8deg) }
 75% { transform: translate(22px, -80vh) rotate(10deg) }
 92% { opacity: var(--o) }
 100% { transform: translate(-10px, -106vh) rotate(-6deg); opacity: 0 }
}
```
Hearts (`.mh` shape inside) scaled .1–.22, color faint pink. 7 floaters with varied --x (5%..92%), --t (11s–19s), --dl (negative delays to pre-populate! negative delay makes them mid-flight at load → first paint alive. Yes: --dl: -3s, -7s etc. so hearts are already floating at 3s screenshot. 

Also maybe ambient also includes 2-3 blurred blobs behind + subtle vignette.

Also — pre-click hint: a small tooltip above the button: "click me" with bouncing arrow? Or pulsing ring around button idle: `.circle::after` — animated pulse ring around button (scale 1→1.25 fade, 2s infinite) to invite click. Nice: "tap me" label. Add caption under card: "pure CSS · zero JavaScript · one checkbox". Add small hint above button inside stage: absolutely positioned "psst — click the heart" pill? Could overlap effects. Put hint below caption: "↑ go on, click it". Simple text hint under the count: "(go on, click it)". Hide hint on check (fade out) and show "click again to unlike 👀"? Fun: `.hint-a` shown unchecked, `.hint-b` shown checked ("WOW. click again to undo"). Ha — do the grid swap trick for the hint too, or simple crossfade: both stacked, toggle opacity. 

Text plan:
- overline: "100% CSS — 0% JAVASCRIPT"
- h1: "The Like Button" with gradient on "Like"? Maybe h1: "This button has a crush on you"? Keep: "The pure-CSS like button". Hmm. Title: "Like it. Loudly." Nice and short. Let me craft: overline "NO JAVASCRIPT · JUST CSS", h1 "Like it. Loudly.", subtitle "One checkbox, zero scripts. Click the heart — chaos is guaranteed. Click it again. It's an infinite party."
- card: button, caption swap Like/Liked, count swap 1,024/1,025, hint swap.
- footer: "made with :checked, @keyframes & far too much spare time" + maybe "reduced-motion friendly".

Fonts: system stack; h1 clamp(2.2rem, 5vw, 3.6rem), weight 800, letter-spacing -0.03em. Gradient text via background-clip. Color palette: bg #0d0a1a; text #efeaff; accent #ff2d6f, gold #ffc24b.

Blobs: .blob absolute, filter blur(90px), opacity .4: blob1 pink #ff2d6f 40vw top-left-ish, blob2 purple #6a5cff right, blob3 orange #ff8a3d bottom, each slowly moving (translate/scale, 18s alternate infinite). Behind content, above bg color. Blur heavy — performance ok (static-ish, animating transform only).

Shake: `#like:checked ~ .scene { animation: shake .5s ... }` — wait .scene contains everything including fixed rain? Shake whole scene: small translate jitter. But .scene shaking also shifts bg — that's the point (earthquake). Keyframes shake with tiny translate/rotate steps, 0.5s. But careful: .scene is the positioning context; animating it is fine.

However: applying animation to .scene when :checked — on uncheck it resets (fine). Also when checked persists, shake runs once. Good.

Also flash: card::before? Put `.boom` big radial glow behind button inside stage: width 700px height 700px radial-gradient(circle, rgba(255,80,130,.35), rgba(255,80,130,.12) 30%, transparent 65%), base opacity 0 scale .6, on check keyframe: 0% {opacity:0 scale .5} 25% {opacity:1 scale 1} 100% {opacity:0 scale 1.15}, .9s. This is behind button (z-index 0) — above card? It's inside stage inside card; card overflow visible? Set card overflow visible (default) so glow spills beyond card. Good.

z-index stack inside stage: boom(0) < burst-rays(1) < rings(1) < circle button(2) < heart(3) < particles(4) < emoji ring(4). Particles inside .burst layer with z 5, pointer-events none.

DOM sketch:

```html
<input type="checkbox" id="like" class="sr-like" aria-label="Like">
<div class="scene">
  <div class="bg">
    <span class="blob b1"></span><span class="blob b2"></span><span class="blob b3"></span>
    <div class="floaters">
      <span class="f f1"><i class="mh"></i></span> ×7
    </div>
  </div>
  <header class="head">
    <p class="overline">No JavaScript · 100% CSS</p>
    <h1>Like it. <span class="grad">Loudly.</span></h1>
    <p class="sub">One checkbox. Zero scripts. Click the heart and brace yourself — then click it again.</p>
  </header>
  <label class="stage" for="like">
    <span class="boom"></span>
    <span class="rays"></span>
    <span class="rings"><i></i><i></i><i></i></span>
    <span class="plusone">+1</span>
    <div class="emojis">
      <span>🎉</span>...×6
    </div>
    <div class="burst">
      <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>... ×18
    </div>
    <span class="circle">
      <span class="heart-wrap">
        <span class="heart h-outline"></span>
        <span class="heart h-cut"></span>
        <span class="heart h-fill"></span>
        <span class="heart h-shine"></span>
      </span>
    </span>
    <span class="caption">
      <span class="swap"><span class="a">Like</span><span class="b">Liked</span></span>
      <span class="dot">·</span>
      <span class="swap count"><span class="a">1,024</span><span class="b">1,025</span></span>
    </span>
  </label>
  <p class="hint swap"><span class="a">psst — click the heart ↑</span><span class="b">un-believe it? click again ↓</span></p>
  <footer class="foot">built with <code>:checked</code>, <code>@keyframes</code> & too much espresso</footer>
</div>
```

Wait — hint below card but the heart is above caption inside stage; hint "↑" pointing up to card. ok. Or place hint between card and footer. Also the "click again to unlike" — on check, hint swaps. cute.

Also the rain container:
```html
<div class="rain">
  <span class="drop d1"><i>🎉</i></span> ...
</div>
```
inside scene, fixed inset 0, z-index above card (confetti in front) but pointer-events none. 12 drops: mix emoji (7) and strip (5). Strip: `.drop.strip i { width:8px;height:16px;background:var(--c);border-radius:2px }` — drop contains `i` centered.

Wait z: rain should fall in front of everything (z 50), pointer-events none so it never blocks clicks. It's outside label → clicking does nothing, good.

Also make sure label stage has no text-selection weirdness: user-select none.

Circle size 150px; stage width ~ max(circle, caption) — caption below circle, stage is column flex centered, gap 18px. Position of effects: centered on the circle, not stage center. Effects layers absolute positioned relative to... put effects inside a `.core` wrapper that wraps only circle? Then effects center = circle center via left:50% top:50% of core. But caption below shifts stage center down slightly — effects centered on stage would be off by caption/2 height. Fix: wrap circle + effects in `.core { position:relative; width:150px; height:150px }`, effects absolute within core. Caption after core in stage. Then all effect layers (boom, rays, rings, burst, emojis, plusone) go inside core, centered with left:50% top:50% translate(-50%,-50%). z-index: circle itself relative z 2 inside core; effects z per layer. But burst particles need to fly outside core — absolutely positioned children of core can overflow visually (no clipping) as long as no overflow hidden. Fine. But clicks: burst/emojis inside label → toggle — harmless.

Hmm, but the core is inside label — label also contains caption. Clicking caption toggles like too. Fine (like buttons usually include text).

Now sizes responsive: at 375px width: h1 clamp small; card padding shrink; circle 150 → 128; heart fit scale .85. The heart fit: `.heart-wrap` centered in core via absolute inset-0 margin auto? Heart is 100×90 — center in 150 circle: left:50% top:50% translate(-50%,-52%). Put heart-wrap absolute at center with translate(-50%,-50%) — but heart-wrap has pop animation overriding transform! So: `.hpos` (positioner with translate) > `.heart-wrap` (animation) > hearts. Positioner absolute left 50% top 50% translate(-50%,-50%) width 100px height 90px. And responsive scale on positioner via media query: transform: translate(-50%,-50%) scale(.85). OK.

Wait also heart-wrap needs drop-shadow filter — filter on wrap (with clipped children) — apply filter on `.hpos` instead (parent of wrap): children clipped, parent filter drop-shadow sees final alpha → glow follows animated heart. filter + transform both on hpos fine. And filter transitions between like states on hpos.

Pop animation on heart-wrap: keyframes pop with scale — heart-wrap is 100×90 (its children absolute inset 0... make hearts absolute inset 0 inside wrap). transform-origin center bottom-ish (50% 85%) for cute bounce. 

Let me write all keyframes:

1. idlePulse (heart-wrap base, infinite 2.6s): 0/100 scale(1), 50% scale(1.06) — subtle heartbeat! Actually make it an actual heartbeat rhythm: 0% scale(1), 10% scale(1.12), 20% scale(1), 30% scale(1.09), 40% scale(1), 100% scale(1) — lub-dub! On checked, replace with pop animation (animation property overridden by more specific rule). Cute: idle heartbeat always, big pop on click. Also circle::before pulse ring idle.

2. pop (checked heart-wrap): as designed.

3. grow (h-fill on check): 0% scale(0); 55% scale(1.18); 75% scale(.94); 100% scale(1). transform-origin 50% 80%. Base transform scale(0) + transition for uncheck shrink.

Wait — h-fill base scale 0 with transition transform .35s; checked: animation grow .55s both; the end state scale(1) persists (fill-mode both + also set checked transform scale(1) for after? animation fill both keeps 100% state, ok). On uncheck: animation removed → computed transform goes to... checked selector also removed, so base scale(0), transition .35s shrink. But the transition needs the start value captured: at moment of uncheck, current transform = animation end 1 (fill both) → transitions 1→0. 

But careful: transitions from animation-filled values: when animation removed, does transition animate from the animated value? The animation was filling; upon removal, style change from animation value to base — transitions trigger on computed value change — yes, in Chrome, transition from animation end value to base works (the animated value counts as the before-change style). I believe this works. If not, worst case it snaps — acceptable risk, but let me double check: CSS Transitions spec: before-change style includes... "the computed values of all properties as of the previous style change event, with animations running at that time included"? Known behavior: transitions don't trigger from animation → non-animated in some cases. There's the known issue that when an animation ends with fill-mode forwards, and then is removed, transition may start from the *base* value (snap). Hmm. To be safe: set `#like:checked ~ .scene .h-fill { transform: scale(1); }` explicitly (checked base = 1). Then uncheck: before-change style = checked base (1) since animation removed in same style recalc... The before-change style is "the computed style at the previous style change event" — which included the animation's effect? Style change events happen after animations update... Actually spec says before-change style includes "declarations from animations" hmm — I recall: transitions start based on before-change style which *excludes* animation effects? No — it says the before-change style is the computed style "as of the previous style change event" — updating animations doesn't trigger style change events... Ugh, murky. 

Pragmatic: Chrome behavior — if animation fill-mode both keeps end state, and the property then changes because :checked removed → transition does animate from the animation's filled value in Chrome (I've seen this work: animation fill forwards → remove class → transition from animated value). Yes, I'm fairly confident Chrome transitions from the filled animation value. Even if it snapped, the unlike would still look ok-ish since outline fades back in simultaneously. Accept.

Alternative to sidestep: make h-fill rely on transition only with spring cubic-bezier for BOTH directions: checked: transform scale(1) with transition cubic-bezier(.34,1.56,.64,1) .45s — springy overshoot via bezier! Then no grow animation needed; shine animation runs separately. Overshoot via transition bezier is clean and reverses nicely on uncheck (shrink spring). Then pop keyframe on wrap adds extra drama. Simplify: h-fill uses spring transition. And h-shine keyframe on check provides sparkle. 

3'. shine keyframes: as discussed.

4. ringx (rings expand): scale .25→1 opacity .9→0, border-width maybe animate 3px→1px.

5. rayspin: scale .2→1.35, rotate 0→25deg, opacity .95→0.

6. boomflash: opacity 0→1→0, scale .55→1.1.

7. fly (particles).

8. ringpop (emoji): translate 0→var(--tx/--ty) with scale bounce: 0% {translate(-50%,-50%) scale(0) rotate(-10deg), opacity 1} 55% {scale 1.25} 75% {scale .95} 100% {translate(var(--tx),var(--ty)) scale(.55) rotate(8deg), opacity 0}. Note translate(-50%,-50%) needed always for centering — include in all frames: transform: translate(-50%,-50%) translate(var(--tx),var(--ty)) scale(...). Since --tx starts 0? Set base --tx/--ty 0 default so 0% frame uses translate(var(--tx0,0px))? Simpler: emojis positioned at center with left/top 50% and margin -half? Emoji font-size 34px; centering with translate(-50%,-50%) baked in every keyframe plus additional translate offset var. In 0% frame: transform: translate(-50%,-50%) translate(0,0) scale(0). In 100%: translate(-50%,-50%) translate(var(--tx),var(--ty)) scale(.6). OK same pattern as particles.

9. rise1 (floaters).

10. fall (rain drops).

11. shake (scene): translate/rotate jitter small: 
0% (0,0) 
10% (-6px, 3px) rot -.4deg
20% (6px,-4px) .4deg
30% (-7px,-2px)
40% (7px,3px) -.4deg
55% (-5px,2px)
70% (5px,-2px)
85% (-3px,1px)
100% (0,0)
duration .55s ease-out. Hmm shaking whole scene incl. text — crazy! good.

12. pulse ring idle (circle::after): scale 1→1.28 opacity .5→0, 2.4s infinite. Border ring pink? Use box-shadow ring: element same size as circle border 2px solid rgba(255,255,255,.25) radius 50%.

13. blobmove: translate/scale slow, alternate.

14. plusrise: +1 floats: 0% {opacity 0, translateY(6px) scale .6} 20% {opacity 1} 100% {opacity 0, translateY(-54px) scale(1)}. .9s.

15. maybe heart ripple on :active: circle scale .92 transition.

Also caption swap transitions: .swap spans translateY with transition .4s cubic-bezier(.2,.7,.3,1.2); count same. Checked: .a → translateY(-115%) opacity 0; .b → 0. Base: .b translateY(115%) opacity 0. Grid stack with overflow hidden. For grid overflow hidden need container height fixed by row — fine.

The hint below card: crossfade only (absolute stacked) or same grid swap. Use grid swap too for consistency.

Focus styles: `#like:focus-visible ~ .scene .circle { outline: 3px dashed #ff2d6f; outline-offset: 6px }`? outline on circle (inside label) shows ring. Good. (Keyboard note in prompt is about games; but supporting space bar here is nice. Note: keyboard works only after iframe click — fine, we don't rely on it.)

Aria: input aria-label="Like this page". Label contains text "Like" so accessible name exists via label content? The input is labeled by the label element with for=like → name = "Like Liked 1,024 1,025..."? The label content includes swap texts — accessible name computed from label text includes hidden-by-transform texts (they're visually moved but still in a11y tree). Meh — set aria-label on input to override: `aria-label="Like — trigger the party"`. Actually when aria-label present it overrides label content. Do that.

Reduced motion: media query: kill floaters? Set all animation-duration: .01ms? Provide `@media (prefers-reduced-motion: reduce){ *{animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.15s !important} }` — but that kills rain visuals mid-state? With .01ms they end instantly at final state (opacity 0) — invisible, fine. Idle pulse stops — fine. Acceptable minimal support. But careful: `!important` universal might break checked-state animations visibility (fill both end states ok). Fine.

Now sizes/positions concrete:

Scene: min-height 100vh (use 100dvh? iframe — use min-height: 100svh maybe; keep 100vh + padding), display flex column, align center, justify center? With header + card + hint + footer: use flex column centered with gaps; footer absolute bottom 18px. Header margin-top auto? Let me: .scene { min-height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center; gap: 26px; padding: 40px 20px 70px } footer absolute bottom.

Blobs: position absolute, .b1 { width:46vw; height:46vw; background:#ff2d6f; top:-10%; left:-8%; opacity:.35 } .b2 { width:40vw; right:-10%; top:20%; background:#5a4dff; opacity:.3 } .b3 { width:44vw; bottom:-14%; left:30%; background:#ff8a3d; opacity:.22 }. filter: blur(70px). Animation blob 22s ease-in-out infinite alternate: translate(±40px, ∓30px) scale(1.08). Different delays.

Wait performance: blur(70px) on 40vw elements animating transform — repaints each frame? transform animations on blurred elements: filter applies... it should be composited; ok.

Floaters: .f { position:absolute; bottom: -60px; left: var(--x); opacity 0; animation: rise var(--t) linear infinite; animation-delay var(--dl) } inner .mh heart scaled: .f .mh { transform: scale(var(--sc)); background: var(--c) } wait .mh is 100×90 clipped; scale inside .f. Hmm rise animation transforms .f (translate Y up 106vh). Inner heart static scale + faint color. Also faint floaters behind card? z-index: floaters z 1, content z 2. Yes bg container z 0, scene content above.

Float hearts colors: rgba(255,90,140,.14) etc; sizes --sc .12–.2 → 12–20px hearts.

Heart sizes: 100×90 in 150 circle fits nicely.

Caption: font-size 15px; count tabular-nums; color #a89fc4; checked color pink #ff6b93 with weight bump? Caption row: gap 8px align baseline.

Text "Liked" gradient text? Solid pink #ff5c8a.

Card: padding: 42px 56px 38px; radius 30px; bg #191231 (solid!); border 1px solid rgba(255,255,255,.07); box-shadow 0 30px 80px -20px rgba(0,0,0,.6), 0 0 0 1px? plus inner? Also a subtle top edge highlight: border-top-color slightly lighter? Keep simple. On checked: card border-color rgba(255,45,110,.35) transition .4s. Card maybe also slight translateY(-4px)? cute: on check card lifts (transition transform .5s spring). 

Wait — but .scene shake animation applies to scene; card transform separate fine.

Circle: width:150px;height:150px;border-radius:50%;background:#241c3f; border? box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); display:grid; place-items:center; transition: transform .18s, box-shadow .5s, background-color .5s, border-color .5s. Checked: box-shadow: inset 0 0 0 1px rgba(255,45,110,.25), 0 12px 50px -12px rgba(255,45,110,.55), 0 0 90px -30px rgba(255,45,110,.5). Also stage:hover circle: box-shadow slight + heart outline brighter; stage:active circle: transform scale(.93).

The circle is inside label before caption. Effects inside core positioned around circle.

Rain drops: 12: positions --x: 4%..94%, delays 0–.35s, durations .9–1.4s, spin var 320–560deg, sway ±40–90px, sizes emoji 20–30px.
Emoji set: 🎉 💖 ✨ 🥳 💯 🌟 🎊 💘; strips colors: #ff2d6f, #ffc24b, #7c5cff, #fff.

Rain animation: on :checked only, both fill-mode? After falling ends they sit at 105vh translated — beyond viewport, invisible. But overflow: they're fixed within .rain fixed inset-0 overflow hidden? If .rain overflow hidden, drops outside clip — but translating 105vh with overflow hidden on fixed container = no page scroll issues. Body overflow hidden anyway? The scene is 100vh; drops absolute top:-5% translate to 105vh — inside .rain { position:fixed; inset:0; overflow:hidden; pointer-events:none; z-index:60 }. 

But shake animates .scene transform — fixed children inside transformed ancestor become... transform on ancestor makes fixed descendants positioned relative to it (containing block change). .rain inside .scene with transform animation → fixed behaves like absolute relative to scene — fine, scene is full viewport anyway. During shake rain shakes too — fun. OK.

Alternatively put rain outside .scene, as sibling after: then selector #like:checked ~ .rain .drop. That keeps rain fixed regardless of shake (rain steady while scene shakes — even better contrast). Do that: .rain sibling. 

Also body overflow hidden to prevent scrollbars from any overflow (shake could cause? transform doesn't affect scroll. floaters bottom -60 rising — absolute within .bg inset 0 overflow hidden? .bg {position:fixed; inset:0; overflow:hidden; z-index:0} — clip floaters. Good. body margin 0; overflow hidden? If content taller than viewport on small screens, we need scroll... At 375×? mobile heights vary; content ~700px tall; keep overflow-y auto? Floaters fixed clipped, rain fixed clipped — nothing triggers horizontal scroll. Vertical: scene min-height 100vh with padding; if viewport short (e.g., 600px), content may exceed → allow scroll: html,body overflow-x hidden; overflow-y auto. But shake animating scene while scrollable — fine. Set overflow-x hidden only. Also blobs are inside fixed .bg → no overflow issues.

Hmm wait, blobs use vw sizes with left offsets — clipped by .bg overflow hidden. Good.

Also title responsive: h1 clamp(2rem, 6vw, 3.4rem). sub max-width 46ch.

Check the :active press: label :active on stage → .circle scale .93. Also add a quick "press ring" on mousedown? skip.

Let me also double check the "no horizontal scrollbar at 375": card padding 56px sides + 150 circle fits (150+112=262 < 375 minus scene padding 40 → 375-40=335 ok). At <420px: card padding 28px 24px.

Effects at small screens: rays 300px scaled — spills past viewport horizontally? Position absolute centered; width 300 < 375 fine. boom 700px — fixed .bg? boom inside core inside card, overflowing card/viewport horizontally — overflow visible ancestors... .scene has overflow visible; body overflow-x hidden → no scrollbar. But could cause repaint region beyond — fine visually (glow clipped at body edge? overflow-x hidden on body clips? Actually html overflow-x hidden clips). OK.

Emoji ring offsets up to ±160px from center — within card region mostly. fine.

Now write per-child rules.

Emoji ring positions (6): 
e1 🎉: (--tx:-120px, --ty:-105px)
e2 ✨: (115px,-115px)
e3 💖: (150px,10px)
e4 🥳: (-150px,20px)
e5 💯: (-70px,-135px)
e6 🌟: (85px,120px)? maybe (60,130). 
delays .04/.09/.14/.19/.24/.29s, duration .95s.

Particles 18 with (tx,ty) from table:
p1 (150,0) c #ff2d6f
p2 (169,62) t #ffc24b
p3 (103,87) s #fff
p4 (82,143) mh (mini heart)
p5 (25,143) c #ffc24b
p6 (-30,172) t #ff2d6f
p7 (-24,138) s #ff5c8a
p8 (-153,54) mh
p9 (-141,0) c #fff
p10 (-127,-46) t #7c5cff
p11 (-132,-109) s #ffc24b
p12 (-72,-126) mh
p13 (-28,-158) c #ff2d6f
p14 (24,-138) t #fff
p15 (30,-172) s #ffc24b
p16 (75,-130) mh
p17 (126,-106) c #7c5cff
p18 (136,-49) t #ff5c8a

Types markup order matches: c,t,s,mh,c,t,s,mh,c,t,s,mh,c,t,s,mh,c,t.

Rots: circles rot 0 (no visual), strips rot ±200–400deg, sparks rot ±180, minihearts rot ±120. Set per rule --rot.

Delays: 0–.1s varied: mostly 0, few .02/.05.

Durations: .85s base; some 1s. Use var(--dur)? Just set animation-duration per few. Keep all .9s, fine — with varied distances speeds differ anyway.

Now shine keyframe with background-position % — note: background-position on h-shine element 100×90 with background-size 250% 100%. Wait I said gradient angle 105deg... For sweep, simple horizontal: linear-gradient(100deg, transparent 40%, rgba(255,255,255,.9) 50%, transparent 60%) size 300% 100%, animate position 0%→100%. Visible window fraction = 100/300 = 33%. band at 50% of image; visible when 200p ≤ 50*3=150... let me recompute: image width = 300% of element = 300 units; element shows 100 units. offset = (300-100)*p = 200p. Visible image range [200p, 200p+100]. Band center at 150. Range contains 150 when 200p ≤ 150 ≤ 200p+100 → p ∈ [.25, .75]. Animating p 0→1 sweeps through. 

@keyframes sweep { 0% { background-position: 0% 0; opacity: 1 } 100% { background-position: 100% 0; opacity: 0 } } with .8s ease. Hmm opacity fading through whole sweep makes it dim quickly — set 0%:1, 70%:1, 100%:0.

But h-shine clip = heart path; base state must not show: opacity 0 base; animation on checked.

Also h-fill gradient might look flat; add second background layer: radial highlight top-left: background: radial-gradient(60% 60% at 30% 25%, rgba(255,255,255,.35), transparent 60%), linear-gradient(160deg, #ff7eb3, #ff2d55 55%, #c9184a). Nice juicy heart.

Idle heartbeat keyframes (wrap): 
0%,100% scale(1)
12% scale(1.13)
24% scale(1)
36% scale(1.08)
48% scale(1)
animation: heartbeat 2.8s ease-in-out infinite. Hmm heartbeat double-thump ~ every 2.8s. But pop animation on check replaces. After pop completes (0.75s, fill both? If fill both persists, heartbeat stops while checked — heart stays still but gradient+glow shows liked; maybe continue subtle heartbeat while liked: apply pop then... can't chain easily (animation: pop .75s both — single). Could use two animations comma: `animation: pop .8s cubic both, heartbeat 2.8s ease-in-out .8s infinite` — heartbeat delayed .8s starts after pop. Both set transform → later in list wins while both active; after pop ends (fill both holds its final transform FOREVER, overriding heartbeat!). fill-mode forwards holds final value which wins over subsequent? The last animation in list wins for the property when multiple animations affect it. Order: pop listed first, heartbeat second → heartbeat wins when active... during first .8s heartbeat is in delay (not active? delay phase: animations don't apply unless fill backwards — no fill → during delay no effect). So pop runs alone 0–.8s, then heartbeat runs and overrides pop's held value? Pop with fill both after finishing still "applies" its final value with fill; multiple animations: the one later in the list takes precedence. Heartbeat is later → wins. So: animation: pop .8s cubic-bezier(.22,1.4,.36,1) both, heartbeat 2.8s ease-in-out 1s infinite. Wait pop .8s and heartbeat delay 1s → .2s gap where pop's fill holds (scale 1) — smooth. 

But careful: pop keyframes include rotate wobbles ending 0 — fine.

Pop keyframes:
0% scale(1) (from idle state—wrap mid-heartbeat value... animation start jumps from current idle transform to 0% frame scale(1) — idle is ~scale(1) mostly; tiny snap acceptable. Better start 0% scale(.9) so click feels immediate press:
0% scale(.85)
35% scale(1.28) rotate(6deg)
55% scale(.92) rotate(-5deg)
75% scale(1.12) rotate(3deg)
100% scale(1) rotate(0)
.8s cubic-bezier(.3,1.6,.4,1)? Easing applies per keyframe segment... set ease overall fine.

Checked wrap also gets glow via hpos filter transition.

The h-outline hover: stage:hover .h-outline bg #cfc7e6; also stage:hover circle box-shadow slight.

Now, count swap container: `.swap{display:grid; overflow:hidden}` — wait overflow hidden + grid: height = row height; spans translateY 115% hidden below. Line-height: set spans line-height 1.2, padding 0. For count font-variant-numeric: tabular-nums.

Caption "·" dot separator static.

Hint swap: also grid. Position: below card, small text #7f76a0; hint-a: "psst — click the heart, it's starving"; hint-b: "ok that was a lot. click again to undo 😌". Fun copy.

Footer: "0 <script> tags · powered by one <input type=checkbox> · made with :checked & @keyframes". Show code snippet styling with <code>.

Head overline: letter-spacing .3em uppercase 11px color #ff5c8a with a leading ✦? 

h1: "Like it. Loudly." — gradient on "Loudly." maybe pink→gold.

Sub copy: "A like button with no JavaScript whatsoever — one checkbox, a label, and an unreasonable number of @keyframes. Click the heart. Then click it again. It never gets old."

Card width: content-driven (circle 150 + caption). 

Also add tiny "CSS-only" badge top-right of card? maybe skip, enough.

Edge: iOS Safari? Demo runs in Chrome; still add -webkit prefixes for mask? Use standard mask + -webkit-mask both.

clip-path path() — supported Chrome yes.

repeating-conic-gradient — Chrome yes.

Now, is the first paint (3s screenshot) meaningful? Yes: dark pretty bg with blobs + floating hearts + title + card with pulsing outline heart + hint. 

Also I should double-check the outline heart illusion with the cutout: .h-outline (gray heart 100×90) + .h-cut (bg-color heart scale .86). Both inside wrap; absolute inset 0. .h-cut transform: scale(.86) — transform-origin center → uniform band ~ (100-86)/2 = 7px horizontal, (90-77.4)/2 ≈ 6.3 vertical. Slightly thick; use .88 → 6px/5.4px. Good, chunky-cute outline.

But wait: hover brightens outline; on checked both fade. transition background .2s for hover, opacity .25s for check fade.

Also cut must exactly equal circle bg: circle bg #241c3f → .h-cut background #241c3f. On checked, circle bg shifts? I set checked circle background stays same (only shadow/border change). Keep same. But hover changes circle shadow only. OK.

BUT the circle has box-shadow inset ring 1px — at edges only, not under heart. Safe.

One more: during pop animation the wrap scales — outline hearts fade out .2s while wrap scales — fine.

Also on checked, .h-fill transform-origin 50% 78% grows from bottom — like filling up. Cute.

Also let me add "impact lines" — comic speed lines around button on check? The rays cover it.

Now plusone position: absolute in core, top: -8px? Place near top-right of circle: right: 6px top: 18px... Actually classic: "+1" appears above the count. Put inside core at top: -6px left: 50% translateX(-50%): floats up above heart. font-weight 800 color #ffc24b, font-size 20px, text-shadow glow. Rise -60px. Cute.

Let me also think about whether to add a "hold to charge" feature: :active long press could grow... CSS can't measure hold duration without transition-delay tricks — skip; click = full blast.

Wait, actually — one more crazy idea: page background hue shift on like: `.bg` filter hue-rotate animation on check? The blobs shift hue during shake — add to scene? Apply `#like:checked ~ .scene .bg { animation: hue 1s ... }`? .bg fixed inside scene... transform on scene ancestor — ok. Add subtle: keyframes hueflash { 0% filter none; 30% hue-rotate(-30deg) saturate(1.4); 100% none } 1s. Sure, cheap win. filter on .bg containing blobs already blurred — filter on parent fine.

Actually careful: .bg is position fixed; scene has animation shake (transform) → fixed becomes relative-to-scene — scene is full-viewport so same thing. OK.

Now, code writing. Also remember: NO <script> at all. Everything CSS.

Let me be careful with selector specificity: `#like:checked ~ .scene X`. Base rules like `.stage .h-fill` vs checked `#like:checked ~ .scene .h-fill` — id specificity higher, fine.

Input CSS:
```css
#like { position: fixed; top: 0; left: 0; width: 1px; height: 1px; opacity: 0; margin: 0; pointer-events: none; }
```

Also `cursor: pointer` on .stage. user-select none on stage.

Now writing full CSS mentally and checking responsive.

Media query <560px: 
- .scene padding 24px 14px 64px; gap 18px
- h1 clamp handles
- card padding 30px 22px 26px
- core stays 150? circle 132px: --circ scale? Circle is DOM size 150 — shrink via transform scale(.88) on circle? That conflicts with :active scale. Use transform on a wrapper... simpler: keep circle 150 even mobile (fits 375: card padding 22*2 + 150 = 194 fine). Keep 150 everywhere. Effects fine. So no resize needed! Only card padding & fonts adjust. Actually 150px circle on 375 screen looks big-good.

So minimal responsive tweaks: paddings, font clamps, sub width.

Footer at bottom absolute — on short screens may overlap card; use margin-top: 32px static instead of absolute? With min-height 100vh and centered column, footer in flow after hint with margin-top 40px — if content shorter than viewport, justify-content center leaves footer near middle... I'd rather: scene flex column center; footer absolute bottom 16px left 0 right 0 text-center. Overlap risk only if content very tall (short viewport ~550px height): content = head(~180) + card(~300) + hint(24) + gaps ≈ 560 — tight but ok. At 375×667 typical mobile: fits (content ~520). Fine, and absolute footer overlapping slightly is acceptable worst-case... make footer font 11px.

Let me now also design the "rays": repeating-conic-gradient(from -10deg, rgba(255,255,255,.9) 0deg 5deg, transparent 5deg 15deg) → 24 rays. mask radial-gradient(closest-side, #000 20%, transparent 72%). size 320px. keyframes rayburst: 0% { transform: translate(-50%,-50%) scale(.2) rotate(-8deg); opacity: 0 } 15% {opacity:.85} 100% { transform: translate(-50%,-50%) scale(1.15) rotate(10deg); opacity: 0 } .7s ease-out.

Rings: base 150px circle centered, border 3px solid; ring1 pink #ff2d6f dur .7 delay 0; ring2 #ffc24b .8 .07; ring3 rgba(255,255,255,.8) .9 .14. keyframe ringout: 0% { transform: translate(-50%,-50%) scale(.45); opacity: 1 } 100% { transform: translate(-50%,-50%) scale(2.1); opacity: 0 }. Scale of 150 → 315px final, border thins visually. Good.

Boom: 560px radial-gradient(circle closest-side, rgba(255,77,140,.5), rgba(255,77,140,.18) 45%, transparent 72%). keyframe boomout: 0% {opacity:0; transform: translate(-50%,-50%) scale(.5)} 20% {opacity:1} 100% {opacity:0; transform: translate(-50%,-50%) scale(1.05)} .85s.

Also a bright flash inside heart? skip.

Also confetti strips inside .burst? already have strips.

Rain: 
`.drop { position:absolute; top:-6%; left: var(--x); font-size: var(--fs); opacity: 0; }` on checked: `animation: fall var(--dur) cubic-bezier(.3,.5,.6,1) var(--dl) forwards` — forwards keeps end (opacity 0 end? set 100% opacity: 0 → after animation ends hidden. forwards fine.
keyframes fall: 0% { transform: translate(0,-6vh) rotate(0deg); opacity: 1 } 50% { transform: translate(var(--sw), 50vh) rotate(calc(var(--spin)/2)) } 100% { transform: translate(calc(var(--sw)*-0.6), 106vh) rotate(var(--spin)); opacity: 0 }.

calc(var(--spin)/2) ok.

12 drops: 
d1 🎉 x 6% fs 26 dur 1.3 dl .02 sw 40px spin 340deg
d2 strip #ff2d6f x 14% dur 1.1 dl .12 sw -50 spin -420
d3 ✨ x 24% fs 20 dur 1.4 dl .05 sw 60 spin 520
d4 💖 x 33% fs 24 dur 1.2 dl .18 sw -40 spin -300
d5 strip #ffc24b x 44% dur 1.05 dl .08 sw 55 spin 460
d6 🥳 x 52% fs 28 dur 1.35 dl 0 sw -60 spin -380
d7 strip #7c5cff x 61% dur 1.15 dl .22 sw 45 spin 400
d8 💯 x 70% fs 22 dur 1.25 dl .1 sw -55 spin -500
d9 🌟 x 78% fs 26 dur 1.1 dl .16 sw 50 spin 340
d10 strip #fff x 86% dur 1.3 dl .06 sw -45 spin -460
d11 🎊 x 93% fs 24 dur 1.2 dl .13 sw 60 spin 380
d12 💘 x 40% fs 18 dur 1.45 dl .2 sw -70 spin -350

Strips: `.drop.t i { display:block; width:9px; height:16px; border-radius:2px; background: var(--c); }` where i is the child. For emoji drops, i is text: `.drop.e i { font-size: var(--fs); display:block; line-height:1 }`.

Hmm structure: `<span class="drop e" ...><i>🎉</i></span>` with vars set in CSS nth-child rules. But .drop i display block; emoji fine.

Set vars via nth-of-type on .drop with classes for type.

OK count sizes: caption font 16px; count tabular.

One concern: `~` sibling selector: input then .scene and .rain are siblings of input inside body. `#like:checked ~ .scene ...` and `#like:checked ~ .rain .drop`. Good.

Focus-visible: `#like:focus-visible ~ .scene .circle { outline: 3px solid #ff5c8a; outline-offset: 5px; border-radius: 50% }` — circle already border-radius 50%, outline follows border radius in Chrome. 

Let me write the heart clip-path string once as a CSS var? `--heart: path("M50 86C26 66 4 48 4 26.5C4 13 15 3 28 3C37.6 3 45.6 8.4 50 17.5C54.4 8.4 62.4 3 72 3C85 3 96 13 96 26.5C96 48 74 66 50 86Z");` then `clip-path: var(--heart)`. Custom property containing path() — supported. Set --heart on a shared root (.heart class elements all use). Define --heart on .heart, .mh (both need). Put --heart on a universal-ish scope: define on .heart and .mh rules, or define on :root and clip-path: var(--heart) in each. Do :root.

Mini hearts .mh also used in floaters and burst. 

.heart { position:absolute; inset:0; width:100px; height:90px; } — inset 0 sets all four; width/height explicit fine. clip-path var(--heart).

.mh { position:absolute; width:100px; height:90px; clip-path: var(--heart); background: currentColor?} colors per context: floaters .mh background rgba pink; burst .mh background: var(--c, #ff2d6f). Use `background: var(--c, rgba(255,80,130,.5))`.

Sparkle .s: width:16px;height:16px; clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%); background: var(--c,#fff). 4-point star? That polygon: points at (50,0),(60,40),(100,50),(60,60),(50,100),(40,60),(0,50),(40,40) — diamond-ish star. good.

Circle particle .c: width 11px; height 11px; border-radius 50%; background var(--c).

Strip .t: width 6px; height 18px; border-radius 3px; background var(--c).

Burst children positioned: left:50%; top:50%; (translate in keyframes). Base state: opacity 0; transform: translate(-50%,-50%) scale(0). Animation on checked: fly .95s cubic-bezier(.16,.68,.4,1) var(--dl, 0s) forwards.

Wait — forwards keeps 100% (opacity 0, offset far) — fine.

Mini heart base scale 0 via same base rule (transform translate(-50%,-50%) scale(0)) good.

Keyframes fly (using --s): 100% scale(var(--s,1)). Circles/sparks/strips --s:1 (default), mini hearts --s:.16 set in .mh? But .mh in floaters uses transform for sizing... floaters: inner .mh needs static scale var — different context: `.f .mh { transform: scale(var(--sc)) }` (no animation, static) fine. In burst: .burst .mh --s:.16. But floaters' .mh default has base transform from `.burst i` rule? Base rules for burst particles under `.burst i` — scoped to burst. .f .mh separate rules. And floaters .mh default background var. Manage scoping carefully.

Also the emoji ring spans: .emo spans font-size 30px; base opacity 0 transform translate(-50%,-50%) scale(0); on checked animation ringpop .95s cubic var(--dl) forwards.

Keyframes ringpop:
0% { transform: translate(-50%,-50%) translate(0,0) scale(0) rotate(0deg); opacity: 1 }
55% { opacity: 1 }
70% { transform: translate(-50%,-50%) translate(calc(var(--tx)*.75), calc(var(--ty)*.75)) scale(1.25) rotate(10deg) } — hmm multi keyframes with calc(var * .75) fine.
100% { transform: translate(-50%,-50%) translate(var(--tx), var(--ty)) scale(.55) rotate(-12deg); opacity: 0 }

Emoji elements positioned left:50% top:50% inside .emo container absolute inset 0 of core.

Everything pointer-events none except circle/caption.

Stage layout: `.stage { position:relative; display:flex; flex-direction:column; align-items:center; gap:16px; cursor:pointer; user-select:none; -webkit-user-select:none; }` `.core { position:relative; width:150px; height:150px }` `.circle { position:absolute; inset:0; ... }` — wait circle needs to be in flow for core sizing? core fixed 150×150, circle inset 0 absolute. fine. Effects absolute inset 0 (layers) each with their own children positioned at center.

Layer elements: `.boom, .rays, .rings, .emo, .burst { position:absolute; inset:0; pointer-events:none }` each child centered individually. .boom & .rays themselves are the visual (single elements) — make them absolute centered: `.boom { position:absolute; left:50%; top:50%; width:560px; height:560px; border-radius:50%; transform: translate(-50%,-50%) scale(.5); opacity:0; ... }` with keyframes including translate. Since base transform includes translate(-50%,-50%) scale(.5) and animation overrides transform — keyframes must include translate(-50%,-50%) every frame. Fine.

Rings: `.rings i { position:absolute; left:50%; top:50%; width:150px; height:150px; border:3px solid; border-radius:50%; margin: -75px 0 0 -75px }` — using margin centering avoids translate in keyframes! Then keyframes only scale + opacity: transform: scale(.45)→scale(2.1). margin trick nice. Similarly for particles could use margins — but particle sizes differ (mini hearts 100×90) — margin: -45px 0 0 -50px each type... translate in keyframes is fine too, keep translate approach for burst (since sizes vary), margin approach for rings/boom/rays (fixed sizes).

Actually for .boom/.rays: margin trick: left:50%; top:50%; margin: -280px (half 560); then transform: scale(...) only. Cleaner. rays 320 → margin -160px.

The 100% translateY(-50%) issue gone.

Caption margin-top 6px.

Also stage active: `.stage:active .circle { transform: scale(.93) }` — circle base has no transform; add transition transform .15s. Circle absolute inset 0 — transform scale fine.

Hmm also add :active heart squish: `.stage:active .heart-wrap? wrap has animation... :active transform overridden by animation. skip; circle scale enough.

Now assemble copy & polish. Header:

overline: "✦ 100% CSS · 0% JAVASCRIPT ✦"
h1: `Like it. <em>Loudly.</em>` em gradient italic? em not italic (font-style normal), gradient text pink→gold.
sub: "One checkbox, one label, an absolutely unreasonable number of keyframes. Click the heart. Then click it again. And maybe one more time."

hint swap below card:
a: "psst — the heart is clickable ↑"
b: "fine, click again to take it back ↓"

footer: `0 <script> tags · 1 checkbox · 47 @keyframes` — count roughly; say "one checkbox · zero scripts · pure :checked magic". Use <code> tags styled.

Also maybe show a tiny "how" line? footer enough.

Colors: 
--bg #0d0a1e; card #191231; circle #241c3f; text #efeaff; muted #9c93bd; pink #ff2d6f; pink-soft #ff5c8a; gold #ffc24b; violet #7c5cff.

bg base: radial-gradient(1200px 800px at 70% -10%, #1a1440, transparent), #0d0a1e? .bg background: radial gradients + solid. Blobs add color.

Body font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif.

Title font-weight 800, letter-spacing -0.035em.

Let me also double check the grid swap with overflow hidden — `.swap { display:grid; overflow:hidden } .swap > span { grid-area: 1 / 1; }` — overflow hidden on grid container with fixed content height (one line). The moving span translateY(115%) inside overflow hidden — clipped. But the container's height: row sized by tallest item — both spans single line same font → equal. Good. transitions on spans.

Count swap font: tabular numbers so "1,024"→"1,025" same width.

Caption row: display flex gap 8 align-items center. Both swaps same font-size.

Hmm "Liked" color pink vs "Like" muted: `.caption .swap .b { color:#ff5c8a; font-weight:700 }` `.a { color:#b9b0d8; font-weight:600 }`.

Also heart color when checked — caption pink matches.

Now let me also consider: clicking toggles off → all effect animations reset instantly (rings/particles vanish mid-flight if quick toggle). Acceptable chaos.

Double-check first-paint: no animations depend on checked except idle ones (heartbeat, pulse ring, floaters, blobs) — all run at load. Screenshot at 3s shows: title, card, gray outline heart pulsing, floating dim hearts, hint. 

Edge: does the pulse ring around circle (idle invite) look good? `.circle::after { content:""; position:absolute; inset:-1px; border-radius:50%; border:2px solid rgba(255,255,255,.28); animation: ping 2.6s ease-out infinite; }` keyframes ping: 0% { transform: scale(1); opacity: .55 } 70%,100% { transform: scale(1.22); opacity: 0 }. On checked: pause/hide ping (animation-play-state or opacity 0): `#like:checked ~ .scene .circle::after { animation-play-state: paused; opacity: 0; transition: opacity .3s }` — hmm pausing leaves ring mid-scale visible unless opacity 0. Set `#like:checked ~ .scene .circle::after { opacity: 0 !important; animation: none }` careful specificity fine without important.

Also on hover, ping brightens? fine as is.

Let me now also verify no JS requirement: yes, zero script tags. 

Potential pitfall: `~` requires .scene to be sibling AFTER input — yes.

Also `<label for="like">` — clicking label toggles checkbox. Label inside .scene. Input outside .scene (first child of body). Label association via for works across DOM. ✓.

Keyboard: input focusable via tab (opacity 0 fixed). Space toggles → all effects. focus-visible ring shown. ✓ (nice extra).

Print exact code now. Also remember viewport meta. Title. 

Let me carefully write the CSS with organization:

```
:root vars
reset
#like hidden
.scene layout
.bg blobs floaters
.head typography
.stage/.core/.circle/.heart...
effects keyframes
checked-state rules
.rain
.foot
responsive
reduced motion
```

Write keyframes list:
- ping (idle ring)
- heartbeat (idle wrap)
- pop (checked wrap)
- growless — none (h-fill uses transition spring)
- sweep (shine)
- ringout (rings)
- rayburst
- boomout
- fly
- ringpop (emoji)
- plusrise
- fall
- rise (floaters)
- blobdrift
- shake
- hueflash (bg)

Let me define the shake keyframes with rotate tiny.

Also `#like:checked ~ .scene { animation: shake .55s cubic-bezier(.36,.07,.19,.97) both }`.

Also card lift on check: `#like:checked ~ .scene .card { transform: translateY(-6px); border-color: rgba(255,92,138,.35) }` card transition .5s.

Wait — .card contains stage? Structure: .card wraps .stage. Card is just visual panel: `<div class="card"><label class="stage">...</label></div>`. Or make label itself the card? Effects (rain) outside anyway. Making the whole card the label = bigger click area, cursor pointer over whole card — actually GOOD for a demo (easy to click). Hmm but text-selection of hint inside? hint outside card. Card content: core + caption. Making whole card clickable is user-friendly. Let me: `<label class="card" for="like"> ... </label>`. Then .stage concept merges into card: `.card { position:relative; ...; cursor:pointer; display:flex; column; align-items:center; gap:16px; }`. Effects inside core inside card. Shake moves scene incl card. :active on card scales circle. Hover on card brightens outline heart. OK simpler DOM.

DOM final:

body
  input#like
  div.scene
    div.bg (blobs, floaters)
    header.head
    label.card[for=like]
      span.core
        span.boom
        span.rays
        span.rings > i×3
        span.emo > span×6
        span.burst > i×18
        span.plusone "+1"
        span.circle > span.hpos > span.heart-wrap > (h-outline,h-cut,h-fill,h-shine)
      span.caption
        span.swap (Like/Liked)
        span.sep "·"
        span.swap (1,024/1,025)
    p.hintswap (grid swap hints)
    footer.foot
  div.rain > span.drop ×12

Wait: .core is 150×150; circle inset 0 absolute inside core; caption below core inside card flex column.

plusone: absolute in core top: -10px? place left 50% top -4px, transform translateX(-50%); keyframes rise: translateY(8px)→(-56px), need base translateX(-50%) — bake into keyframes: 0% { transform: translate(-50%, 10px) scale(.6); opacity:0 } 25% { opacity:1 } 100% { transform: translate(-50%,-60px) scale(1); opacity:0 }.

Now hpos: absolute left 50% top 50% width 100 height 90 margin: -45px 0 0 -50px (margin centering so no transform on hpos — keeps filter/transition separate). hpos has filter transition (glow). heart-wrap inside inset 0 with heartbeat animation. hpos also could hold responsive scale — skip scaling (fixed sizes fit mobile too).

heart children: .heart absolute inset 0? width 100 height 90 at top-left of wrap (wrap is 100×90) — inset 0 fine.

.h-outline { background: #6f6790 } hover→ #bfb6dd. transition background .25s.
.h-cut { background: #241c3f; transform: scale(.88) }
checked: outline & cut opacity 0 (transition .2s).
.h-fill { background: radial + linear; transform: scale(0); transform-origin: 50% 80%; transition: transform .5s cubic-bezier(.3,1.9,.5,1) } — spring overshoot bezier: cubic-bezier(.3,1.9,.4,1) gives overshoot ~1.15. checked: transform scale(1) (transition does the pop!). Actually then I don't need a grow keyframe — the transition bezier gives overshoot bounce. But bezier overshoot on scale from 0→1 with y>1 gives values >1 — springy. 

checked shine: animation sweep .8s ease-out .1s both.

hpos filter: base: drop-shadow(0 8px 22px rgba(255,45,111,0)) drop-shadow(0 0 46px rgba(255,45,111,0)); checked: drop-shadow(0 10px 26px rgba(255,45,111,.6)) drop-shadow(0 0 60px rgba(255,45,111,.45)); transition filter .45s. Also hover slight: drop-shadow(0 8px 22px rgba(255,45,111,.25))... keep base zero to checked strong; hover add small: base hover (card:hover) → .2 alpha. And transition covers both.

Note: filter + fixed px drop-shadows on clipped children: hpos children are wrap (with animated transform) — drop-shadow recomputed each frame — fine.

Also heart idle heartbeat: wrap animation heartbeat 3s infinite; checked: animation: pop .85s cubic-bezier(.28,1.7,.4,1) both, heartbeat 3s ease-in-out 1.2s infinite.

Hmm one nuance: during checked, heartbeat continues forever — subtle life while liked. good.

Wait, specificity: `.card:hover .h-outline` etc fine.

Rain z-index: .rain fixed inset 0 z 80 pointer-events none overflow hidden.
.bg z 0; .scene content z: head/card/hint z 1 (position relative).
.foot z 1.

Scene position relative; shake animation transform on scene — creates containing block for fixed descendants (.bg inside scene!). I placed .bg inside .scene — with scene transformed (animated), .bg's position:fixed behaves relative to scene — scene spans full viewport height & width (min-height 100vh, width 100%) — so visually identical. Except during shake, bg shakes — desired (whole world shakes). OK good. But wait: when animation has `both` fill and ends at identity, does the containing block persist? A finished animation with fill both keeps applying transform → containing block persists — fine either way.

BUT caution: .rain is sibling OUTSIDE scene → truly fixed, unaffected by shake. Good.

Now hueflash on .bg on check: `#like:checked ~ .scene .bg { animation: hueflash .9s ease-out }` keyframes: 0/100% filter none... filter with 'none' can't interpolate to hue-rotate? Use from filter: hue-rotate(0deg) saturate(1) to hue-rotate(-35deg) saturate(1.5) mid... keyframes: 0% { filter: hue-rotate(0) saturate(1) } 35% { filter: hue-rotate(-28deg) saturate(1.45) } 100% { filter: hue-rotate(0) saturate(1) }.

Also .bg contains floaters hearts — hue shift affects them — fine.

Blobs keyframes: blobdrift: 0% { transform: translate(0,0) scale(1) } 100% { transform: translate(50px, -40px) scale(1.15) } alternate infinite 16s/20s/24s with delays.

Floaters: 7 items:
f1: --x: 8%; --t: 14s; --dl: -2s; --sc:.16; c pink .16
f2: --x: 20%; --t: 18s; --dl: -9s; --sc:.11; c #ffc24b .12
f3: --x: 34%; --t: 12s; --dl: -5s; --sc:.2; c pink .14
f4: --x: 52%; --t: 17s; --dl: -12s; --sc:.13
f5: --x: 68%; --t: 15s; --dl: -7s; --sc:.18; gold .10
f6: --x: 82%; --t: 19s; --dl: -3s; --sc:.12; violet .14
f7: --x: 92%; --t: 13s; --dl: -10s; --sc:.15; pink .12

.heart opacity var --o in keyframes: set keyframe 8%/88% opacity: var(--o, .5).

Hmm: opacity property with var in keyframes OK.

Also floaters behind card (z): .bg z-index:0; scene children z 1 → floaters behind card. Card is opaque solid → floaters passing behind hidden — they're at page edges mostly; fine. Could put floaters above bg but below content: yes that's current.

Maybe ALSO 2 floaters in front (z 30, very faint, pointer-events none) for depth? skip.

Also small detail: scene gap and layout — justify-content: center → vertical center. With head + card + hint + foot(absolute). 

Font sizes:
overline 11px ls .32em uppercase color #ff5c8a weight 700.
h1 clamp(2.3rem, 6.5vw, 3.9rem) — mobile 2.3rem*16=37px ok.
sub 15px muted, max-width 52ch, line-height 1.6.
caption 15px.
hint 13px muted italic? no italic; small.
foot 11.5px code styled #8f86ad; code with bg rgba(255,255,255,.06) padding 2px 6px radius 6px font 11px.

Also selection color styling ::selection pink. Nice touch.

Also details: `html { color-scheme: dark }`.

Let me make sure the h1 gradient text: background: linear-gradient(90deg, #ff5c8a, #ffc24b); -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent.

Now — the burst children CSS rules (18 nth-of-type) — write them compactly:

```css
.burst i:nth-of-type(1) { --tx: 150px; --ty: 0px; --rot: 0deg; }
...
```
with --c overrides on some. Type classes assign default colors: .c { --c: #ff2d6f } .t { --c: #ffc24b } .s { --c:#fff } .mh { --c:#ff2d6f; --s:.16 } and nth-of-type can override --c: e.g. n5 { --c:#ffc24b }. Let me assign colors per particle from my table:

p1 c #ff2d6f
p2 t #ffc24b
p3 s #fff
p4 mh default pink #ff2d55? mini hearts colors: alternate #ff2d6f/#ff5c8a/#c9184a? give: p4 #ff2d6f, p8 #ff5c8a, p12 #ffc24b? gold heart cute, p16 #c81d5e.
p5 c #ffc24b
p6 t #ff2d6f
p7 s #ff5c8a
p9 c #fff
p10 t #7c5cff
p11 s #ffc24b
p13 c #ff2d6f
p14 t #fff
p15 s #ffc24b
p17 c #7c5cff
p18 t #ff5c8a

Rot values: circles 0 (invisible rotation, but scale wobble? fine). strips: p2 260deg, p6 -300, p10 340, p14 -260, p18 300. sparks: p3 180, p7 -160, p11 200, p15 -200. minihearts: p4 120, p8 -140, p12 160, p16 -120.

Delays: mostly 0; p4 .03, p8 .05, p12 .04, p16 .06 (hearts slightly later). ok.

Durations: base .95s; long-distance ones 1.05s? keep uniform .95s with easing — fine. Actually slight variety: set per nth --dur? skip, uniform.

Emoji nth rules: .emo span:nth-child(k) { --tx.. --ty.. --dl }.

Emoji list: 🎉 ✨ 💖 🥳 💯 🌟 positions as earlier.

Now ringpop overshoot keyframes need consistent translate(-50%,-50%): fine.

Also, `.emo span` base: opacity 0; transform: translate(-50%,-50%) scale(0); position absolute left 50% top 50%; font-size 30px; line-height 1; (emoji). filter drop-shadow small glow? nah.

Alright, also think: 18 burst + 6 emoji + 3 rings + 12 rain + 7 floaters + 3 blobs — ~50 animated elements on click; Chrome handles.

One more idea for "crazy": the card itself does a little jump flip? Card lift -6px is there. Also caption bounce: `#like:checked ~ .scene .caption { animation: capbounce .6s }` keyframes scale 1→1.08→1. cute, add.

Also title reaction? "Like it. Loudly." could swap gradient hue on check — hueflash covers ambience. skip.

Potential issue — label wrapping everything in card: clicking caption also toggles: fine. user-select none to prevent text select on double clicks. Add `-webkit-tap-highlight-color: transparent`.

Also iOS double-tap zoom — meta viewport user-scalable ok default.

Another check — `.card:active .circle { transform: scale(.93) }` — circle also has `transition: transform .18s, box-shadow .5s`. On quick click: press scale then effects. good.

But note: circle transform base none; on checked no transform change (wrap pops instead). fine.

Now the +1: also maybe show on every re-like — yes since animation re-applies on re-check. 

Also: un-like — is there any effect? Text swaps back, heart unfills with spring shrink, glow fades, outline fades in. Decent.

Hmm — one more consideration about transitions on .swap spans: `transition: transform .45s cubic-bezier(.25,.9,.3,1.15), opacity .35s` — slight overshoot on text slide, nice.

hint swap: `.hint { display:grid; text-align:center } .hint > span { grid-area:1/1; transition: opacity .4s, transform .4s }` — hint-a visible base; hint-b opacity 0 translateY(6px); checked reverse. Also keep hint container height stable = one line (grid auto). hints are one-liners; on mobile they might wrap to 2 lines — grid stacks both, container = max height — fine.

Foot: position absolute bottom: 14px; left 0; right 0; text-align center; padding 0 16px.

Let me also double-check `.swap` overflow hidden clipping descenders? line-height 1.25, fine. "Liked" d descender — line-height 1.3 safer. Set spans display block, line-height 1.3.

Grid + overflow hidden: container has no explicit height — row height = max content — fine.

One more subtle thing: `#like:checked ~ .scene .h-outline` fade — transition opacity .2s on base for both directions.

Also during check: fill grows OVER outline before outline fades? Set outline fade fast (.15s) so gradient edges don't show gray ring. Fill transition .5s covers outline anyway except the 6px band. Outline fade .15s quickly. good.

Let me now also handle: `.burst i` etc. animations applied `#like:checked ~ .scene .burst i { animation: fly .95s cubic-bezier(.15,.62,.35,1) var(--dl,0s) forwards; }` — var in animation-delay shorthand: `animation: name dur easing var(--dl, 0s) forwards` — animation-delay accepts var? animation shorthand with var() for delay — the whole shorthand is parsed with var substitution, works.

Also for replay: toggling uncheck removes; recheck re-adds → restart. ✓

For `.rays` and `.boom` base opacity 0 + transform scale — with margin centering no translate needed.

Let me write out final keyframes concretely:

```css
@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  12% { transform: scale(1.12); }
  24% { transform: scale(1); }
  36% { transform: scale(1.07); }
  48% { transform: scale(1); }
}
@keyframes pop {
  0% { transform: scale(.85) rotate(0deg); }
  30% { transform: scale(1.25) rotate(7deg); }
  50% { transform: scale(.9) rotate(-6deg); }
  72% { transform: scale(1.14) rotate(4deg); }
  100% { transform: scale(1) rotate(0deg); }
}
@keyframes sweep {
  0% { background-position: 0% 0; opacity: 1; }
  70% { opacity: 1; }
  100% { background-position: 100% 0; opacity: 0; }
}
@keyframes ringout {
  0% { transform: scale(.5); opacity: 1; }
  100% { transform: scale(2.15); opacity: 0; }
}
@keyframes rayburst {
  0% { transform: scale(.2) rotate(-10deg); opacity: 0; }
  18% { opacity: .9; }
  100% { transform: scale(1.2) rotate(12deg); opacity: 0; }
}
@keyframes boomout {
  0% { transform: scale(.45); opacity: 0; }
  22% { opacity: 1; }
  100% { transform: scale(1.08); opacity: 0; }
}
@keyframes fly {
  0% { transform: translate(-50%,-50%) translate(0,0) scale(0) rotate(0deg); opacity: 1; }
  55% { opacity: 1; }
  100% { transform: translate(-50%,-50%) translate(var(--tx),var(--ty)) scale(var(--s,1)) rotate(var(--rot,0deg)); opacity: 0; }
}
@keyframes ringpop {
  0% { transform: translate(-50%,-50%) translate(0,0) scale(0) rotate(0deg); opacity: 1; }
  60% { opacity: 1; }
  100% { transform: translate(-50%,-50%) translate(var(--tx),var(--ty)) scale(.5) rotate(-14deg); opacity: 0; }
}
```
Hmm ringpop no overshoot mid-keyframe — add 70% frame with translate *0.8 and scale 1.15:
```
  70% { transform: translate(-50%,-50%) translate(calc(var(--tx)*.8), calc(var(--ty)*.8)) scale(1.15) rotate(8deg); opacity: 1; }
```
Good.

```css
@keyframes plusrise {
  0% { transform: translate(-50%, 12px) scale(.5); opacity: 0; }
  25% { opacity: 1; }
  100% { transform: translate(-50%, -62px) scale(1); opacity: 0; }
}
@keyframes capbounce {
  0%,100% { transform: scale(1); }
  40% { transform: scale(1.09); }
  70% { transform: scale(.97); }
}
@keyframes shake {
  0%,100% { transform: translate(0,0) rotate(0deg); }
  10% { transform: translate(-7px,4px) rotate(-.5deg); }
  20% { transform: translate(7px,-5px) rotate(.5deg); }
  35% { transform: translate(-8px,-3px) rotate(-.4deg); }
  50% { transform: translate(8px,4px) rotate(.45deg); }
  65% { transform: translate(-6px,2px) rotate(-.3deg); }
  80% { transform: translate(5px,-3px) rotate(.25deg); }
  90% { transform: translate(-3px,2px) rotate(-.15deg); }
}
@keyframes fall { ... }
@keyframes rise { ... }
@keyframes blobdrift { ... }
@keyframes ping { 0% { transform: scale(1); opacity: .5 } 75%, 100% { transform: scale(1.24); opacity: 0 } }
@keyframes hueflash { ... }
```

fall uses translate3d? fine 2d.

For ringpop translate uses var with calc multiplication — ok.

Now the floaters rise keyframe with translate x oscillation — heart shapes: note .f children .mh scaled — heart shape 100×90 scaled .12 visually but box 100×90 — the .f positioned left var(--x) — box width 100px might overflow viewport edge at --x 92% → left:92% + 100px → overflow → .bg overflow hidden clips. fine.

Wait — .f .mh transform scale — but .mh base in burst has translate(-50%,-50%) scale(0) from `.burst i` rule? I scope burst base styles with `.burst i` selector; floaters use `.f .mh` separately. Common .mh rule: width/height/clip/background only. Burst adds positioning/animation. Floaters add scale/color. No conflicts. ✓

Also .mh default background: set `--c` per context; rule `.mh { background: var(--c, rgba(255,92,138,.5)) }`.

For floaters set --c like rgba(255,92,138,.16) directly in .f nth rules.

Burst mini hearts: --c set in nth rules (p4 etc.) plus --s .16 in `.burst .mh` rule.

Now compile the nth-of-type lists. Burst markup order — I'll write HTML with classes:

```html
<div class="burst" aria-hidden="true">
  <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
  <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
  <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
  <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
  <i class="c"></i><i class="t"></i>
</div>
```
nth-of-type within .burst counts `i` elements: 1..18. ✓

CSS:

```css
.burst i:nth-of-type(1){--tx:150px;--ty:0px;--c:#ff2d6f}
.burst i:nth-of-type(2){--tx:169px;--ty:62px;--rot:260deg;--c:#ffc24b}
.burst i:nth-of-type(3){--tx:103px;--ty:87px;--rot:180deg;--c:#fff}
.burst i:nth-of-type(4){--tx:82px;--ty:143px;--rot:120deg;--c:#ff2d6f;--dl:.03s}
.burst i:nth-of-type(5){--tx:25px;--ty:143px;--c:#ffc24b}
.burst i:nth-of-type(6){--tx:-30px;--ty:172px;--rot:-300deg;--c:#ff2d6f}
.burst i:nth-of-type(7){--tx:-24px;--ty:138px;--rot:-160deg;--c:#ff5c8a}
.burst i:nth-of-type(8){--tx:-153px;--ty:54px;--rot:-140deg;--c:#ff5c8a;--dl:.05s}
.burst i:nth-of-type(9){--tx:-141px;--ty:0px;--c:#fff}
.burst i:nth-of-type(10){--tx:-127px;--ty:-46px;--rot:340deg;--c:#7c5cff}
.burst i:nth-of-type(11){--tx:-132px;--ty:-109px;--rot:200deg;--c:#ffc24b}
.burst i:nth-of-type(12){--tx:-72px;--ty:-126px;--rot:160deg;--c:#ffc24b;--dl:.04s}
.burst i:nth-of-type(13){--tx:-28px;--ty:-158px;--c:#ff2d6f}
.burst i:nth-of-type(14){--tx:24px;--ty:-138px;--rot:-260deg;--c:#fff}
.burst i:nth-of-type(15){--tx:30px;--ty:-172px;--rot:-200deg;--c:#ffc24b}
.burst i:nth-of-type(16){--tx:75px;--ty:-130px;--rot:-120deg;--c:#c81d5e;--dl:.06s}
.burst i:nth-of-type(17){--tx:126px;--ty:-106px;--c:#7c5cff}
.burst i:nth-of-type(18){--tx:136px;--ty:-49px;--rot:300deg;--c:#ff5c8a}
```

Base burst styles:
```css
.burst { position:absolute; inset:0; pointer-events:none; z-index:6 }
.burst i { position:absolute; left:50%; top:50%; opacity:0; transform: translate(-50%,-50%) scale(0); }
.burst .c { width:11px;height:11px;border-radius:50%;background:var(--c,#ff2d6f) }
.burst .t { width:6px;height:18px;border-radius:3px;background:var(--c,#ffc24b) }
.burst .s { width:16px;height:16px;background:var(--c,#fff);clip-path:polygon(50% 0,61% 39%,100% 50%,61% 61%,50% 100%,39% 61%,0 50%,39% 39%) }
.burst .mh { --s:.16 }
```
sparkle polygon: 50% 0 → 61% 39% → 100% 50% → 61% 61% → 50% 100% → 39% 61% → 0 50% → 39% 39%. ✓ 4-point star.

checked: `#like:checked ~ .scene .burst i { animation: fly .95s cubic-bezier(.16,.64,.38,1) var(--dl,0s) forwards; }`

Emo:
```css
.emo { position:absolute; inset:0; pointer-events:none; z-index:7 }
.emo span { position:absolute; left:50%; top:50%; font-size:30px; line-height:1; opacity:0; transform: translate(-50%,-50%) scale(0); }
.emo span:nth-child(1){--tx:-120px;--ty:-105px;--dl:.02s}
(2)✨: 115px,-115px,.07s
(3)💖: 150px,10px,.12s
(4)🥳: -150px,25px,.17s
(5)💯: -70px,-140px,.22s
(6)🌟: 70px,120px,.27s
```
checked: animation ringpop 1s cubic-bezier(.2,.75,.3,1) var(--dl,0s) forwards.

Rings:
```css
.rings { position:absolute; inset:0; pointer-events:none; z-index:4 }
.rings i { position:absolute; left:50%; top:50%; width:150px; height:150px; margin:-75px 0 0 -75px; border-radius:50%; border:3px solid; opacity:0; transform: scale(.5); }
.rings i:nth-child(1){ border-color:#ff2d6f; animation: ringout .7s cubic-bezier(.2,.7,.3,1) forwards }
```
— wait animations only on checked; base opacity 0. Put animation assignment in checked block with nth-child delay:
```css
#like:checked ~ .scene .rings i { animation: ringout .8s cubic-bezier(.17,.67,.3,1) forwards; }
#like:checked ~ .scene .rings i:nth-child(2){ animation-delay:.08s; border-color:#ffc24b... }
```
Hmm border-color per nth set in base rules (border colors static): nth-child(1) #ff2d6f, (2) #ffc24b, (3) rgba(255,255,255,.85). delays in checked block.

Durations: nth1 .75s, nth2 .85s .08, nth3 .95s .16 — per-child animation shorthand overrides: 
```css
#like:checked ~ .scene .rings i:nth-child(1){ animation: ringout .75s ease-out 0s forwards }
#like:checked ~ .scene .rings i:nth-child(2){ animation: ringout .85s ease-out .08s forwards }
#like:checked ~ .scene .rings i:nth-child(3){ animation: ringout .95s ease-out .16s forwards }
```
Fine.

Rays: `.rays { position:absolute; left:50%; top:50%; width:320px; height:320px; margin:-160px 0 0 -160px; border-radius:50%; background: repeating-conic-gradient(rgba(255,255,255,.85) 0deg 5deg, rgba(255,255,255,0) 5deg 16deg); -webkit-mask: radial-gradient(closest-side, #000 24%, transparent 72%); mask: radial-gradient(closest-side, #000 24%, transparent 72%); opacity:0; transform: scale(.2); z-index:3; pointer-events:none }`
checked: animation rayburst .7s ease-out forwards.

Hmm rays white might be harsh — tint pink: rgba(255,214,230,.9). Use rgba(255,190,215,.9).

Boom: `.boom { position:absolute; left:50%; top:50%; width:560px; height:560px; margin:-280px 0 0 -280px; border-radius:50%; background: radial-gradient(circle closest-side, rgba(255,77,140,.55), rgba(255,77,140,.16) 46%, rgba(255,77,140,0) 72%); opacity:0; transform:scale(.45); z-index:2; pointer-events:none }`
checked: boomout .9s ease-out forwards.

Wait z-index: boom behind circle: circle z 5? Let me order: boom z1, rays z2, rings z3, circle z4, hearts inside circle (children), burst z6, emo z7, plusone z8. Circle must be above boom/rays/rings. Heart stack inside circle (position absolute within? hpos inside circle element? circle is grid place-items center; hpos is child → centered. circle overflow visible so hearts can pop slightly beyond? hearts within 150 circle fine.

Actually hpos absolute? If circle is grid with place-items:center and hpos is a grid item with width 100 height 90 → centered. good, no absolute needed. But .core wraps circle... circle inset 0 absolute. Then hpos in circle grid centered. ✓

pulse ring ::after inset -1? circle relative; ::after absolute inset: -8px? ring outside circle edge: inset:-10px border-radius 50%. animation ping 2.8s infinite. base opacity handled by keyframes (starts .5 → 0). Element also needs `pointer-events:none`.

Checked: `#like:checked ~ .scene .circle::after { animation: none; opacity: 0 }` — animation none stops; opacity 0 hides residue. transition opacity .3s? keyframes had control; on animation none, computed opacity from rule: set opacity:0 explicit. ✓

Also hover circle: `#like:not(:checked) ~ .scene .card:hover .circle { box-shadow: inset 0 0 0 1px rgba(255,255,255,.12), 0 14px 40px -18px rgba(0,0,0,.8) }` plus outline heart brighten. Card hover translate? skip.

Circle base: `background:#241c3f; box-shadow: inset 0 0 0 1px rgba(255,255,255,.055); transition: transform .18s ease, box-shadow .55s ease;`

Checked circle: `box-shadow: inset 0 0 0 1px rgba(255,92,138,.35), 0 0 44px rgba(255,45,111,.5), 0 18px 60px -18px rgba(255,45,111,.55);`

Now heart components:

```css
.hpos { position:relative; width:100px; height:90px; filter: drop-shadow(0 10px 24px rgba(255,45,111,0)) drop-shadow(0 0 60px rgba(255,45,111,0)); transition: filter .5s ease; }
#like:checked ~ .scene .hpos { filter: drop-shadow(0 12px 28px rgba(255,45,111,.55)) drop-shadow(0 0 64px rgba(255,45,111,.4)); }
.heart-wrap { position:absolute; inset:0; animation: heartbeat 3s ease-in-out infinite; transform-origin: 50% 60%; }
#like:checked ~ .scene .heart-wrap { animation: pop .85s cubic-bezier(.26,1.5,.42,1) both, heartbeat 3s ease-in-out 1.3s infinite; }
.heart { position:absolute; inset:0; clip-path: var(--heart); }
.h-outline { background:#716a92; transition: background .25s ease, opacity .2s ease; }
.card:hover .h-outline { background:#c9c0e8; }
.h-cut { background:#241c3f; transform: scale(.88); transition: opacity .2s ease; }
.h-fill { background: radial-gradient(60% 60% at 32% 26%, rgba(255,255,255,.38), rgba(255,255,255,0) 62%), linear-gradient(160deg, #ff7eb3 0%, #ff2d55 55%, #c9184a 100%); transform: scale(0); transform-origin: 50% 82%; transition: transform .55s cubic-bezier(.3,1.85,.45,1); }
#like:checked ~ .scene .h-fill { transform: scale(1); }
.h-shine { background: linear-gradient(100deg, rgba(255,255,255,0) 40%, rgba(255,255,255,.95) 50%, rgba(255,255,255,0) 60%); background-size: 300% 100%; background-position: 0% 0; opacity: 0; }
#like:checked ~ .scene .h-shine { animation: sweep .8s ease-out .12s forwards; }
#like:checked ~ .scene .h-outline, #like:checked ~ .scene .h-cut { opacity: 0; }
```

Shine sweep direction check: sweep keyframes bg-pos 0%→100% with size 300%: visible band sweep left→right ✓ (computed earlier p∈[.25,.75]).

Note: `.heart-wrap` transform-origin 50% 60%.

Wait issue: heartbeat runs always (infinite) even before any interaction — heart pulsing idle ✓.

pop keyframes end scale(1) rotate(0) — with `both` fill. Then heartbeat (delay 1.3s) takes over transform (later in list wins) — during 0.85s→1.3s, pop's fill holds scale(1). At 1.3s heartbeat starts at scale(1) (0% frame) — seamless ✓.

But: multiple animations where later one is in delay phase — does it apply? No (no fill) → pop's forwards fill applies. At heartbeat start it overrides. ✓ 

caption:

```css
.caption { display:flex; align-items:center; gap:9px; font-size:15px; margin-top:4px; }
.swap { display:grid; overflow:hidden; }
.swap > span { grid-area: 1/1; display:block; line-height:1.35; white-space:nowrap; transition: transform .45s cubic-bezier(.22,.9,.32,1.12), opacity .3s ease; }
.swap .b { transform: translateY(112%); opacity: 0; }
#like:checked ~ .scene .swap .a { transform: translateY(-112%); opacity: 0; }
#like:checked ~ .scene .swap .b { transform: translateY(0); opacity: 1; }
```
Colors: `.word .a { color:#bdb3dc; font-weight:600 } .word .b { color:#ff5c8a; font-weight:700 }` count spans color #9a91ba, checked b color #ffc24b? count "1,025" color #ffc7dd. Let's: count .a #8f86ad, .b #ffc24b. tabular-nums on caption.

Hint:
```css
.hint { display:grid; text-align:center; font-size:13px; color:#837aa4; min-height: 1.4em; margin-top: 2px }
.hint > span { grid-area:1/1; transition: opacity .35s ease, transform .35s ease; }
.hint .b { opacity: 0; transform: translateY(8px); }
#like:checked ~ .scene .hint .a { opacity: 0; transform: translateY(-8px); }
#like:checked ~ .scene .hint .b { opacity: 1; transform: translateY(0); }
```
Overflow hidden not needed for crossfade.

Plusone:
```css
.plusone { position:absolute; left:50%; top:-2px; font-size:19px; font-weight:800; color:#ffc24b; text-shadow: 0 2px 12px rgba(255,194,75,.5); opacity:0; transform: translate(-50%, 12px) scale(.5); z-index:8; pointer-events:none; }
#like:checked ~ .scene .plusone { animation: plusrise .95s ease-out .1s forwards; }
```
plusrise 0% opacity 0 — keyframes define both opacity & transform; base opacity 0 fine.

Position: top -2px relative to core → above circle top; rises -62px. ✓

Now rain CSS:

```css
.rain { position:fixed; inset:0; overflow:hidden; pointer-events:none; z-index:80; }
.drop { position:absolute; top:-8%; left:var(--x); opacity:0; transform: translate(0,-4vh) rotate(0deg); }
.drop i { display:block; font-size:var(--fs,24px); line-height:1; font-style:normal; }
.drop.t i { width:9px; height:16px; border-radius:2px; background:var(--c,#ff2d6f); }
#like:checked ~ .rain .drop { animation: fall var(--dur,1.2s) cubic-bezier(.25,.46,.55,.95) var(--dl,0s) forwards; }
@keyframes fall {
  0% { transform: translate(0,-6vh) rotate(0deg); opacity: 1; }
  85% { opacity: 1; }
  100% { transform: translate(var(--sw,40px),104vh) rotate(var(--spin,360deg)); opacity: 0; }
}
```
I removed mid zig-zag? Add 50% frame: translate(calc(var(--sw)*-1), 48vh) rotate(calc(var(--spin)/2)) — then 100% translate(var(--sw)...): zig-zag left then right. ✓ opacity at 50% keep 1 (default from frames? unspecified opacity in 50% frame interpolates 1→1 fine since 0% and 85% both 1).

Drop nth rules with vars as listed. 12 drops.

Floaters:

```css
.floaters { position:absolute; inset:0; }
.f { position:absolute; bottom:-70px; left:var(--x); opacity:0; animation: rise var(--t,15s) linear var(--dl,0s) infinite; }
.f .mh { transform: scale(var(--sc,.14)); background: var(--c, rgba(255,92,138,.16)); }
@keyframes rise {
  0% { transform: translate(0,0) rotate(0deg); opacity:0 }
  8% { opacity: var(--o,.5) }
  25% { transform: translate(26px,-27vh) rotate(10deg) }
  50% { transform: translate(-20px,-54vh) rotate(-9deg) }
  75% { transform: translate(24px,-81vh) rotate(8deg) }
  88% { opacity: var(--o,.5) }
  100% { transform: translate(-12px,-108vh) rotate(-7deg); opacity:0 }
}
```
Wait .f .mh transform scale — but rise animates .f. ✓ mh inside .f is 100×90 box; .f has no width — inline? .f display:block; child absolute? .mh position absolute? .mh in floaters: keep static (block) — .f auto height 90? inline-block. Set .f { display:block } .mh display block. box 100×90 — the heart drawn at top-left of .f box; visual center offset — since hearts drift anywhere, fine. But rotation origin .f box corner — rotate(10deg) around top-left of 100px box → wobbly orbit-ish — acceptable natural drift.

Also z: floaters inside .bg behind content — but also they're large boxes (100px) with tiny visual — clicks? .bg pointer-events none. set.

Blobs:

```css
.bg { position:fixed; inset:0; overflow:hidden; z-index:0; pointer-events:none; background: radial-gradient(900px 520px at 78% -8%, #1c1544 0%, rgba(28,21,68,0) 60%), radial-gradient(800px 600px at 12% 108%, #161033 0%, rgba(22,16,51,0) 55%), #0d0a1e; }
.blob { position:absolute; border-radius:50%; filter: blur(80px); }
.b1 { width:44vw; height:44vw; min-width:340px; min-height:340px; background:#ff2d6f; opacity:.32; top:-12%; left:-10%; animation: blobdrift 19s ease-in-out -4s infinite alternate; }
.b2 { width:38vw; height:38vw; min-width:300px; min-height:300px; background:#5a45ff; opacity:.3; top:16%; right:-12%; animation: blobdrift 23s ease-in-out -11s infinite alternate-reverse; }
.b3 { width:40vw; height:40vw; min-width:320px; min-height:320px; background:#ff8a3d; opacity:.18; bottom:-16%; left:34%; animation: blobdrift 27s ease-in-out -18s infinite alternate; }
@keyframes blobdrift { from { transform: translate(0,0) scale(1) } to { transform: translate(60px,-42px) scale(1.18) } }
```
alternate-reverse for variety.

Scene:

```css
.scene { position:relative; z-index:1; min-height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:26px; padding:44px 18px 76px; }
```
Wait .bg inside .scene before content — .bg is fixed; as flex child it participates? position:fixed removes from flow ✓.

But .bg z-index 0 vs scene content: scene children need z-index/position: give .head,.card,.hint position:relative z-index 1... .foot absolute z 1. Actually .scene itself has z-index 1 stacking above .bg (sibling? no, .bg is child). Children of scene: .bg (fixed, z 0) then .head etc. static — static elements paint above positioned z0? Positioned z-index:0 vs later static content: static content paints... in same stacking context, positioned elements with z-index:0 paint ABOVE non-positioned block backgrounds but below... painting order: block backgrounds → floats → inline → positioned z≥0? Positioned descendants with z-index 0 paint in step 8, after normal-flow content (step 4-7)? Actually positioned elements paint above in-flow content unless negative z. So .bg z-index:0 would paint above .head text? No — z-index:0 positioned paints in "stacking level 0" which is AFTER normal flow content. So blobs would cover text! Fix: give .bg z-index:-1 (paints below everything in scene) — but scene has background? scene transparent → .bg z -1 goes behind scene bg (transparent) → visible. But scene creates stacking context? scene has animation shake → transforms create stacking context! Then z -1 child stays within scene, painting below other scene content but above scene background (transparent) ✓. But before check (no animation applied), does scene still create stacking context? Only during animation... after animation ends with fill both? I set shake `both` → transform persists → stacking context persists. Before first click: no transform → scene not stacking context → .bg z:-1 goes behind body background? body background is... body bg color #0d0a1e set on body — then .bg behind it = invisible!! Danger. Fix: don't rely on negative z. Instead: make .bg position:fixed with z-index:0, and give content wrappers position:relative + z-index:1. Set .head, .card(label), .hint, .foot { position:relative; z-index:1 }. Then content above bg. ✓ Simple and safe.

Alternatively put .bg as sibling of scene... then selector `#like:checked ~ .bg` works too, and scene shake won't move bg (hmm I wanted bg to shake... fine, shake scene only — content shakes; bg static — actually looks better: content rattles over calm bg? Meh either way). Keep .bg inside scene with z0 + content z1. Rain outside scene z80 fixed. ✓

During shake, .bg fixed→ contained by transformed scene — it'll shake too (as scene's descendant... wait .bg is child of scene; scene transform animates → bg (fixed) becomes fixed-to-scene → bg shakes WITH scene (moves identical) — net effect: bg visually moves with content — shake applies to everything including bg ✓ (whole world shakes). Good.

.foot: `position:fixed`?? — if inside scene with transform, fixed becomes relative to scene → bottom 14px of scene (scene min-height 100vh) ≈ viewport bottom ✓, and shakes with scene ✓. Set .foot { position:absolute; bottom:16px; left:0; right:0; text-align:center; z-index:1; padding:0 14px; } — absolute relative to scene (scene position:relative ✓).

head:

```css
.head { text-align:center; max-width:640px; }
.overline { font-size:11px; font-weight:700; letter-spacing:.34em; text-transform:uppercase; color:#ff5c8a; margin:0 0 14px; }
h1 { margin:0 0 14px; font-size:clamp(2.2rem, 6vw, 3.7rem); font-weight:800; letter-spacing:-.035em; color:#f4efff; line-height:1.05; }
h1 em { font-style:normal; background:linear-gradient(92deg,#ff5c8a 10%,#ff9a3d 55%,#ffc24b 90%); -webkit-background-clip:text; background-clip:text; color:transparent; -webkit-text-fill-color:transparent; }
.sub { margin:0 auto; font-size:15px; line-height:1.65; color:#9a90bb; max-width:52ch; }
```

card:

```css
.card { position:relative; z-index:1; display:flex; flex-direction:column; align-items:center; gap:18px; padding:44px 58px 36px; border-radius:32px; background:#191231; border:1px solid rgba(255,255,255,.07); box-shadow: 0 40px 90px -30px rgba(0,0,0,.75), 0 2px 0 rgba(255,255,255,.03) inset; cursor:pointer; user-select:none; -webkit-user-select:none; -webkit-tap-highlight-color:transparent; transition: transform .5s cubic-bezier(.22,1.2,.36,1), border-color .5s ease; }
#like:checked ~ .scene .card { transform: translateY(-6px); border-color: rgba(255,92,138,.4); box-shadow: 0 40px 90px -30px rgba(0,0,0,.75), 0 0 70px -18px rgba(255,45,111,.45); }
```
Hmm box-shadow transition ok.

focus-visible: `#like:focus-visible ~ .scene .card { outline:3px solid #ff5c8a; outline-offset:4px }` — outline on card nicer than circle.

core/circle:

```css
.core { position:relative; width:150px; height:150px; }
.circle { position:absolute; inset:0; border-radius:50%; background:#241c3f; box-shadow: inset 0 0 0 1px rgba(255,255,255,.06); display:grid; place-items:center; transition: transform .18s ease, box-shadow .55s ease; z-index:4; }
.card:active .circle { transform: scale(.93); }
.circle::after { content:""; position:absolute; inset:-10px; border-radius:50%; border:2px solid rgba(255,255,255,.3); animation: ping 2.8s cubic-bezier(.2,.6,.35,1) infinite; pointer-events:none; }
```
Hmm ping opacity in keyframes from .55 — but base element opacity default 1; keyframes control always (0% .55 → 100% 0) fine.

checked circle box-shadow glow.

Also checked ping none:
`#like:checked ~ .scene .circle::after { animation: none; opacity: 0; }` — with animation none, opacity from base rule → set in that rule ✓.

Also hover circle glow slight when unchecked:
`#like:not(:checked) ~ .scene .card:hover .circle { box-shadow: inset 0 0 0 1px rgba(255,255,255,.14), 0 18px 44px -20px rgba(0,0,0,.85); }`

caption + hint + foot + rain as above.

foot content: `<footer class="foot">0 &lt;script&gt; tags · 1 checkbox · <code>:checked</code> + <code>@keyframes</code> = all of this</footer>`

Hmm ampersand escapes fine.

hint texts:
a: "psst — the heart wants attention. click it ↑"
b: "ok wow. click again to un-like (or don't) ↓"

Wait arrow direction: heart above hint... hint below card so heart is ↑ from hint ✓.

Responsive media (max-width:520px):
- .scene gap 18px; padding 30px 12px 64px
- .card padding 32px 20px 26px; border-radius 26px
- .sub font 14px
- .foot font 11px
- .emo span font-size 26px
- h1 fine via clamp

Also max-height media? skip.

Reduced motion block at end.

Also global `* { box-sizing: border-box }`, `body { margin:0; font-family...; background:#0d0a1e; color:#efeaff; overflow-x:hidden; min-height:100vh }`. Note: with scene min-height 100vh, body fine. Also `html,body { height:100% }`? not needed.

::selection { background:#ff2d6f; color:#fff }.

Let me double check the `--heart` custom property: defined at :root as `--heart: path("...")`. clip-path: var(--heart) — path() function inside var — allowed (custom property substitution into clip-path value). ✓ Chrome fine.

Heart path check again for validity: 
`M50 86C26 66 4 48 4 26.5C4 13 15 3 28 3C37.6 3 45.6 8.4 50 17.5C54.4 8.4 62.4 3 72 3C85 3 96 13 96 26.5C96 48 74 66 50 86Z`
Commands: M(50,86); C1 (26,66)(4,48)(4,26.5); C2 (4,13)(15,3)(28,3); C3 (37.6,3)(45.6,8.4)(50,17.5); C4 (54.4,8.4)(62.4,3)(72,3); C5 (85,3)(96,13)(96,26.5); C6 (96,48)(74,66)(50,86); Z. Valid. Shape sanity: left side from tip (50,86) to (4,26.5) via ctrl (26,66),(4,48): smooth. Top-left corner arc (4,26.5)→(28,3): ctrl (4,13),(15,3): rounded. notch (28,3)→(50,17.5): ctrl (37.6,3),(45.6,8.4): dips down to center point y17.5. Mirror right. Then right side (96,26.5)→(50,86) via (96,48),(74,66). Heart plausible ✓. Width 92 (4..96), height 83 (3..86) within 100×90 ✓ bottom tip near 86 with 4px space — bottom of heart slightly above element bottom; fine.

The cut heart scale .88 around center (50,45): band ~ (100−88)/2=6px sides, (90−79.2)/2≈5.4px top/bottom ✓.

Circle bg #241c3f matches h-cut ✓.

Now check contrast of outline heart #716a92 on #241c3f — visible subtle ✓, hover #c9c0e8 ✓.

One risk: `.card:active .circle { transform: scale(.93) }` — but circle also has `z-index:4` etc fine.

Another: h-shine is above h-fill — but also above? order in DOM: outline, cut, fill, shine — all absolute inset 0, equal z → DOM order paints later above ✓.

During uncheck, shine resets to opacity 0 base ✓.

plusrise & sweep & ringpop & fly & fall & boomout & rayburst & ringout all `forwards` — after end remain at 100% (opacity 0) — invisible ✓. On uncheck, animations removed → base (hidden) ✓.

shake `both` — ends identity ✓.

capbounce: `#like:checked ~ .scene .caption { animation: capbounce .6s ease-out }` ✓ (caption is child of card label — transform on caption doesn't break layout).

hueflash on .bg 1s ✓.

Count: is "1,024" ok with nowrap ✓.

Edge case — burst `.mh` base background: `var(--c, #ff2d6f)` where --c set in nth rules ✓. But `.burst i` base sets background for .c/.t via their class rules; .s sets clip; all good.

Also `.burst .s` clip-path polygon — using default --c #fff.

Emoji font-size 30px via `.emo span`.

Also add slight rotate to card hover? no.

Now — total HTML. Let me also add `aria-hidden="true"` on decorative layers ✓.

Write out final code carefully. Watch: within <style>, no issues. Comments allowed.

One more check on `sweep` background-position percentages: background-size:300% 100%; animating background-position 0%→100%: at 0%: offset = (300-100)*(0/100)=0 → visible image [0,100] of 300 → gradient position: gradient across 300-wide image: transparent 40% (0..120), white at 50% (150), so visible [0,100] all transparent ✓. At 100%: offset=200 → visible [200,300]: transparent (white at 150 < 200) ✓. Mid p=50%: offset 100 → visible [100,200] contains 150 white band ✓ sweep passes. 

Also the h-shine gradient angle 100deg — diagonal band, ok with horizontal position sweep (band sweeps horizontally-ish).

Fall keyframes: 0% translate(0,-6vh) — drop top:-8% + translate -6vh → starts above viewport ✓. 100% 104vh ✓.

Rain drops left var(--x) — percent of .rain width ✓.

Also give drops slight opacity variance? fine.

Now assemble everything. Also double-check that nothing references external resources ✓ no fonts ✓.

Also title: <title>A like button in pure CSS</title>.

Final check of prompt rules: 
- One code block html ✓
- no JS ✓ (script absence fine — "JavaScript in <script>" is where it would go; we have none)
- meaningful first paint ✓
- 1280×800 & 375 ✓
- no localStorage/alert ✓
- no external ✓

Sizes at 1280×800: content column centered; head ~150px + card ~330 + hint 20 + gaps → ~560 + padding 120 = 680 < 800 ✓.

Let me write the whole file now, carefully, keeping CSS organized with comments. I'll be meticulous with braces.

Also — the `.f` floaters: `.f { display:block }` needed? span default inline — animation transform on inline doesn't apply! Inline elements can't be transformed. `.f` span must be display:block (or inline-block). Same for `.drop i` (display:block set ✓), `.emo span` (set display:block), `.burst i` (set display:block), `.rings i` block ✓ via position absolute (absolutized elements are blockified automatically ✓). Position:absolute blockifies, so .f (absolute) fine; but .f's child .mh inline `i` with transform scale — needs display:block. Add `.mh { display:block }` global. And .emo span absolute ✓ blockified. `.drop` absolute ✓. `.f .mh` is child of absolute .f — .mh itself must be display block ✓ via .mh rule.

Also `.heart` spans absolute ✓.

caption spans inside .swap — grid items blockified ✓.

Also `label.card` — flex container ✓.

Input `#like` styles.

Let me also think about whether `.card:active` triggers while clicking label — yes mousedown on label. ✓

Now, potential subtle issue: clicking the label triggers checkbox change on CLICK (mouseup) — effects start on release. Standard. The :active press scale gives feedback on mousedown ✓.

Alright, also let me reconsider `pop` bezier with rotate — keyframes with rotate might jitter; keep modest angles.

Another consideration: `#like:checked ~ .scene .heart-wrap { animation: pop .85s ..., heartbeat ... }` — overrides idle `animation: heartbeat...` shorthand ✓.

Also on uncheck, wrap returns to base animation heartbeat (restarts from 0 — jump to scale 1 — since pop ended at 1, fine).

Also `.h-fill` transition bezier (.3,1.85,.45,1): overshoot to ~1.2 then settle. On uncheck, same bezier shrink — bounce through 0? y>1 bezier from 1→0: intermediate values dip below 0 → scale negative → heart flips inside-out momentarily!! Negative scale flips heart — during shrink it might show mirrored heart briefly (clip same shape — mirrored heart looks same-ish? heart is symmetric horizontally, so mirrored looks identical!) — actually h-flip of symmetric heart = same shape; scale passes through 0 (invisible instant) then tiny negative (mirrored tiny heart, invisible-ish at ~2% size) then settles 0. Visually it's a quick shrink to nothing — acceptable, even cute "pop-out". But transform-origin bottom: negative scale from origin bottom — flips upward — like the heart collapsing into bottom point — fun! OK.

Hmm wait, but heart is symmetric about vertical center line ✓ so no visual glitch. 

Also `.h-cut` scale .88 static ✓.

Let me also double check `.swap` for the word: "Like"/"Liked" nowrap; container auto width = max ✓. Count similarly ✓.

Focus-visible: also `.card:focus-within`? input outside card — focus-within won't trigger (input is sibling). Use #like:focus-visible ~ .scene .card outline ✓.

Reduced-motion: 

```css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .15s !important; }
}
```
This makes floaters/blobs static (invisible? floaters opacity 0 base with rise 1 iteration .01ms → forwards? rise is infinite → iteration-count 1 → ends at 100% opacity 0 → hearts invisible — fine). Blob static visible ✓. Ping ends opacity 0 ✓. heartbeat stops at base ✓. Click effects instant — heart fill via transition .15s ✓ still works. Good enough.

Now, one important review: does the screenshot (3s) capture nicely? Yes: static title/card/pulse etc. ✓

Write final HTML. I'll be thorough but concise-ish in comments.

Also — set `html { scrollbar-hidden? }` no. overflow-x hidden on body + html.

Let me draft the complete file:

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Like it. Loudly. — a pure-CSS like button</title>
<style>
/* ============ base ============ */
* { box-sizing: border-box; margin: 0; }
html, body { overflow-x: hidden; }
html { color-scheme: dark; }
body {
  min-height: 100vh;
  background: #0d0a1e;
  color: #efeaff;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
::selection { background: #ff2d6f; color: #fff; }

/* the entire trick: one checkbox drives EVERYTHING */
#like {
  position: fixed; top: 0; left: 0;
  width: 1px; height: 1px; opacity: 0;
  pointer-events: none;
}

:root {
  --heart: path("M50 86C26 66 4 48 4 26.5C4 13 15 3 28 3C37.6 3 45.6 8.4 50 17.5C54.4 8.4 62.4 3 72 3C85 3 96 13 96 26.5C96 48 74 66 50 86Z");
}
```

etc. Then all sections. Let me write it fully now (careful, long).

Also note `* { margin: 0 }` resets headings/p — then set margins manually where wanted.

Scene bg gradients etc as planned.

Ordering in stylesheet: base → input → bg/floaters/blobs → head → card/core/circle/hearts → effects (boom rays rings burst emo plusone) → caption/hint/foot → checked-state rules (grouped for readability!) → rain → keyframes → media.

I'll group "checked" rules together to make the CSS readable and show intent.

Also caption element: `<span class="caption">` with `<span class="swap word">` etc. And classes on b spans.

Also, "count" swap: b color gold.

Write rain HTML:

```html
<div class="rain" aria-hidden="true">
  <span class="drop e"><i>🎉</i></span>
  <span class="drop t"><i></i></span>
  <span class="drop e"><i>✨</i></span>
  <span class="drop e"><i>💖</i></span>
  <span class="drop t"><i></i></span>
  <span class="drop e"><i>🥳</i></span>
  <span class="drop t"><i></i></span>
  <span class="drop e"><i>💯</i></span>
  <span class="drop e"><i>🌟</i></span>
  <span class="drop t"><i></i></span>
  <span class="drop e"><i>🎊</i></span>
  <span class="drop e"><i>💘</i></span>
</div>
```
nth-of-type within .rain counts all spans .drop — nth-of-type on span matches span type regardless of class ✓ so d1..d12 nth-of-type rules. Colors for .t via --c in those rules.

drop rules:
```css
.rain .drop:nth-of-type(1){--x:6%;--fs:26px;--dur:1.3s;--dl:.02s;--sw:44px;--spin:340deg}
.rain .drop:nth-of-type(2){--x:14%;--c:#ff2d6f;--dur:1.15s;--dl:.12s;--sw:-52px;--spin:-420deg}
.rain .drop:nth-of-type(3){--x:24%;--fs:20px;--dur:1.45s;--dl:.05s;--sw:60px;--spin:520deg}
.rain .drop:nth-of-type(4){--x:33%;--fs:24px;--dur:1.2s;--dl:.18s;--sw:-42px;--spin:-300deg}
.rain .drop:nth-of-type(5){--x:44%;--c:#ffc24b;--dur:1.05s;--dl:.08s;--sw:56px;--spin:460deg}
.rain .drop:nth-of-type(6){--x:52%;--fs:28px;--dur:1.35s;--dl:0s;--sw:-60px;--spin:-380deg}
.rain .drop:nth-of-type(7){--x:61%;--c:#7c5cff;--dur:1.15s;--dl:.22s;--sw:46px;--spin:400deg}
.rain .drop:nth-of-type(8){--x:70%;--fs:22px;--dur:1.25s;--dl:.1s;--sw:-56px;--spin:-500deg}
.rain .drop:nth-of-type(9){--x:78%;--fs:26px;--dur:1.1s;--dl:.16s;--sw:50px;--spin:340deg}
.rain .drop:nth-of-type(10){--x:86%;--c:#fff;--dur:1.3s;--dl:.06s;--sw:-46px;--spin:-460deg}
.rain .drop:nth-of-type(11){--x:93%;--fs:24px;--dur:1.2s;--dl:.13s;--sw:62px;--spin:380deg}
.rain .drop:nth-of-type(12){--x:40%;--fs:18px;--dur:1.5s;--dl:.2s;--sw:-70px;--spin:-350deg}
```

Fall keyframe with zig-zag:
```css
@keyframes fall {
  0% { transform: translate(0, -6vh) rotate(0deg); opacity: 1; }
  50% { transform: translate(calc(var(--sw, 40px) * -1), 46vh) rotate(calc(var(--spin, 360deg) / 2)); }
  85% { opacity: 1; }
  100% { transform: translate(var(--sw, 40px), 104vh) rotate(var(--spin, 360deg)); opacity: 0; }
}
```
Wait 50% frame has no opacity → interpolated between 0% (1) and 85% (1) → stays 1 ✓.

Burst fly duration uniform .95s; but far particles (172px) at .95s fine.

Emoji `.emo span` base transform translate(-50%,-50%) scale(0) ✓.

Also `.plusone` uses translate(-50%, ...) ✓.

Let me also give `.core` children z-index: boom z1, rays z2, rings z3, circle z4, burst z6, emo z7, plusone z8 — set on each absolute layer. circle needs z to be above rays ✓ (circle z4 > rings z3 ✓; hearts inside circle ✓ above rings).

Hmm wait — rays behind circle: rays radius 160 scaled 1.2 → extends beyond circle; circle (opaque) covers center part of rays — good comic look (rays radiate from behind button) ✓.

Now write checked-state grouped rules:

```css
/* ============ when :checked — the party ============ */
#like:checked ~ .scene { animation: shake .55s cubic-bezier(.36,.07,.19,.97) both; }
#like:checked ~ .scene .bg { animation: hueflash 1s ease-out; }
#like:checked ~ .scene .card { transform: translateY(-6px); border-color: rgba(255,92,138,.42); box-shadow: 0 40px 90px -30px rgba(0,0,0,.75), 0 0 80px -14px rgba(255,45,111,.5); }
#like:checked ~ .scene .circle { box-shadow: inset 0 0 0 1px rgba(255,92,138,.35), 0 0 46px rgba(255,45,111,.55), 0 18px 60px -18px rgba(255,45,111,.6); }
#like:checked ~ .scene .circle::after { animation: none; opacity: 0; }
#like:checked ~ .scene .h-outline, #like:checked ~ .scene .h-cut { opacity: 0; }
#like:checked ~ .scene .h-fill { transform: scale(1); }
#like:checked ~ .scene .h-shine { animation: sweep .8s ease-out .12s forwards; }
#like:checked ~ .scene .heart-wrap { animation: pop .85s cubic-bezier(.26,1.5,.42,1) both, heartbeat 3s ease-in-out 1.3s infinite; }
#like:checked ~ .scene .hpos { filter: drop-shadow(0 12px 28px rgba(255,45,111,.55)) drop-shadow(0 0 64px rgba(255,45,111,.42)); }
#like:checked ~ .scene .caption { animation: capbounce .6s ease-out; }
#like:checked ~ .scene .swap .a { transform: translateY(-112%); opacity: 0; }
#like:checked ~ .scene .swap .b { transform: translateY(0); opacity: 1; }
#like:checked ~ .scene .hint .a { opacity: 0; transform: translateY(-8px); }
#like:checked ~ .scene .hint .b { opacity: 1; transform: translateY(0); }
#like:checked ~ .scene .boom { animation: boomout .95s ease-out forwards; }
#like:checked ~ .scene .rays { animation: rayburst .75s ease-out forwards; }
#like:checked ~ .scene .rings i:nth-of-type(1) { animation: ringout .75s cubic-bezier(.17,.67,.35,1) forwards; }
#like:checked ~ .scene .rings i:nth-of-type(2) { animation: ringout .85s cubic-bezier(.17,.67,.35,1) .08s forwards; }
#like:checked ~ .scene .rings i:nth-of-type(3) { animation: ringout 1s cubic-bezier(.17,.67,.35,1) .17s forwards; }
#like:checked ~ .scene .burst i { animation: fly .95s cubic-bezier(.16,.64,.38,1) var(--dl, 0s) forwards; }
#like:checked ~ .scene .emo span { animation: ringpop 1s cubic-bezier(.2,.75,.35,1) var(--dl, 0s) forwards; }
#like:checked ~ .scene .plusone { animation: plusrise 1s ease-out .1s forwards; }
#like:checked ~ .rain .drop { animation: fall var(--dur, 1.2s) cubic-bezier(.3,.45,.6,1) var(--dl, 0s) forwards; }
```

Wait `.rings i` — i elements are `i` type; nth-of-type on i ✓ (they're the only i's in .rings).

Hmm `.burst i` base `--s` for minihearts `.burst .mh { --s:.16 }` and `.burst .c,.t,.s` default --s unset → var(--s,1) = 1 ✓.

pop bezier `.26,1.5` per-segment easing — keyframes default easing applies between frames — bouncy ✓.

Also, `.h-shine` background gradient angle: since heart width 100, band sweeps with bg-position % — ✓.

One more: heart idle `heartbeat` on wrap — while checked pop runs (0.85s) then idle until 1.3s then heartbeat resumes ✓.

Everything seems consistent. Also `.card` transition includes box-shadow ✓.

Also don't forget `.heart` has `clip-path: var(--heart)` — and :root custom property with path() — note: `var()` in clip-path referencing path() ✓.

Edge: In some browsers custom property with path() fails if re-parsed... Chrome fine.

Also add `.h-shine` `mix-blend-mode: screen`? not needed.

Also caption `font-variant-numeric: tabular-nums` on .count.

Also caption's swap b span colors:
`.word .b { color:#ff5c8a; font-weight:700 }`
`.count .a { color:#8f86ad } .count .b { color:#ffc24b; font-weight:700 }`
word .a `color:#bdb3dc; font-weight:650`? use 600.

sep: color #665e86.

Also caption margin-top small.

Foot code style: `.foot code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 10.5px; background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.06); padding: 1.5px 6px; border-radius: 6px; color: #cbbaff; }`

Head z-index: `.head { position:relative; z-index:1 }` ✓ same hint.

Floaters/BG z: `.bg { z-index:0 }` with position fixed ✓ and content z1 ✓. But .bg inside .scene which is `position:relative; z-index:1` — hmm scene z-index 1 relative → creates stacking context? z-index on positioned element creates stacking context only if not auto ✓ (z-index:1 + position relative) → yes scene is stacking context → .bg z0 inside, content z1 inside — bg behind content ✓ regardless of body. And shake transform also on scene fine. But WAIT: if scene is a stacking context and .bg is `position:fixed` inside it — fine, fixed positions to viewport (scene untransformed initially). After shake (fill both) transform persists → .bg becomes fixed relative to scene — scene is full width & min-height 100vh starting at top of body... body margin 0 → scene top = 0 → identical viewport coverage ✓. 

But subtle: scene min-height 100vh; if content taller than viewport (short screens), scene grows; .bg fixed relative to scene covers full scene ✓ fine.

Also .foot absolute bottom of scene — if scene taller than viewport, foot sits at scene bottom (below fold) — acceptable.

Rain z80 fixed to viewport, sibling of scene — body stacking: scene z1, rain z80 ✓ above.

Everything checks. Now also I realize: `.scene` justify-content center with gap; children: .bg (out of flow), .head, .card(label), .hint, .foot (absolute) → flow children head/card/hint centered ✓.

Input before scene ✓.

Also `#like:focus-visible ~ .scene .card { outline: 3px dashed rgba(255,92,138,.9); outline-offset: 5px; border-radius already; }` ✓.

Let me write HTML body:

```html
<body>
<input type="checkbox" id="like" aria-label="Like — set off the pure-CSS party">

<div class="scene">
  <div class="bg" aria-hidden="true">
    <span class="blob b1"></span>
    <span class="blob b2"></span>
    <span class="blob b3"></span>
    <div class="floaters">
      <span class="f"><i class="mh"></i></span> ×7 with nth rules
    </div>
  </div>

  <header class="head">
    <p class="overline">✦ 100% css · 0% javascript ✦</p>
    <h1>Like it. <em>Loudly.</em></h1>
    <p class="sub">One checkbox, one label, and an absolutely unreasonable number of <code>@keyframes</code>. Click the heart. Then click it again. It never gets old.</p>
  </header>

  <label class="card" for="like">
    <span class="core">
      <span class="boom"></span>
      <span class="rays"></span>
      <span class="rings"><i></i><i></i><i></i></span>
      <span class="burst">
        <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
        <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
        <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
        <i class="c"></i><i class="t"></i><i class="s"></i><i class="mh"></i>
        <i class="c"></i><i class="t"></i>
      </span>
      <span class="emo"><span>🎉</span><span>✨</span><span>💖</span><span>🥳</span><span>💯</span><span>🌟</span></span>
      <span class="plusone">+1</span>
      <span class="circle">
        <span class="hpos">
          <span class="heart-wrap">
            <span class="heart h-outline"></span>
            <span class="heart h-cut"></span>
            <span class="heart h-fill"></span>
            <span class="heart h-shine"></span>
          </span>
        </span>
      </span>
    </span>
    <span class="caption">
      <span class="swap word"><span class="a">Like</span><span class="b">Liked</span></span>
      <span class="sep">·</span>
      <span class="swap count"><span class="a">1,024</span><span class="b">1,025</span></span>
    </span>
  </label>

  <p class="hint"><span class="a">psst — the heart is clickable ↑</span><span class="b">ok wow. click again to un-like ↓</span></p>

  <footer class="foot">0 <code>&lt;script&gt;</code> tags · 1 checkbox · <code>:checked</code> + <code>@keyframes</code> did all of this</footer>
</div>

<div class="rain" aria-hidden="true">…</div>
</body>
```

Note: label contains nested spans only — valid (label content phrasing; span ok, div inside label? I used div.rain outside; floaters div inside .bg not label ✓; burst is span containing i's ✓; all good. `.core` span containing spans ✓.

Wait — I used `<div class="floaters">` inside `.bg` div ✓ fine.

But inside label I have `.core` as span — but `.burst` is span with i children ✓; `.emo` span > spans ✓; `.rings` span > i ✓. All phrasing ✓. Note `span` with position absolute fine.

Important: `.burst` base rule sets `.burst i` position absolute left 50% top 50% — these `i` elements are inline by default — absolutized ✓.

`.mh` display block needed for floaters `.f > i.mh` (not absolute): `.f` is absolute (blockified), child i.mh inline — transform on inline fails → add `.mh { display:block }` ✓.

Also `.f` needs width? .f absolute bottom left; child .mh block 100×90 → .f height auto 90 ✓.

For floaters the .mh transform: `.f .mh { transform: scale(var(--sc,.14)); background: var(--c, rgba(255,92,138,.16)); }` — but base `.burst i` rule sets transform translate(-50%,-50%) scale(0) — that's scoped `.burst i`, floaters unaffected ✓.

Also base `.mh` background var(--c,...) set in .mh rule — then floaters override --c? They set background directly via `.f .mh` — or set --c in .f nth rules. Cleaner: `.mh { background: var(--c, #ff2d6f) }` and floaters set `--c` on `.f` (inherits) ✓. Burst nth rules set --c on the i itself ✓. Floater colors: rgba values.

Floater rules:
```css
.f:nth-of-type(1){--x:8%;--t:15s;--dl:-2.5s;--sc:.16;--c:rgba(255,92,138,.17)}
.f:nth-of-type(2){--x:19%;--t:19s;--dl:-11s;--sc:.11;--c:rgba(255,194,75,.14)}
.f:nth-of-type(3){--x:33%;--t:12.5s;--dl:-5s;--sc:.2;--c:rgba(255,92,138,.13)}
.f:nth-of-type(4){--x:50%;--t:17s;--dl:-13s;--sc:.13;--c:rgba(150,120,255,.15)}
.f:nth-of-type(5){--x:66%;--t:14s;--dl:-8s;--sc:.18;--c:rgba(255,92,138,.1)}
.f:nth-of-type(6){--x:81%;--t:18s;--dl:-4s;--sc:.12;--c:rgba(255,194,75,.12)}
.f:nth-of-type(7){--x:92%;--t:13s;--dl:-9.5s;--sc:.15;--c:rgba(255,92,138,.15)}
```
nth-of-type on span within .floaters ✓ (spans only).

--o opacity var: set --o in these too? keyframes default .5; set --o per f? Use opacity in keyframes var(--o,.45). Add --o values ~ .8-.12? keyframes use `opacity: var(--o, .5)` — but the --c alpha already dims hearts; --o ~1? Let's set --o:.9 default in var. Actually since colors are faint, set opacity var default 1: keyframes `8% { opacity: var(--o, 1) }`. Fine.

Also: `.f` bottom:-70px start below; hearts rise full 108vh ✓.

Blobs min sizes for mobile (44vw of 375 = 165px — blur 80 huge relative; min-width keeps drama) ✓.

Wait blob blur(80px) + big — on mobile could be heavy but ok.

Font: h1 uses default system-ui bold 800 ✓.

Now compile keyframes: heartbeat, pop, sweep, ringout, rayburst, boomout, fly, ringpop, plusrise, capbounce, shake, hueflash, fall, rise, blobdrift, ping. 16 keyframes ✓.

Double-check `pop` — wrap transform-origin set where? `.heart-wrap { transform-origin: 50% 62% }` ✓.

Also — during pop, wrap scaling affects hpos drop-shadow (filter recomputes) fine.

Hmm — one thing: `.h-fill` transition .55s cubic-bezier(.3,1.85,.45,1) — bezier control y=1.85 >1 gives overshoot ✓ (max ~1.2ish). It's applied on both scale up and down ✓.

Also: after fill scale(1) (checked), heart-wrap pop animation also scales wrap — compound bounce ✓ juicy.

Now sweep on h-shine: base `opacity:0`; animation `forwards` from opacity 1... wait sweep 0% opacity 1 — jump from 0 to 1 at start (delay .12s) — slight pop of the whole shine layer? At 0% the band is off-screen left (bg-pos 0 → band at 150 of 300-range, visible [0,100]) — the whole h-shine is clipped to heart; its non-band area transparent → jumping opacity 0→1 only reveals transparent pixels — invisible ✓. Good.

Also check `.h-shine` has same clip (`.heart` class ✓).

Now: does the heart outline sit over circle edge? heart 100×90 in 150 circle: fits ✓.

Alright — also caption alignment: `.caption { display:inline-flex }` — it's a span inside label (flex column card). Set display flex ✓.

Potential text-selection: label user-select none ✓.

Let me also think about the `sep` span: `<span class="sep">·</span>` style color #665e86, and when checked maybe pink — static fine.

Media query small:

```css
@media (max-width: 540px) {
  .scene { gap: 20px; padding: 32px 12px 64px; }
  .card { padding: 34px 18px 28px; border-radius: 26px; }
  .sub { font-size: 13.5px; }
  .overline { letter-spacing: .26em; }
  .emo span { font-size: 24px; }
  .plusone { font-size: 16px; }
  .foot { font-size: 10.5px; }
}
```

Also ensure h1 not overflow at 375: "Like it. Loudly." at 2.2rem ~ 35px — width ~ 300px ✓.

Also the `.hint` margin-top negative? Card gap via scene gap 26 ✓.

Finally, the foot text with `<code>` inline.

Also — since label wraps and `.foot` is outside label ✓.

One more consideration: `#like` `position: fixed` might be clipped? no.

Let me also verify no horizontal scroll from .rain drops at left 93% + emoji width — .rain overflow hidden ✓. Blobs — .bg overflow hidden ✓. Burst particles translate up to 172px from center of card — card centered; on 375 screen, card center ~187; +172 → 359 ✓ inside. boom 560 wide centered on card → extends ±280 → beyond 375 viewport → .scene overflow visible → body overflow-x hidden clips (body overflow-x hidden with no scroll) ✓. Actually body overflow-x hidden: content overflowing horizontally is clipped — yes no scrollbar ✓.

Hmm wait — will the huge .boom (fixed inside scene... no, .boom is inside .core inside card inside scene — static positioning context: overflow of body clips only if body is the clipping box; overflowing content from nested elements eventually propagates to viewport/html which has overflow-x hidden ✓ clipped.

But careful: `html,body { overflow-x: hidden }` — if content vertical overflows, scroll-y remains ✓.

Edge: On desktop 1280, boom ±280 around card center — fine.

Now — is there anything about the shake moving scene that could cause horizontal scrollbar? transform doesn't affect overflow ✓.

I think we're set. Let me also add a subtle inner highlight to card top: `.card::before`? skip.

Actually one more polish: card small "PURE CSS" ribbon? skip — enough elements.

Let me now also double check `.swap` overflow hidden + translateY(-112%): spans height = line box; 112% of span height moves fully out ✓.

And grid stack: `.swap > span { grid-area: 1 / 1 }` both a & b stack ✓ container width = max("Like","Liked") ✓.

Also add `will-change`? skip, fine.

Final code assembly. Also ensure I don't accidentally use `filter` transitions on .bg conflicting with hueflash (bg has no base filter; animation adds — on uncheck resets ✓).

Also `.blob` blur + scene shake → composite ok.

Let me count .burst i nth-of-type — with 18 i's ✓.

One last check — `#like:checked ~ .scene .rings i:nth-of-type(2)` — `i` elements only; nth-of-type(2) is second i ✓.

Also base `.rings i { border-color }` per nth-child:
```css
.rings i:nth-of-type(1) { border-color: #ff2d6f; }
.rings i:nth-of-type(2) { border-color: #ffc24b; }
.rings i:nth-of-type(3) { border-color: rgba(255,255,255,.85); }
```

And base `.rings i { ... opacity: 0; border: 3px solid; }` — border shorthand then color per nth — order: define border first then colors ✓ (specificity same, later wins ✓).

Writing final file now. Also include a CSS comment header for flavor.

Check: emojis used: 🎉 ✨ 💖 🥳 💯 🌟 🎊 💘 — fine.

Also caption count comma "1,024" ✓ tabular nums so width same as "1,025" ✓.

Hmm — also think about the `hint` visible pre-click: good.

Also initial `+1` hidden ✓.

Write it.

Also for safety, `.heart-wrap` needs `will-change: transform`? optional, skip.

Potential bug: `.heart-wrap { position:absolute; inset:0 }` — inside `.hpos` (position: relative; width:100px; height:90px) ✓ wrap fills hpos ✓.

`.heart { position:absolute; inset:0 }` inside wrap — but heart needs width/height 100×90: inset 0 on 100×90 wrap ✓ clip-path path coords fit ✓.

hpos inside circle grid `place-items:center` — hpos is grid item ✓ centered.

Also `.circle { display:grid; place-items:center; }` ✓.

Final: write everything. Also `<meta name="color-scheme" content="dark">` not needed.

Also one more detail: when clicking rapidly (check→uncheck→check), all animations restart — chaos ✓ intended.

Also the ripple `ping` — pre-check invite ✓.

OK writing final answer now. Length ~350 lines CSS. Let me be careful with syntax.

One more: the `fly` keyframes uses `var(--s,1)` — for mini hearts --s .16 — but their base hidden transform translate(-50%,-50%) scale(0); animation 0% matches ✓.

`ringpop` uses calc(var(--tx) * .8) — need `calc(var(--tx)*.8)` ✓ valid.

In `fall` keyframes: `calc(var(--sw, 40px) * -1)` ✓ and `calc(var(--spin, 360deg) / 2)` ✓.

Emoji spans `--tx/--ty/--dl` in nth-child rules ✓.

Also `.emo span:nth-child(k)` — .emo's children are spans only ✓.

Done — write.

Actually, hmm, let me reconsider the `.f` heart rotation origin issue: .f box is 100px wide (heart drawn at 100×90 scale .14 → visual 14×12.6 at box top-left). rise keyframes rotate .f — rotates around box center (50,45) which is far from visual heart → heart appears to orbit slightly — with rotate ±10deg, offset arc radius ~50px?? Rotation about distant center moves the small heart noticeably sideways in an arc — could look weird (hearts swinging widely). Fix: rotate the inner .mh instead, not .f. Move rotate to `.f .mh { transform: scale(var(--sc)) rotate(var(--r, 8deg)) }` static rotate? For animation, rotate .f but make .f box shrink-wrapped to visual size? .f width = 100 * sc? Set .f { width: calc(100px * var(--sc)); height: calc(90px * var(--sc)); } and .mh transform-origin top-left with scale: `transform: scale(var(--sc)); transform-origin: 0 0;` → heart visual fits exactly .f box ✓ then rotating .f rotates around its own center ✓. Nice:

```css
.f { position:absolute; bottom:-70px; left:var(--x); width:calc(100px * var(--sc,.14)); height:calc(90px * var(--sc,.14)); opacity:0; animation: rise var(--t,15s) linear var(--dl,0s) infinite; }
.f .mh { transform: scale(var(--sc,.14)); transform-origin: 0 0; background: var(--c, rgba(255,92,138,.16)); }
```
Wait .mh box 100×90 overflows .f small box — visual clipped? No clipping (overflow visible) — visual heart scaled to .f size anchored top-left = .f box exactly ✓. left var(--x) percent of .bg width ✓.

Good.

Similarly burst mini-hearts rotate around their center? `.burst i` positioned left 50% top 50%, transform translate(-50%,-50')... rotation in `fly` 100% frame: `rotate(var(--rot))` after translate — rotation origin = element center (50,45 of 100×90 box) = visual heart center ✓ (since translate(-50%,-50%) centers box on point; rotate around box center ~ heart center) ✓ fine.

Emoji spans: single text node — box sized to text; rotate center ✓.

OK. Also floaters z within bg — fine.

NOW write. I'll produce the final single HTML file.

Also double-check `input` — `position: fixed; opacity: 0` — Chrome might not focus scroll — fine.

Also `#like` needs `appearance: none`? Not necessary (invisible via opacity 0) but checkbox may paint? opacity 0 hides ✓.

Also — iframe keyboard: after user clicks, keydown Space on focused checkbox toggles ✓ (checkbox is focused after click? Clicking label focuses... clicking a label doesn't focus the input. Tab would. Eh — the prompt's keyboard guidance is for game demos; here mouse click suffices. Focus-visible rule included for tab users.)

Let me write the final file.

Additional guard: `.mh` display block ✓.

Also `.blob` spans display block via absolute ✓.

Final CSS length is large but fine.

Quick re-verify pop overshoot bezier: `cubic-bezier(.26,1.5,.42,1)` used with keyframes — per-frame interpolation uses this easing between each keyframe pair → springy ✓.

Also capbounce on `.caption` (display flex) transform ✓.

Writing now — final answer with one code block.

Also make sure I define `.count { font-variant-numeric: tabular-nums; }` — .count is the swap span container.

Also `.word` container.

Also caption spans `.b` for word has bold; count b bold gold.

Also `.caption .sep`.

I'll write HTML/CSS now in final form.

Also footer text — hmm keep short: "zero <script> tags · one checkbox · :checked + @keyframes did all of this".

Let me write out. I'll be careful that every brace closes.

After writing, mentally lint: look for missing semicolons/typos in keyframes and selectors.

Also the `.rays` mask both prefixed and standard ✓.

`repeating-conic-gradient(rgba(255,190,215,.9) 0deg 5deg, rgba(255,190,215,0) 5deg 16deg)` ✓.

`.boom` gradient ✓.

Also let me reconsider whether to keep pointer-events: none on `.emo/.burst/.rings...` — they're inside label; pointer-events none means clicks pass to whatever below (card bg/circle — still inside label ✓). Keep.

The label card is the click region — cursor pointer across card ✓.

Final write-up:

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Like it. Loudly. — pure-CSS like button</title>
<style>
/* ============================================================
   A LIKE BUTTON, 100% CSS. No <script> on this page. At all.
   The entire trick: <input type="checkbox"> + :checked + far
   too many @keyframes.
   ============================================================ */

:root{
  --heart: path("M50 86C26 66 4 48 4 26.5C4 13 15 3 28 3C37.6 3 45.6 8.4 50 17.5C54.4 8.4 62.4 3 72 3C85 3 96 13 96 26.5C96 48 74 66 50 86Z");
  --pink:#ff2d6f; --pink-soft:#ff5c8a; --gold:#ffc24b; --violet:#7c5cff;
}

*{box-sizing:border-box;margin:0;padding:0}
html{color-scheme:dark;overflow-x:hidden}
body{
  min-height:100vh;overflow-x:hidden;
  background:#0d0a1e;color:#efeaff;
  font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  -webkit-font-smoothing:antialiased;
}
::selection{background:var(--pink);color:#fff}

/* the man behind the curtain */
#like{position:fixed;top:0;left:0;width:1px;height:1px;opacity:0;pointer-events:none}
```

continue... `padding:0` in universal — careful: that kills intended paddings? I set paddings explicitly where needed (scene, card, foot). ✓

Then scene etc.

I'll now produce the complete final file text. During writing, keep consistent.

For `.scene`:

```css
.scene{
  position:relative;z-index:1;min-height:100vh;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:26px;padding:44px 18px 80px;
}
```

.bg:

```css
.bg{
  position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;
  background:
    radial-gradient(900px 520px at 78% -10%, #1d1546 0%, rgba(29,21,70,0) 62%),
    radial-gradient(820px 620px at 10% 110%, #171040 0%, rgba(23,16,64,0) 58%),
    #0d0a1e;
}
.blob{position:absolute;border-radius:50%;filter:blur(80px)}
...
```

Then floaters, head, card, core, circle, hearts, effect layers, caption, hint, foot, checked block, rain, keyframes, media.

Also `.head{position:relative;z-index:1;text-align:center;max-width:660px;padding:0 6px}`.

Also `.hint{position:relative;z-index:1;...}` and `.foot{position:absolute;...;z-index:1}`.

Let me finalize foot: `position:absolute;bottom:16px;left:0;right:0;text-align:center;font-size:11.5px;color:#8f86ad;letter-spacing:.02em;padding:0 14px`.

OK writing final now. Also I want to sanity check the count of `i` tags in burst = 18 (4 rows of 4 + 2) ✓ matches nth rules 1–18.

Also in `.burst i:nth-of-type(4)` etc I set `--dl` — and `--s` from `.burst .mh` ✓ (nth rule for 4 also sets --tx etc; class .mh sets --s ✓; order irrelevant different props).

Let me make sure `.burst .c/.t/.s` shapes get `--s` default 1 via var fallback ✓.

For `.burst .s` sparkle clip polygon — 8 points ✓.

Also add `.burst .c` slight blur? no.

Also particles could have drop-shadow glow? skip perf.

Write final. Also mention in hint pre-click that it's clickable — done.

One more time about shake + `.scene { min-height:100vh; justify-content:center }` and foot absolute — fine.

Potential vertical overflow: body min-height 100vh, scene min-height 100vh + padding — content ~ head 170 + card 340 + hint 30 + gaps 52 + padding 124 ≈ 716 < 800 ✓. Mobile 375×667: head ~230 (sub wraps more) + card 340 + 30 + gaps + padding ≈ 730 > 667 → page scrolls vertically a bit — acceptable (overflow-y auto default). Foot absolute at scene bottom — appears after scroll ✓ ok.

Actually with justify-content:center and min-height, when content exceeds, it overflows both ways? Flex centering with overflow can clip top in some cases (centered flex with overflow: items overflow equally top/bottom but scroll anchoring... safe-mode: use `justify-content:center` with `margin:auto` on children? The known issue: centered flex content taller than container overflows top unreachable. To be safe: `justify-content:flex-start` + `margin:auto 0`? Standard fix: keep justify-content: center but add `.head { margin-top: auto }`... Simplest: use `justify-content: safe center` (supported Chrome 115+). Chrome latest ✓ supports `safe center`. Use `justify-content:safe center`. Fallback older: fine anyway. I'll write `justify-content:safe center;` — hmm if unsupported keyword invalidates declaration, fallback needed: declare `justify-content:center;justify-content:safe center;` ✓.

OK, write.

Also — during shake animation, transform on scene + `will-change`? fine without.

Also one more flourish: make the little ping ring also mirror as "hint arrow bounce"? skip.

Alright — final answer.

Also double check no `alert` etc ✓.

Also there is the "hint" element ordering inside scene: head, label.card, p.hint, footer.foot(absolute) ✓.

Also caption inside label after core ✓.

Final CSS checked-state selector for `.hint .b` etc ✓.

Also don't forget base `.hint .b{opacity:0;transform:translateY(8px)}` ✓.

Let me write everything now, no more second-guessing.

Actually one more thought about `.h-fill` transition overshoot with transform-origin 50% 82%: overshoot ~1.2 scale — top of heart pokes above? within circle fine ✓.

And `heartbeat` scale 1.12 while wrap inside circle 150 — heart 100×90*1.12=112×100 ✓ fits.

Also idle pulse ring `.circle::after` inset -10px → 170px ring scaled 1.24 → ~211 ✓.

Go.

Also — the `sweep` animation delay .12s and fill forwards — before delay starts, h-shine at base opacity 0 (no fill backwards) ✓ invisible during delay ✓.

Writing final file:

Also add subtle vignette overlay? bg gradient covers.

Also last: label cursor pointer ✓; `.card{cursor:pointer}`.

Also `#like:checked ~ .scene .card` transform — conflicts with `:active` scale on circle only (different elements) ✓.

Deliver.