Exploding like buttonOne-line
Qwen3.8 Max (0902)
by Qwenreasoning defaultClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 6 min 36 s
- Cost
- $0.118
- Output tokens
- 19,574
- Spent thinking
- 11,887 tokens
- Speed
- 49.7 tok/s
- Console errors
- 0
- First token after
- 2.4 s
- First visible text after
- 4 min 53 s
- Prompt tokens
- 411
- Code size
- 19.0 KB
- Finish reason
- stop
- Served by
- Alibaba
- Model id
qwen/qwen3.8-max-0902- Reasoning sent
model default- Max output
- 131,072 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>The Pure-CSS Like Machine — Specimen Nº 001</title>
<style>
:root{
--bg0:#071d26; --bg1:#0d3140;
--ink:#eef6f2; --mut:#7fa3ab; --line:#1d4552;
--red:#ff4d5a; --red-d:#c81e3c;
--yel:#ffcf3f; --mint:#3ee6b0; --sky:#54c6ff; --org:#ff8a3d;
--disp:'Avenir Next Condensed','Franklin Gothic Medium','Arial Narrow','Segoe UI',sans-serif;
--body:'Avenir Next','Segoe UI',system-ui,-apple-system,sans-serif;
--mono:ui-monospace,'SF Mono','Cascadia Code',Consolas,monospace;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
background:var(--bg0); color:var(--ink); font-family:var(--body);
overflow-x:hidden; -webkit-font-smoothing:antialiased;
}
::selection{background:var(--red);color:#fff}
/* visually hidden but focusable checkbox = the whole engine */
.vh{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.scene{
position:relative; min-height:100vh; min-height:100svh;
display:flex; flex-direction:column; overflow:hidden;
background:
radial-gradient(1100px 700px at 72% 38%, var(--bg1), transparent 70%),
var(--bg0);
}
/* ---------- ambient layers ---------- */
.halftone{
position:absolute; inset:0; pointer-events:none;
background-image:radial-gradient(circle, rgba(120,190,200,.13) 1px, transparent 1.6px);
background-size:20px 20px;
-webkit-mask-image:radial-gradient(120% 100% at 50% 40%, #000 40%, transparent 100%);
mask-image:radial-gradient(120% 100% at 50% 40%, #000 40%, transparent 100%);
}
.tint{
position:absolute; inset:0; pointer-events:none; opacity:0; transition:opacity .6s ease;
background:radial-gradient(640px 540px at 68% 46%, rgba(255,77,90,.16), transparent 70%);
}
#like:checked ~ .scene .tint{opacity:1}
.ambient{position:absolute; inset:0; pointer-events:none}
.ambient i{
position:absolute; bottom:-6vh; font-style:normal; color:var(--c,var(--mut));
animation:floatUp var(--dur,24s) linear infinite; animation-delay:var(--dl,0s);
will-change:transform,opacity;
}
@keyframes floatUp{
0%{transform:translateY(0) rotate(0deg); opacity:0}
10%{opacity:var(--o,.4)}
90%{opacity:var(--o,.4)}
100%{transform:translateY(-118vh) rotate(30deg); opacity:0}
}
/* ---------- top bar ---------- */
.top{
position:relative; z-index:3;
display:flex; justify-content:space-between; align-items:center; gap:12px;
padding:16px clamp(18px,4vw,44px);
border-bottom:1px dashed var(--line);
font-family:var(--mono); font-size:11px; letter-spacing:.2em; text-transform:uppercase;
color:var(--mut);
}
.top .sep{color:var(--yel); letter-spacing:0}
.top .hot{color:var(--red)}
/* ---------- main grid ---------- */
main{
position:relative; z-index:2; flex:1;
display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
align-items:center; gap:clamp(20px,4vw,60px);
width:100%; max-width:1200px; margin:0 auto;
padding:clamp(20px,4vh,44px) clamp(18px,4vw,44px) 56px;
}
/* ---------- copy column ---------- */
.eyebrow{
font-family:var(--mono); font-size:12px; letter-spacing:.32em; text-transform:uppercase;
color:var(--mint); margin-bottom:14px;
}
h1{
font-family:var(--disp); font-weight:900; text-transform:uppercase;
font-size:clamp(3.1rem,8.5vw,6.6rem); line-height:.9; letter-spacing:-.01em;
margin-bottom:20px;
}
h1 span{display:block}
h1 .l2{margin-left:.55em; color:var(--mut); -webkit-text-stroke:1.5px var(--ink); -webkit-text-fill-color:transparent}
h1 .l3{
color:var(--red); transform:rotate(-2deg); transform-origin:left bottom;
text-shadow:5px 5px 0 rgba(4,16,22,.6);
}
.lede{max-width:46ch; color:var(--mut); font-size:clamp(14px,1.3vw,16px); line-height:1.65; margin-bottom:26px}
.lede code{
font-family:var(--mono); font-size:.9em; color:var(--yel);
background:rgba(255,207,63,.09); border:1px solid rgba(255,207,63,.25);
padding:1px 6px; border-radius:5px;
}
.specs{list-style:none; max-width:460px; border-top:1px dashed var(--line)}
.specs li{
display:grid; grid-template-columns:130px 1fr; gap:12px; align-items:baseline;
padding:10px 6px; border-bottom:1px dashed var(--line);
transition:background .25s, padding-left .25s;
}
.specs li:hover{background:rgba(255,255,255,.03); padding-left:12px}
.specs b{font-family:var(--disp); font-weight:800; letter-spacing:.12em; font-size:13px; color:var(--ink)}
.specs span{font-family:var(--mono); font-size:12px; color:var(--mut)}
/* ---------- stage ---------- */
.stage{position:relative; display:grid; justify-items:center; gap:26px; user-select:none}
.stamp{
position:absolute; top:-6px; left:50%; z-index:5; pointer-events:none;
font-family:var(--disp); font-weight:900; font-size:clamp(42px,6vw,66px);
color:var(--yel); text-shadow:4px 4px 0 rgba(4,16,22,.75);
opacity:0; transform:translateX(-30%) rotate(-12deg) scale(2.4);
}
#like:checked ~ .scene .stamp{animation:stampIn 1s cubic-bezier(.2,.9,.3,1) both}
@keyframes stampIn{
0%{opacity:0; transform:translateX(-30%) rotate(-12deg) scale(2.4)}
16%{opacity:1; transform:translateX(-30%) rotate(-9deg) scale(1)}
70%{opacity:1; transform:translateX(-30%) rotate(-9deg) scale(1)}
100%{opacity:0; transform:translateX(-30%) rotate(-9deg) scale(.92)}
}
.pad{position:relative; display:grid; place-items:center; padding:26px}
.pad::before{ /* orbit ring */
content:""; position:absolute; width:272px; height:272px; border-radius:50%;
border:1px dashed rgba(127,163,171,.35);
animation:spin 40s linear infinite reverse;
}
.sunburst{
position:absolute; width:min(540px,92vw); aspect-ratio:1; border-radius:50%;
background:repeating-conic-gradient(from 0deg, rgba(255,207,63,.11) 0deg 7deg, transparent 7deg 16deg);
-webkit-mask:radial-gradient(closest-side, transparent 16%, #000 22%, #000 58%, transparent 70%);
mask:radial-gradient(closest-side, transparent 16%, #000 22%, #000 58%, transparent 70%);
opacity:.55; transition:opacity .6s ease;
animation:spin 90s linear infinite; pointer-events:none;
}
#like:checked ~ .scene .sunburst{opacity:1}
@keyframes spin{to{transform:rotate(360deg)}}
/* ---------- THE button ---------- */
.btn{
position:relative; z-index:2; display:grid; place-items:center;
width:clamp(126px,16vw,156px); aspect-ratio:1; border-radius:50%;
cursor:pointer; outline-offset:7px;
transition:transform .18s cubic-bezier(.34,1.56,.64,1);
}
.btn:hover{transform:translateY(-3px)}
.btn:active{transform:translateY(1px) scale(.96)}
#like:focus-visible ~ .scene .btn{outline:3px dashed var(--yel)}
.face{
width:84%; aspect-ratio:1; border-radius:50%;
display:grid; place-items:center;
background:linear-gradient(160deg,#183b49,#0d2733);
border:3px solid #1f4a58;
box-shadow:0 16px 34px -14px rgba(0,0,0,.7), inset 0 -5px 0 rgba(4,16,22,.3);
transition:border-color .45s, box-shadow .45s, background .45s;
}
#like:checked ~ .scene .face{
border-color:#8a3247;
background:linear-gradient(160deg,#241a2c,#151020);
box-shadow:0 16px 34px -12px rgba(0,0,0,.75), 0 0 64px rgba(255,77,90,.28), inset 0 -5px 0 rgba(4,16,22,.35);
}
.heart{
width:54%; height:auto; display:block;
fill:transparent; stroke:#8fb4bb; stroke-width:1.6px;
transition:fill .3s ease, stroke .3s ease, transform .18s ease;
}
#like:not(:checked) ~ .scene .heart{animation:idleBeat 2.8s ease-in-out infinite}
@keyframes idleBeat{
0%,40%,100%{transform:scale(1)}
10%{transform:scale(1.08)}
20%{transform:scale(1)}
28%{transform:scale(1.05)}
}
.btn:hover .heart{stroke:#ffd7dd}
.btn:active .heart{transform:scale(.78)}
#like:checked ~ .scene .heart{
fill:var(--red); stroke:var(--red-d);
animation:heartPop .9s cubic-bezier(.3,1.4,.4,1) both;
}
@keyframes heartPop{
0%{transform:scale(.25) rotate(-18deg)}
38%{transform:scale(1.35) rotate(7deg)}
56%{transform:scale(.9) rotate(-4deg)}
74%{transform:scale(1.14) rotate(2deg)}
100%{transform:scale(1) rotate(0)}
}
/* shockwave + comic rays */
.ring{
position:absolute; inset:-4%; border-radius:50%; pointer-events:none;
border:5px solid var(--yel); opacity:0; transform:scale(.35);
}
#like:checked ~ .scene .ring{animation:ringOut .65s cubic-bezier(.2,.7,.3,1) .04s both}
@keyframes ringOut{
0%{opacity:.95; transform:scale(.35); border-width:9px}
100%{opacity:0; transform:scale(1.75); border-width:1px}
}
.rays{
position:absolute; inset:-52%; pointer-events:none; border-radius:50%;
background:repeating-conic-gradient(from 8deg, rgba(255,207,63,.9) 0deg 6deg, transparent 6deg 24deg);
-webkit-mask:radial-gradient(closest-side, transparent 30%, #000 34%, #000 52%, transparent 58%);
mask:radial-gradient(closest-side, transparent 30%, #000 34%, #000 52%, transparent 58%);
opacity:0; transform:scale(.4) rotate(0deg);
}
#like:checked ~ .scene .rays{animation:raysFlash .7s ease-out .02s both}
@keyframes raysFlash{
0%{opacity:0; transform:scale(.4) rotate(0deg)}
25%{opacity:1}
100%{opacity:0; transform:scale(1.22) rotate(28deg)}
}
/* confetti burst — 14 pieces */
.burst{position:absolute; inset:0; pointer-events:none}
.p{
position:absolute; left:50%; top:50%; opacity:0;
width:var(--s,10px); height:var(--s,10px); background:var(--c,#fff);
}
.p.dot{border-radius:50%}
.p.shard{height:calc(var(--s,10px)*.42); border-radius:2px}
#like:checked ~ .scene .p{
animation:shoot .85s cubic-bezier(.15,.85,.3,1) both;
animation-delay:calc(var(--k,0)*13ms);
}
@keyframes shoot{
0%{opacity:1; transform:translate(-50%,-50%) rotate(var(--a)) translateX(12px) scale(1)}
72%{opacity:1}
100%{opacity:0; transform:translate(-50%,-50%) rotate(var(--a)) translateX(var(--d)) scale(.12)}
}
/* runaway hearts */
.fly{position:absolute; inset:0; pointer-events:none}
.fly i{
position:absolute; left:50%; top:26%; font-style:normal; font-size:22px;
color:var(--red); text-shadow:2px 2px 0 rgba(4,16,22,.55); opacity:0;
}
#like:checked ~ .scene .fly i{
animation:rise 1.05s cubic-bezier(.2,.7,.3,1) both;
animation-delay:calc(.14s + var(--k,0)*.13s);
}
@keyframes rise{
0%{opacity:0; transform:translate(-50%,14px) scale(.4) rotate(0deg)}
14%{opacity:1}
100%{opacity:0; transform:translate(calc(-50% + var(--x,0px)),-165px) scale(1.05) rotate(var(--r,0deg))}
}
/* recoil */
#like:checked ~ .scene .btn{animation:kick .6s cubic-bezier(.3,1.2,.4,1) both}
@keyframes kick{
0%{transform:scale(.92)}
35%{transform:scale(1.06) rotate(2deg)}
70%{transform:scale(.985) rotate(-1deg)}
100%{transform:scale(1) rotate(0)}
}
/* ---------- readout ---------- */
.readout{
display:flex; align-items:center; gap:20px; flex-wrap:wrap; justify-content:center;
padding:11px 18px; border:1px dashed var(--line); background:rgba(255,255,255,.02);
font-family:var(--mono); font-size:12px; letter-spacing:.14em; color:var(--mut);
}
.swap{display:inline-grid; min-width:9ch; text-align:left}
.swap span{grid-area:1/1; transition:opacity .3s, transform .3s}
.swap .b{opacity:0; transform:translateY(8px)}
#like:checked ~ .scene .swap .a{opacity:0; transform:translateY(-8px)}
#like:checked ~ .scene .swap .b{opacity:1; transform:none}
.swap .a{color:var(--mint)}
.swap .b{color:var(--red)}
.likes{display:flex; align-items:baseline; gap:10px}
.num{font-size:21px; font-weight:700; letter-spacing:.06em; color:var(--ink)}
.win{display:inline-block; height:1.15em; overflow:hidden; vertical-align:top}
.reel{display:block; transition:transform .6s cubic-bezier(.22,1.4,.36,1) .12s}
.reel i{display:block; height:1.15em; line-height:1.15em; font-style:normal}
#like:checked ~ .scene .reel{transform:translateY(-1.15em)}
#like:checked ~ .scene .num{color:var(--yel)}
.num{transition:color .4s .12s}
.hint{
font-family:var(--mono); font-size:11px; letter-spacing:.22em; text-transform:uppercase;
color:var(--mut); text-align:center;
}
.hint .swap{min-width:0}
.hint .a::before{content:"▲ "; color:var(--yel); animation:bob 1.4s ease-in-out infinite}
.hint .a,.hint .b{display:inline-block}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
#like:checked ~ .scene .hint .b{color:var(--yel)}
/* ---------- ticker ---------- */
.ticker{
position:relative; z-index:2; overflow:hidden;
border-top:1px dashed var(--line); padding:12px 0;
background:rgba(7,25,32,.6);
}
.belt{display:flex; width:max-content; animation:tick 26s linear infinite}
.belt span{
font-family:var(--mono); font-size:11px; letter-spacing:.22em; text-transform:uppercase;
color:var(--mut); padding-right:3.5em; white-space:nowrap;
}
.belt em{font-style:normal; color:var(--yel)}
@keyframes tick{to{transform:translateX(-50%)}}
/* ---------- responsive ---------- */
@media (max-width:980px){
main{grid-template-columns:1fr; gap:34px; padding-bottom:64px}
.stage{order:2}
.top .hide-s{display:none}
.sunburst{width:min(440px,96vw)}
.pad::before{width:236px;height:236px}
}
@media (max-width:520px){
.specs li{grid-template-columns:1fr; gap:2px; padding:8px 4px}
.readout{gap:12px; font-size:11px}
.stamp{top:-14px}
h1 .l2{margin-left:.3em}
}
@media (prefers-reduced-motion:reduce){
.sunburst,.pad::before,.ambient i,.belt,.heart,.hint .a::before{animation:none !important}
#like:checked ~ .scene .heart{animation-duration:.25s}
#like:checked ~ .scene .p,
#like:checked ~ .scene .ring,
#like:checked ~ .scene .rays,
#like:checked ~ .scene .fly i,
#like:checked ~ .scene .stamp,
#like:checked ~ .scene .btn{animation-duration:.35s}
}
</style>
</head>
<body>
<input type="checkbox" id="like" class="vh" aria-label="Like this — toggles the animation">
<div class="scene">
<div class="halftone" aria-hidden="true"></div>
<div class="tint" aria-hidden="true"></div>
<div class="ambient" aria-hidden="true">
<i style="left:6%; --dur:21s; --dl:-3s; --o:.45; --c:#ff4d5a; font-size:14px">♥</i>
<i style="left:16%; --dur:27s; --dl:-12s; --o:.35; --c:#3ee6b0; font-size:10px">✦</i>
<i style="left:37%; --dur:23s; --dl:-7s; --o:.4; --c:#54c6ff; font-size:12px">✚</i>
<i style="left:57%; --dur:29s; --dl:-16s; --o:.35; --c:#ffcf3f; font-size:9px">●</i>
<i style="left:75%; --dur:22s; --dl:-9s; --o:.5; --c:#ff4d5a; font-size:13px">♥</i>
<i style="left:91%; --dur:25s; --dl:-2s; --o:.4; --c:#3ee6b0; font-size:11px">✦</i>
</div>
<header class="top">
<span>PURE CSS <span class="sep">◆</span> NO JS</span>
<span class="hide-s">SPECIMEN Nº 001 — THE LIKE BUTTON</span>
<span class="hot">PROPULSION: :checked</span>
</header>
<main>
<section class="copy">
<p class="eyebrow">Exhibit A · checkbox-powered ordnance</p>
<h1><span class="l1">Smash</span><span class="l2">that</span><span class="l3">Like.</span></h1>
<p class="lede">
One hidden <code><input type="checkbox"></code>. Zero JavaScript.
Fourteen particles, three runaway hearts, a shockwave and a comic-book
flash — every last bit of it fired by <code>:checked</code>. Click it twice:
it reloads.
</p>
<ul class="specs">
<li><b>ENGINE</b><span>1 × checkbox, 0 × scripts</span></li>
<li><b>PAYLOAD</b><span>♥ ×3 · confetti ×14 · shockwave ×1</span></li>
<li><b>SIDE EFFECTS</b><span>mild euphoria, urge to unlike</span></li>
</ul>
</section>
<section class="stage">
<div class="stamp" aria-hidden="true">POP!</div>
<div class="pad">
<div class="sunburst" aria-hidden="true"></div>
<label class="btn" for="like" title="Like">
<span class="rays" aria-hidden="true"></span>
<span class="ring" aria-hidden="true"></span>
<span class="burst" aria-hidden="true">
<i class="p dot" style="--a:8deg; --d:132px; --c:#ffcf3f; --s:10px; --k:0"></i>
<i class="p shard" style="--a:34deg; --d:118px; --c:#ff4d5a; --s:15px; --k:1"></i>
<i class="p dot" style="--a:60deg; --d:142px; --c:#3ee6b0; --s:8px; --k:2"></i>
<i class="p dot" style="--a:86deg; --d:120px; --c:#54c6ff; --s:11px; --k:3"></i>
<i class="p shard" style="--a:112deg; --d:138px; --c:#ffcf3f; --s:13px; --k:4"></i>
<i class="p dot" style="--a:138deg; --d:124px; --c:#ff8a3d; --s:9px; --k:5"></i>
<i class="p dot" style="--a:164deg; --d:146px; --c:#ffffff; --s:7px; --k:6"></i>
<i class="p shard" style="--a:190deg; --d:126px; --c:#3ee6b0; --s:16px; --k:7"></i>
<i class="p dot" style="--a:216deg; --d:140px; --c:#ff4d5a; --s:10px; --k:8"></i>
<i class="p dot" style="--a:242deg; --d:118px; --c:#ffcf3f; --s:8px; --k:9"></i>
<i class="p shard" style="--a:268deg; --d:144px; --c:#54c6ff; --s:12px; --k:10"></i>
<i class="p dot" style="--a:294deg; --d:128px; --c:#ff8a3d; --s:11px; --k:11"></i>
<i class="p dot" style="--a:320deg; --d:140px; --c:#3ee6b0; --s:8px; --k:12"></i>
<i class="p shard" style="--a:346deg; --d:132px; --c:#ffffff; --s:13px; --k:13"></i>
</span>
<span class="fly" aria-hidden="true">
<i style="--x:-52px; --r:-22deg; --k:0">♥</i>
<i style="--x:6px; --r:8deg; --k:1; font-size:27px">♥</i>
<i style="--x:56px; --r:20deg; --k:2">♥</i>
</span>
<span class="face">
<svg class="heart" viewBox="0 0 24 24" aria-hidden="true">
<path d="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"/>
</svg>
</span>
</label>
</div>
<div class="readout">
<span>STATUS
<span class="swap"><span class="a">ARMED</span><span class="b">LIKED ♥</span></span>
</span>
<span class="likes">
<span>LIKES</span>
<span class="num">4,09<span class="win"><span class="reel"><i>5</i><i>6</i></span></span></span>
</span>
</div>
<p class="hint">
<span class="swap">
<span class="a">Click it — or Tab to it & hit Space</span>
<span class="b">Nice. Click again to unlike & reload</span>
</span>
</p>
</section>
</main>
<footer class="ticker" aria-hidden="true">
<div class="belt">
<span>NO JAVASCRIPT WAS HARMED IN THE MAKING OF THIS BUTTON <em>✦</em> ONE CHECKBOX, FOURTEEN PARTICLES <em>✦</em> 100% :CHECKED PROPULSION <em>✦</em> UNLIKE AT YOUR OWN RISK <em>✦</em></span>
<span>NO JAVASCRIPT WAS HARMED IN THE MAKING OF THIS BUTTON <em>✦</em> ONE CHECKBOX, FOURTEEN PARTICLES <em>✦</em> 100% :CHECKED PROPULSION <em>✦</em> UNLIKE AT YOUR OWN RISK <em>✦</em></span>
</div>
</footer>
</div>
</body>
</html>Reasoning trace (11,887 tokens)
The user wants a "like" button in pure CSS — no JavaScript — with an insane animation when clicked. The tricky part: pure CSS click detection without JavaScript. The classic technique: use a checkbox (`<input type="checkbox">`) and `:checked` to trigger the animation, or use `:active` for press only. For "click to toggle" behavior, the checkbox hack is the right one — clicks toggle checked, and CSS animation kicks off on `:checked ~ label` or with `:has()`.
Since this is a showcase piece, I should build a rich scene: a layered background, motion, micro-interactions, strong typographic contrast. It should feel like a crafted, playful demo — like a lab / playground for the like button. Multiple elements: particles bursting (pure CSS with checkboxes triggering animations on sibling elements), floating hearts, a ring pulse, confetti shards, a counter that flips (pure CSS counter via the `counter()` trick — actually CSS counters combined with content can work in conjunction with checked state… for a counter that increments, you can fake it with two overlapping numbers that swap on checked).
Key pure-CSS mechanisms:
- A hidden `<input type="checkbox" id="like">`, with `<label for="like">` as the button.
- On `:checked`, the heart scales/bounces, a burst ring expands, particles fly out radially using custom properties and keyframes.
- Click again to unlike — reverse-play (maybe the reverse animation is subtle).
- `:active` for a squish on press.
- Also add `:focus-visible` styling for accessibility.
Modern CSS supports `:has()`, so `body:has(#like:checked)` can change the whole scene: background hue shift, ambient elements react, etc. That's nice "insanity" — the whole scene responds.
Design direction: let me pick something distinctive. A like button is social-media-ish — playful candy / pop-art vibe. Let me pick something bolder: hot pop-art / arcade feel. Deep teal / petrol background with warm coral-red hearts and yellow bursts — high contrast, playful. Or a "lab specimen" concept: "The Like Button — Specimen No. 1" and a specimen-plate aesthetic. That has character and is fun.
Idea: a pop-art / comic-book scene — halftone-dot background, thick outlines, "POW"-style burst. Click → heart explodes into confetti shards, a ring shockwave, comic burst rays rotate, numbers tick up with a flip. The scene can switch from a muted state to a vivid state via `:has(:checked)`. That's distinctive and matches the theme (liking = pop!). Fonts: can't load external fonts (no network requests), so I have to use system fonts. Character can come from the treatment itself: heading in a condensed heavy uppercase (e.g. `"Avenir Next Condensed", "Arial Narrow", "Franklin Gothic Medium", sans-serif`) with letter-spacing; body in a normal sans; counter digits maybe in monospace (`"SF Mono", ui-monospace`). Typographic contrast comes from size / weight / treatment.
The demo needs something meaningful on first paint; since it's a click interaction, no self-play needed (that rule is for games). A "click it" hint is enough. Keyboard: checkbox is focusable and toggleable with space, so I'll display a hint; the iframe will receive keyboard after a click anyway.
Let me design the scene:
Layout (1280×800, adapts down to 375):
- Full-viewport scene. Background: layered — a deep petrol/ink base with a halftone dot pattern (radial-gradient dots), a large rotating sunburst behind the button (conic-gradient rays, low opacity, slow rotation), floating ambient hearts / sparkles drifting upward.
- Top-left: small label/spec tag. Big display heading: "PRESS FOR DOPAMINE" or "THE LIKE MACHINE". Maybe a spec sheet on the side: "SPECIMEN 001 · CLASSIC HEART · SIDE EFFECTS: EUPHORIA".
- Center: the like button — a big circular button with a heart inside, sitting on a pedestal / shadow. Around it: burst parts (particles, ring, rays), number badge.
- Bottom: a caption / counter row: "LIKES: 4,095" → flip animation changes it to 4,096 on checked. Use a sliding odometer effect: two digit stacks, translateY on check.
- A small "unlike" micro-reaction too: when unchecked, a little gray "pfft" puff? A small shake could work.
Insane-animation details on check (one-way on check; reverse is simpler):
1. Heart: squash & stretch — shrink, then overshoot scale with rotation wiggle, color shifts from outline / gray to hot red, tiny tilt. Keyframes with spring-y overshoot steps.
2. Shockwave ring: an expanding bordered circle, fades out.
3. Particle burst: 10–14 dots / shards using CSS custom properties to shoot outward at different angles (--angle per particle), colors: yellow, coral, mint, white. Use `transform: rotate(var(--a)) translateX(dist)` keyframes, fade.
4. Rotating comic rays (conic-gradient starburst) behind the heart scale up + rotate, then vanish.
5. The button itself kicks back (recoil) and returns; shadow squishes.
6. Floating mini-hearts drift up from the button (three of them, staggered, wobbling).
7. Counter flips: the "LIKES" number rolls 4095→4096 with an odometer translate.
8. Whole scene: `body:has(#like:checked)` shifts background hue slightly / turns on the sunburst brightness; big background text "LIKE!" stamps in with a slight rotate. Maybe the heading letters also jitter once.
Unchecked → default: heart returns with a subtle deflate animation. Animations defined on the `:checked` state only play forward; when unchecked, we can define a quick "deflate" animation on the unchecked state — but the initial page load would also trigger it. Trick to avoid animation on load: use `:not(:checked)` animations scoped under a `body.user-acted`-ish hack — not possible in pure CSS. Alternative: use `body:has()` to detect… no, no interaction flag exists. Common workaround: apply "off" animations only to elements inside a wrapper via `#like:not(:checked) ~ .stage .heart` — but they'd still run on load. Acceptable? A subtle settle animation on load might actually be nice (heart breathes in). But the particle burst on load would be weird. Keep the burst animations strictly under `:checked` selectors, and for the uncheck simply snap back with a transition (no animation), or a very subtle transition. Use transitions for the resting state so the uncheck is a gentle deflation (scale down with cubic-bezier), and the checked animation does the insanity.
`label:active` also triggers squish (pressing down shrinks the heart) — that gives tactile feedback before release triggers the burst.
Multiple like buttons? The task is "one like button" — keep one hero button. But I can add ambient details: ticker text, a spec sheet. Keep the focus.
Counter without JS: static text "LIKES" and the number: two spans stacked inside a fixed-height window, `.odometer` with `translateY(-1em)` on check. Digit 5 → 6 in "4 0 9 5|6". Only the last digit needs to roll. Nice micro-detail: an extra bouncy easing.
Accessibility: `.sr-only` label text inside the label ("Like"). Use `:focus-visible` ring on the label when the input is focused: `#like:focus-visible ~ .stage .btn { outline... }`.
Colors: pick a palette —
- bg: deep ink teal `#0d2b33` / `#0a2229`, halftone dots slightly lighter.
- accent heart: hot coral-red `#ff4d5a` / `#ff2e4d`.
- burst: butter yellow `#ffd23f`, mint `#3ee6b0`, sky `#4cc9f0`, white.
- text: off-white `#f4f1e6`, secondary muted `#8fb0b5`.
The red heart over teal pops nicely, and I've got multiple accents (yellow, mint, coral) plus the halftone texture.
Halftone: `background-image: radial-gradient(circle, rgba(...) 1px, transparent 1.5px)` with `background-size: 18px 18px`. Plus a big conic sunburst centered on the button: a repeating-conic-gradient of yellow rays at ~5% opacity, slow spin via animation. Layered background ✓.
Typography: display stack: `'Avenir Next Condensed','Franklin Gothic Medium','Arial Narrow',sans-serif` heavy, uppercase, tight tracking? Actually, for punch: big letter-spacing on small labels, giant heading. Body: `'Avenir Next','Segoe UI',system-ui`. Counter: `ui-monospace,'SF Mono','Cascadia Mono',Consolas,monospace`.
Heading ideas: since the subject is the like button, open the scene with the button as the centerpiece, plus a plate: "SPECIMEN Nº 001 — THE LIKE BUTTON". Big word behind: "POP!". Maybe top bar: left "PURE CSS · NO JS · 100% :checked", right "CLICK RESPONSIBILITY: YOURS".
Layout plan (desktop):
- Grid: header row (top bar), main center stage, footer strip.
- Top bar: small-caps labels on left and right, maybe also a dashed rule below.
- Center: stage with the button; heading can sit above or to the side of the button. Left column vertical: giant heading "PRESS. / POP. / REPEAT." and a spec list; right / center: the button. Stack on mobile.
Hmm, simpler and bolder: put the giant headline behind/above the button, centered? I'll go with an asymmetric left-aligned block + right stage on wide screens. Structure:
```
<main class="scene">
<input checkbox id="like" class="visually-hidden">
<header>...</header>
<section class="grid">
<div class="copy">
<p class="eyebrow">SPECIMEN Nº 001 · PURE CSS</p>
<h1>THE<br>LIKE<br>BUTTON</h1>
<p class="lede">Zero JavaScript. One checkbox. Fourteen particles of pure chaos. Click it — your serotonin is waiting.</p>
<ul class="specs">
<li>PROPULSION — :checked</li>
<li>PAYLOAD — hearts ×3, confetti ×14</li>
<li>SIDE EFFECTS — delight</li>
</ul>
</div>
<div class="stage">
<div class="sunburst"></div>
<div class="stamp">POP!</div>
<label for="like" class="btn">
<span class="ring"></span>
<span class="rays"></span>
particles...
<span class="heart">♥? or svg-like shape via CSS</span>
<span class="badge">...</span>
</label>
<div class="odometer">LIKES 4,095→4,096</div>
<p class="hint">☝ click / space to fire</p>
</div>
</section>
<footer>ticker / note</footer>
</main>
```
For the input to control everything via sibling selectors, the input needs to come before the elements as a preceding sibling (or use `:has`). Place the input as the first child of body (or of .scene), and use `#like:checked ~ ...` selectors. Also `body:has(#like:checked)` for scene-wide shifts (works in latest Chrome).
Heart shape: CSS heart with two circles + a rotated square, or an emoji ♥ styled — the emoji rendering varies. Better: draw a heart with a rotated square and two circles pseudo-element inside a span, or a div with `clip-path`? A classic CSS heart:
```
.heart { width: X; height: X; transform: rotate(-45deg); }
.heart::before/::after { circles at top/left }
```
But animating an inner fill + outline is fiddly. Alternative: inline SVG inside the label — that's allowed ("no JavaScript" — SVG is fine, still pure-CSS interaction). An inline SVG heart path with stroke + fill is crisp and controllable: on check, fill transitions from transparent → red, stroke also changes, animate the SVG wrapper's transform. Using SVG is practical and looks good. "Pure CSS" refers to the interaction/styling; inline SVG is markup, no problem.
Actually, let me build the heart as inline SVG with a path, class `.heart-svg`. Inside the label button:
```
<label class="btn" for="like">
<svg class="heart" viewBox="0 0 24 24">...path...</svg>
</label>
```
Heart path: `M12 21s-8.4-5.6-11-10.2C-0.6 7 1.8 3 5.6 3c2.3 0 3.9 1.2 4.9 2.9C11.5 4.2 13.1 3 15.4 3c3.8 0 6.2 4 4.6 7.8C17.4 15.4 12 21 12 21z` — I'll use the well-known one: "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". Good.
Particles: 14 spans inside `.burst` container, each with a custom property `--i` for angle and color, size variants (dots, rectangles / shards). Keyframes:
```
@keyframes shoot {
0% { transform: rotate(var(--a)) translateX(6px) scale(1); opacity: 1; }
100% { transform: rotate(var(--a)) translateX(var(--d)) scale(.2); opacity: 0; }
}
```
Wait, rotation with a child element: put each particle at the center, transform-origin center; rotate(var(--a)) then translateX moves along that angle. For a shard's own rotation, add an inner spin? Keep simple: shard is a rectangle that also scales. `animation: shoot .8s cubic-bezier(.2,.7,.3,1) forwards; animation-delay: calc(var(--k)*12ms)` for stagger.
Ring: `.ring` scale 0→1.6, border-width shrinks, opacity fades, .6s.
Rays: `.rays` with `background: repeating-conic-gradient(from 0deg, var(--yellow) 0 9deg, transparent 9deg 30deg);` masked into a ring? Simpler: use a star-burst via conic with radial fade mask: `-webkit-mask: radial-gradient(closest-side, transparent 30%, black 31% 70%, transparent 71%)`. Scale 0→1.15, rotate 40deg, fade out.
Mini-hearts: three spans with ♥ glyph? CSS shape or the tiny SVG again. Use the ♥ text glyph with `font-size` — cross-platform rendering as text glyph is fine (U+2665 renders everywhere). Use `content:"♥"`. Rise animation: translateY(0→-140px) with translateX wiggle keyframes (separate `--x` left/right paths), scale, fade. Staggered delays .1/.25/.4s.
Stamp "POP!": a big word behind the button that stamps in with scale 3→1, rotate -12deg, and fades after ~0.9s (forwards to opacity 0? or leave it briefly then disappear). Keep: appear and disappear (opacity keyframes 0→1→0). Fun.
Button recoil: `.btn` animation `kick`: scale 1→.9→1.06→1 with slight rotate. Heart itself: `heart-pop`: scale 0.2→1.25→0.9→1.05→1, rotate wiggle -10→6→0. Default (unchecked) heart: gray / outline (stroke #7e9aa0, fill transparent or dark). Checked: fill red, stroke deep red.
Transition on uncheck: heart fill transitions back quickly (.25s), a tiny `transform: scale(.9)` then settle — using a transition is fine.
Scene-wide via `body:has(#like:checked)`:
- Background color shifts slightly warmer / brighter: `body { background: #0b2530; } body:has(...){ background:#123140 }`? Transition on background. Or increase sunburst opacity.
- The ambient floating sparks speed up / brighten.
- Heading accent word color flips to red.
- Keep subtle to not distract.
Ambient background elements: 5–6 tiny hearts / plus signs / dots at various positions with low opacity, drifting slowly up and looping (`@keyframes drift`), each with a different duration/delay. Plus a halftone dot layer, plus a fixed `.sunburst-bg` centered on the stage, slow rotate 60s linear infinite. Plus a subtle vignette.
Odometer:
```
<div class="count">
<span class="lbl">LIKES</span>
<span class="window"><span class="reel">4,095<br>4,096</span></div>
</div>
```
Better: keep "4,09" static and roll the last digit: window height 1em, reel is a column of "5" "6". `#like:checked ~ ... .reel { transform: translateY(-1.1em); }` with a bouncy cubic-bezier(.3,1.6,.4,1) and .5s transition, small delay so it lands with the burst. Also change label color.
Also a small status line toggle: default "STATUS: ARMED" → checked "STATUS: LIKED ✔". Use two spans that crossfade via `:checked` selector.
Press feedback: `.btn:active .heart { transform: scale(.8); }` with a fast transition. Cursor pointer. Hover: heart tilts / brightens, button lifts, shadow grows; maybe a subtle idle heartbeat animation when unchecked (a gentle pulse of scale 1↔1.04 every 2.2s), drawing attention — nice living detail. Idle pulse halts during the pop animation (animation overrides).
Focus style: `#like:focus-visible ~ .stage .btn { box-shadow ring }`.
Hide the checkbox visually but keep it focusable: `.visually-hidden` clip technique (don't use display:none, that would remove keyboard focus).
Footer: marquee-style ticker? A pure-CSS marquee via translateX loop, duplicated content: "NO JAVASCRIPT WAS HARMED · ONE CHECKBOX · ZERO LIBRARIES · ...". Adds motion; placed at bottom edge. Keep low contrast.
Responsive:
- ≥900px: two-column grid (copy | stage).
- <900: single column, copy first, stage below; shrink heading with clamp().
- Ensure no horizontal overflow: `overflow-x: hidden` on body (careful with fixed elements), use min(…, vw) sizes.
- 375px: reduce padding, particle distances in px are fine, button size ~120px.
Viewport height: use min-height: 100svh with fallback 100vh; center content; at 800px height it should fit: heading clamp max ~72px, stage button ~180px. OK.
Reduced motion: `@media (prefers-reduced-motion: reduce)` turns long animations off / shortens them — good craftsmanship.
Now for the exact CSS structure with sibling selectors. Put `<input id="like">` right after `<body>`, then `<div class="scene">` containing everything, so selectors become `#like:checked ~ .scene …`, `#like:not(:checked) ~ .scene …`, and for body-level things `body:has(#like:checked)`.
Particle markup: 14 spans, each with style="--a:26deg; --d:120px; --c:#ffd23f; --k:1". Mix shapes: `.p.dot` round, `.p.shard` rotated rectangle. Vary distances 90–150px.
Angles: distribute: 0,25,52,80,105,135,160,185,215,240,265,290,315,340, with varied colors.
Keyframes list:
- heart-pop
- kick
- ring-out
- shoot
- rays-flash
- rise (mini hearts)
- stamp
- idle-pulse (subtle heartbeat on the heart when unchecked)
- spin (background sunburst)
- drift (ambient float)
- tick (ticker)
- maybe flicker for hint arrow
- count reel transition (transition, not keyframe)
Important: animations on `:checked` must use `both` / `forwards`, and only run when checked. On uncheck, animations are removed and elements snap to base styles — but particles snap back visible for a moment? Base particle style: `opacity: 0`, so at rest they're invisible. Ring is base opacity 0. Rays opacity 0. Mini-hearts opacity 0. Stamp opacity 0. So on uncheck they vanish instantly — no problem, and the heart smoothly transitions back via transition (fill/transform). To make uncheck cute, add a quick scale down via transition (heart transform base scale(1); on check animation ends at scale(1) fill forwards; on uncheck animation removed → transform transitions from 1… to same, no problem). Maybe the uncheck triggers a subtle "sigh": not easily doable without load-time animation. Never mind — add a small transition rotate.
Wait: if the animation is defined under `#like:checked ~ ... .heart { animation: heart-pop .9s ... both; }`, on uncheck animation is removed, and the element returns to base via transition — transform transitions apply since the property changed. Good: give `.heart { transition: transform .35s cubic..., fill... }` (SVG fill transitions work as CSS `fill` transition). Use CSS for fill/stroke rather than attributes to enable transition: set `fill` and `stroke` via classes in CSS.
Idle heartbeat: on the `.heart` wrapper span (not svg), `animation: idle 2.4s ease-in-out infinite` — pause / remove when checked: `#like:checked ~ .scene .heart-wrap { animation: none; }` and apply pop on the same wrapper? Combining idle + pop on same element conflicts; put idle on `.btn` glow or on the heart svg when unchecked:
`#like:not(:checked) ~ .scene .heart-svg { animation: idle 2.6s infinite; }`
Issue: this also runs on load — that's fine (nice living detail). When re-unchecking, the idle restarts from 0 — acceptable, subtle.
But on load, does anything weird run? Only idle + ambient drift + ticker — all nice.
Hint: "CLICK THE BUTTON — OR FOCUS IT AND PRESS SPACE" with an animated arrow bobbing up-down. The checkbox is focusable, so mention keyboard. Also, since iframe needs a click first, hint says "click inside, then…". Keep simple: "GO ON — CLICK IT (SPACE WORKS TOO)".
Add `user-select:none` to stage.
Big background word: faint giant "LIKE!" outline text behind the stage? When checked, "POP!" stamp appears. Base: maybe none, cleaner.
Header top bar: left: "PURE-CSS LIKE MACHINE"; right: "PAYLOAD: ♥♥♥ + CONFETTI"; separated by a dashed rule. Small caps, letter-spacing.
Copy heading: giant condensed uppercase: "SMASH / THAT / LIKE." — with the last word in coral, slight rotate / highlight? Per-word stack, big size clamp(3rem, 8vw, 6.5rem), weight 900, condensed stack. Lede in normal sans, muted. Specs: mono small list with arrows.
Also add a second interactive? Task says one like button — keep one, richly.
Let me write the code carefully.
Structure:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The Pure-CSS Like Machine</title>
<style> ... </style>
</head>
<body>
<input type="checkbox" id="like" class="vh" aria-label="Like">
<div class="scene">
<div class="halftone"></div>
<div class="sunburst"></div>
<div class="ambient"> spans ... </div>
<header class="top">
<span class="tag">PURE CSS · NO JS</span>
<span class="tag">SPECIMEN Nº 001</span>
<span class="tag">PROPULSION: :checked</span>
</header>
<main class="grid">
<section class="copy">
<p class="eyebrow">Exhibit A — the humble checkbox-powered</p>
<h1><span class="l1">SMASH</span> <span class="l2">THAT</span> <span class="l3">LIKE.</span></h1>
<p class="lede">One hidden checkbox. Zero JavaScript. Fourteen particles, three runaway hearts and one shockwave, all fired by <code>:checked</code>. Go on — press the button.</p>
<ul class="specs">
<li><b>ENGINE</b><span>1 × <input type="checkbox"></span></li>
<li><b>PAYLOAD</b><span>♥ ×3 · confetti ×14 · shockwave ×1</span></li>
<li><b>SIDE EFFECTS</b><span>mild euphoria, urge to unlike</span></li>
</ul>
</section>
<section class="stage">
<div class="stamp" aria-hidden="true">POP!</div>
<label class="btn" for="like">
<span class="rays" aria-hidden="true"></span>
<span class="ring" aria-hidden="true"></span>
<span class="burst" aria-hidden="true">
14 × <i class="p dot|shard" style="--a..">
</span>
<span class="hearts-fly" aria-hidden="true"><i class="hf" style="--x:-46px; --r:-24deg; --d:.05s">♥</i>...</span>
<span class="face">
<svg class="heart" viewBox="0 0 24 24" aria-hidden="true"><path d="..."/></svg>
</span>
</label>
<div class="readout">
<span class="mode">STATUS</span>
<span class="stack"><span class="on">ARMED</span><span class="off">LIKED ♥</span></span>
<span class="count">
<span class="win"><span class="reel">5<br>6</span></span><span class="pre">4,09</span>? order...
</span>
</div>
<p class="hint">▲ CLICK IT — OR TAB TO IT AND HIT SPACE</p>
</section>
</main>
<footer class="ticker"><div class="belt"><span>...</span><span aria-hidden>duplicate</span></div></footer>
</div>
<script>none</script>
</body>
</html>
```
Counter display: "LIKES 4,095" static with the last digit rolling. Markup:
```
<div class="likes">
<span class="likes-label">LIKES</span>
<span class="num">4,09<span class="win"><span class="reel"><i>5</i><i>6</i></span></span></span>
</div>
```
Window: display inline-block; height 1em; overflow hidden; reel is a flex column; transition transform .55s bouncy with .12s delay.
Wait — a line of mono digits: set font to mono, size ~28px.
Status crossfade: stack the two words; `.on` visible by default; when checked `.on` hides, `.off` shows with a small slide.
Colors:
```
--bg0:#08222b; --bg1:#0d3140;
--ink:#eef6f2;
--mut:#7fa3ab;
--red:#ff3b52; --red-d:#c81e3c;
--yel:#ffcf3f; --mint:#2fe6a7; --sky:#54c6ff; --org:#ff8a3d;
--line:#1d4552;
```
Halftone layer: dots radial gradient in low-opacity mint-ish color, plus a second offset layer? One layer is enough + vignette radial.
Sunburst behind stage: place absolutely centered on the button. Simpler: place `.sunburst` absolutely inside `.stage` centered on the button position. Stage is a flex column centered; put sunburst in a wrapper `.pad` around the label: position absolute inset centered, size 560px, `background: repeating-conic-gradient(rgba(255,207,63,.07) 0 6deg, transparent 6deg 15deg); border-radius:50%; mask radial fade`. Animation spin 80s linear infinite. When checked, briefly brighten: `body:has(#like:checked) .sunburst { opacity:1 }` default .6.
Halftone is static.
Header `.top`: flex justify-between with dashed border-bottom padding; hide middle tag on small screens.
Grid: `grid-template-columns: minmax(0,1.05fr) minmax(0,1fr);` big gap; align center; max-width 1200 centered; padding.
Stage: display grid; justify-items center; row gap 22px; position relative; padding-block for stamp.
Copy heading spans: display block for stacked lines; `.l3` in coral with a slight rotate(-2deg) and a text-shadow offset (comic-style: `text-shadow: 4px 4px 0 rgba(0,0,0,.35)` and a coral color). Maybe give each line a slight offset indent for liveliness: l2 margin-left .6em, l3 -rotate. Eyebrow: mono uppercase, small, mint, letter-spacing .3em.
Lede: max-width 46ch, color mut, size 15-16px. Inline code styled as mono chip.
Specs list: border-top dashed per row, b is condensed uppercase, span is mono mut, hover row highlight.
Ambient floaters: `.ambient i` positioned fixed-ish absolute inside scene, characters ♥, ✚, ✦, ●, with low opacity, `animation: drift Xs linear infinite`, drift: translateY(20px)→(-30px) alternate? Better: continuous rise loop with fade: keyframes floatUp { from translateY(15vh) opacity 0; 10% opacity .35; to translateY(-110vh) opacity 0 } with different durations 18–30s and negative delays so mid-flight at load. Place at various left%. This gives gentle living background. Use characters: ♥ ✦ + ●.
Ticker: fixed footer inside scene bottom; overflow hidden; belt is flex; width max-content; animation tick 22s linear infinite; two identical spans separated by gap; content: "NO JAVASCRIPT WAS HARMED IN THE MAKING OF THIS BUTTON ✦ ONE CHECKBOX, FOURTEEN PARTICLES ✦ 100% :CHECKED PROPULSION ✦ UNLIKE AT YOUR OWN RISK ✦ " repeated. Mono uppercase, small, muted, border-top dashed. TranslateX(-50%) loop (belt has two halves). Use padding-right for the gap.
prefers-reduced-motion: turn off spin/drift/ticker/idle; keep pop but shorten; simplest: `*{animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important}`? That kills the point of the demo for such users but is correct etiquette; maybe reduce just ambient and keep the pop short. Disable ambient / ticker / spin / idle, and keep the main pop but at a shorter time.
Responsive tweaks:
- @media (max-width: 940px): grid single column; copy text-align left still; stage margin-top; reduce heading clamp; hide middle tag in top; keep ticker.
- @media (max-width: 480px): btn 120px; face 104px; particles --d scale? distances fixed at ~120px which is fine; compress specs; stamp font smaller; heading size already clamp(2.6rem, 12vw...). Use clamp everywhere.
Height concerns at 1280×800: header ~48 + main content: heading ~3×72=216 + lede + specs ~ copy total ~420; stage: btn 150 + readout ~40 + hint ~20 + gaps ~280. Fits.
Now for checked selectors — all need the `#like:checked ~ .scene` prefix since input is a preceding sibling of .scene. Also `#like:focus-visible ~ .scene .btn`.
Edge: label needs `for="like"` and input must be preceding sibling — click on label toggles input: yes, works.
Also `#like:checked ~ .scene .hint .go { opacity:.35 }`, and maybe swap the hint text? Crossfade two spans: "GO ON — CLICK IT" → "NICE. CLICK AGAIN TO UNLIKE". Cute: do the stack crossfade like status.
Also ensure the page fits in 800px height without scroll: header 46 + main fits; ticker overlays bottom; main padding-bottom 70. Fine; use min-height and allow scroll if needed but aim to fit.
Now let me write the final code carefully. Ensure valid HTML, escape `<` in text (use `<input>`), no JS at all. The task says "no JavaScript" — omit the script tag entirely.
One more check: `.vh` checkbox focusable: yes, position absolute clip. Label click toggles. Space toggles when input focused. Show focus ring on .btn via :focus-visible.
Also the heart path: use the classic material heart:
`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`
Heart svg size: 54% of face.
Write the CSS neatly.
Let me write out all the particles with inline vars:
```
<span class="burst" aria-hidden="true">
<i class="p dot" style="--a:8deg; --d:132px; --c:#ffd23f; --s:10px; --k:0"></i>
<i class="p shard" style="--a:34deg; --d:118px; --c:#ff4d5a; --s:14px; --k:1"></i>
<i class="p dot" style="--a:60deg; --d:142px; --c:#3ee6b0; --s:8px; --k:2"></i>
<i class="p dot" style="--a:86deg; --d:120px; --c:#54c6ff; --s:11px; --k:3"></i>
<i class="p shard" style="--a:112deg; --d:138px; --c:#ffcf3f; --s:13px; --k:4"></i>
<i class="p dot" style="--a:138deg; --d:124px; --c:#ff8a3d; --s:9px; --k:5"></i>
<i class="p dot" style="--a:164deg; --d:146px; --c:#fff; --s:7px; --k:6"></i>
<i class="p shard" style="--a:190deg; --d:126px; --c:#3ee6b0; --s:15px; --k:7"></i>
<i class="p dot" style="--a:216deg; --d:140px; --c:#ff4d5a; --s:10px; --k:8"></i>
<i class="p dot" style="--a:242deg; --d:118px; --c:#ffcf3f; --s:8px; --k:9"></i>
<i class="p shard" style="--a:268deg; --d:144px; --c:#54c6ff; --s:12px; --k:10"></i>
<i class="p dot" style="--a:294deg; --d:128px; --c:#ff8a3d; --s:11px; --k:11"></i>
<i class="p dot" style="--a:320deg; --d:140px; --c:#3ee6b0; --s:8px; --k:12"></i>
<i class="p shard" style="--a:346deg; --d:132px; --c:#fff; --s:12px; --k:13"></i>
</span>
```
Base for particles: position absolute left 50% top 50%, margin -half? transform handles from center; set left:50%; top:50%; and include translate(-50%,-50%) in both keyframe frames: `transform: translate(-50%,-50%) rotate(var(--a)) translateX(var(--d0))`. OK.
Shard: width var(--s); height calc(var(--s)*.42); border-radius 2px. Dot: width/height var(--s); border-radius 50%.
Mini-hearts:
```
<span class="fly" aria-hidden="true">
<i style="--x:-52px; --r:-22deg; --k:0">♥</i>
<i style="--x:6px; --r:8deg; --k:1; font-size:26px">♥</i>
<i style="--x:56px; --r:20deg; --k:2">♥</i>
</span>
```
fly container placed centered on button: absolute inset 0, pointer-events none; i absolute left 50% top 30%.
rise keyframes with opacity 0 at 0% so hidden before delay: 0%{opacity:0; transform:translate(-50%,10px) scale(.4)} 12%{opacity:1} 100%{opacity:0; transform: translate(calc(-50% + var(--x)), -160px) rotate(var(--r)) scale(1)}. Duration 1s, delay calc(var(--k)*.13s + .12s), forwards. Base opacity 0.
Stamp: position absolute; maybe top center over the button; `top:-8px`. Font weight 900, color yel, -webkit-text-stroke 2px var(--ink-deep)? text-stroke overlaying fill can look off; use text-shadow outline trick, or just a solid yel with a dark shadow. Use color var(--yel) with text-shadow 4px 4px 0 rgba(7,25,32,.8). Font-size clamp(40px, 7vw, 68px). Rotate -12deg.
Readout styling: border 1px dashed var(--line); padding 10px 16px; display flex; gap 18px; align center; background rgba(255,255,255,.02). Mono.
Status word: `.on` color mint; `.off` color red. Both absolute in a relative span of width set — to avoid width jump, set min-width: 7ch on the stack.
Counter digits: `.num` mono bold 22px ink; window height 1.15em, reel i height 1.15em, line-height 1.15em; translateY(-1.15em).
Hmm, `i` inside reel display block.
Ticker content spans separated by gap 2em; each span ends with ✦. Two identical spans for seamless -50% loop.
Also add `::selection` styling coral — nice touch.
Focus ring: `#like:focus-visible ~ .scene .btn{ outline:3px dashed var(--yel); outline-offset:6px; }`.
Cursor on `.vh` is irrelevant. Label cursor pointer.
Also ensure no horizontal scrollbar: all absolute decorations inside scene with `overflow:hidden` (scene is min-height 100svh, position relative, overflow hidden). Ambient floaters inside it.
Ambient floaters: 6 items:
```
<i style="left:6%; --dur:21s; --dl:-3s; --o:.5; font-size:14px">♥</i>
<i style="left:16%; --dur:26s; --dl:-12s; --o:.35; font-size:10px">✦</i>
<i style="left:38%; --dur:23s; --dl:-7s; --o:.4; font-size:12px">+</i>
<i style="left:58%; --dur:28s; --dl:-16s; --o:.35; font-size:9px">●</i>
<i style="left:76%; --dur:22s; --dl:-9s; --o:.5; font-size:13px">♥</i>
<i style="left:90%; --dur:25s; --dl:-2s; --o:.4; font-size:11px">✦</i>
```
Colors: alternate muted coral / mint. animation floatUp var(--dur) linear infinite; animation-delay var(--dl). Keyframes: 0%{transform:translateY(105vh); opacity:0} 8%{opacity: calc(.5*var(--o))}? Can't multiply var in opacity unless calc — calc(var(--o)*.8) is fine. End 100%{transform:translateY(-12vh); opacity:0}.
Set their color per item via a --c var: style includes --c:#ff4d5a etc.
OK. Scene background is base gradient; plus a subtle top glow.
Header tags: mono 11px, letter-spacing .18em, uppercase, color mut; separated by "◆". Use flex gap with a dot in between: simple spans separated by `<span class="sep">◆</span>`; hide the last tag on mobile.
Edge: ensure text in lede escapes properly: `<input type="checkbox">`.
Title / h1 semantics also fine.
Time to write. CSS organized with comments. Ensure zero console errors: no JS at all → fine.
Double-check the `.stack` spans for the hint: give it a min-height to avoid layout shift; two overlapping spans.
Crossfade pattern:
```
.swap{display:inline-grid;}
.swap span{grid-area:1/1; transition:opacity .3s, transform .3s;}
.swap .b{opacity:0; transform:translateY(8px);}
#like:checked ~ .scene .swap .a{opacity:0; transform:translateY(-8px);}
#like:checked ~ .scene .swap .b{opacity:1; transform:none;}
```
Use `.swap` for status and hint.
The like counter window: transition with spring delay:
```
.reel{transition:transform .6s cubic-bezier(.22,1.4,.36,1) .12s;}
#like:checked ~ .scene .reel{transform:translateY(-1.15em);}
```
Button shadow: `box-shadow: 0 14px 30px -12px rgba(0,0,0,.6), inset 0 -4px 0 rgba(7,25,32,.25);` face background: linear-gradient(#173845,#0e2833); border 3px solid #1e4654. On check: face background shifts subtly warmer: `linear-gradient(#2a2030,#1a1226)`? Maybe shift border color to a coral tint: border-color: #7e2f42. Add transition .4s. And glow: box-shadow with 0 0 60px rgba(255,77,90,.25) added.
Hover: `.btn:hover{transform:translateY(-3px)}` but transform on label conflicts with kick animation (animation overrides transform while playing). Fine.
`.btn:hover .heart{ fill/stroke hover tint }` when unchecked: stroke #8fb4bb → hover #ffd7dd.
Also `#like:checked ~ .scene .btn:hover .heart{}` not needed.
Active squish on svg via a class transform without an animation: `.btn:active .heart{ transform: scale(.8) }` with a .heart transition transform .18s — but when checked, the heart-pop animation controls transform; while pressing during checked, animation still wins (animation overrides transition). Fine.
Idle pulse: `#like:not(:checked) ~ .scene .heart{ animation: idle 2.8s ease-in-out infinite; }` keyframes idle: 0,100 scale(1); 12% scale(1.07); 24% scale(1); 36% scale(1.04); 48% scale(1) — double heartbeat. Cute!
On initial load heart is gray outline pulsating — clearly inviting.
Stamp z-index above button, pointer-events none.
Sunburst element: inside .stage, `.pad{position:relative; display:grid; place-items:center;}` containing `.sunburst` absolute centered, size 540px, plus label. Stage children: stamp (absolute), pad, readout, hint.
Sunburst mask: `-webkit-mask: radial-gradient(closest-side, transparent 18%, #000 22%, #000 60%, transparent 68%);` and `mask:` same. Chrome supports both.
Repeating-conic ray gradient: `repeating-conic-gradient(from 0deg at 50% 50%, rgba(255,210,63,.10) 0deg 7deg, transparent 7deg 16deg)`.
Spin 90s.
Also add a faint orbit ring circle behind the button: `.pad::before` dashed circle 260px, rotate slowly opposite — extra layer.
Also small "confetti at rest"? No.
OK let me write the final. Also `body{display:block}`, scene max-width etc.
Font stacks:
--disp: 'Avenir Next Condensed','Franklin Gothic Medium','Arial Narrow',Impact,'Segoe UI',sans-serif;
--body: 'Avenir Next','Segoe UI',system-ui,-apple-system,sans-serif;
--mono: ui-monospace,'SF Mono','Cascadia Code','JetBrains Mono',Consolas,monospace;
Heading letter-spacing slightly tight -0.01em; tags letter-spacing .2em.
Media queries:
- max-width 980: grid 1 col; stage order 2; copy margin; maybe center? Keep left. Hide third top tag. Reduce sunburst to 420px.
- max-width 560: btn 124px; face 108; heart 30; reduce readout gap, wrap; keep ticker; stamp font 40; shrink specs (grid 1 col? keep but smaller); h1 clamp handles.
At 375 ensure no overflow: particle distances ~140px from center → 280px spread, fits within 375 if centered (button centered, margin 188-140=48px). OK. Stamp width auto fits.
Body overflow-x hidden; scene overflow hidden too.
svh support: use `min-height:100vh; min-height:100svh;`.
Grid main: `flex:1; display:grid; align-content:center;` scene as flex column: header, main (flex1 grid), ticker at bottom (static, part of flex column) — ticker static at bottom, no fixed overlay. Scene min-height 100svh, display flex column. Main flex:1 display grid align-items center. Good.
Let me write.
Also add a small easter egg on unclick? The status stack's b text is "LIKED ♥" and hint's b is "NICE. AGAIN? AGAIN.".
Ensure `i` elements are display block / inline-block as needed.
`.vh` class: position:absolute; width:1px;height:1px; margin:-1px; clip-path: inset(50%); overflow:hidden; white-space:nowrap.
Also for the label default `tabindex` not needed; input focusable, label click works.
Also `body:has(#like:checked){ --glow: ... }` might not be needed; do the background shift on .scene: `#like:checked ~ .scene{ background-color:#0d2d3a }`? Scene background is multiple layers; simplest: `.tint` overlay div with opacity 0→1 transition: radial warm glow behind stage: `background: radial-gradient(600px 500px at 68% 45%, rgba(255,77,90,.14), transparent 70%)`. Place `.tint` in scene; opacity transition .5s. Also brighten sunburst: `#like:checked ~ .scene .sunburst{opacity:1}`, default .55, transition .6s.
Final check for the animation re-trigger concern: after unchecking, all the burst selectors no longer match → animations removed; even after re-check, the same selector matches again → browser restarts animation. Yes, this is standard behavior for these CSS-only buttons.
One more: `.btn` kick animation sets transform; `.btn:hover` transform translateY — during kick animation hover transform ignored; fine.
Let me write the code with attention to syntax. No <script> at all. Ensure the html code block language.