Components / Motion / Burst Button
Burst Button beta
A real call-to-action that answers a click with a burst of sparks — feedback you can see from across the room.
It fires once when it arrives. After that, it answers clicks only.
<div style="display:flex;gap:26px;flex-wrap:wrap;align-items:center;padding:16px 6px"> <span class="k-burst" data-burst><canvas aria-hidden="true"></canvas><button class="k-burst-btn" type="button">Deploy to production</button></span> <span class="k-burst" data-burst><canvas aria-hidden="true"></canvas><button class="k-burst-btn teal" type="button">Publish the part</button></span> </div> <p style="font-size:12.5px;color:var(--k-ink-3)">It fires once when it arrives. After that, it answers clicks only.</p>
/* KATA Burst Button — a CTA with visible punctuation. */
.k-burst{position:relative;display:inline-block;font-family:var(--k-font)}
.k-burst canvas{position:absolute;inset:-70px -90px;width:calc(100% + 180px);height:calc(100% + 140px);pointer-events:none}
.k-burst-btn{position:relative;z-index:1;background:var(--k-ink);color:var(--k-bg);border:0;font-family:inherit;font-size:14.5px;font-weight:650;padding:13px 26px;border-radius:11px;cursor:pointer;transition:transform .12s}
.k-burst-btn:active{transform:scale(.96)}
.k-burst-btn.teal{background:var(--k-accent);color:var(--k-on-color)}
// KATA Burst Button — sparks from the point of the click.
document.querySelectorAll('[data-burst]').forEach(function (wrap) {
var canvas = wrap.querySelector('canvas');
var btn = wrap.querySelector('.k-burst-btn');
var ctx = canvas.getContext('2d');
var DPR = Math.min(3, window.devicePixelRatio || 1);
var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var cs = getComputedStyle(wrap);
var COLORS = ['--k-accent', '--k-ink', '--k-zinc-400'].map(function (v) { return cs.getPropertyValue(v).trim(); }).filter(Boolean);
var parts = [], raf = null, W = 0, H = 0;
function size() { W = wrap.offsetWidth + 180; H = wrap.offsetHeight + 140; canvas.width = W * DPR; canvas.height = H * DPR; ctx.setTransform(DPR, 0, 0, DPR, 0, 0); }
function fire(cx, cy) {
if (reduced) return;
size();
var r = wrap.getBoundingClientRect();
var ox = cx != null ? cx - r.left + 90 : W / 2;
var oy = cy != null ? cy - r.top + 70 : H / 2;
for (var i = 0; i < 30; i++) {
var a = Math.PI * 2 * Math.random();
var sp = 1.4 + Math.random() * 4.4;
parts.push({ x: ox, y: oy, vx: Math.cos(a) * sp, vy: Math.sin(a) * sp - .8, life: 1, c: COLORS[i % COLORS.length], s: 2 + Math.random() * 2.6 });
}
if (!raf) tick();
}
function tick() {
ctx.clearRect(0, 0, W, H);
parts = parts.filter(function (p) { return p.life > 0; });
parts.forEach(function (p) {
p.vy += .11; p.vx *= .985; p.vy *= .985;
p.x += p.vx; p.y += p.vy; p.life -= .02;
ctx.globalAlpha = Math.max(0, p.life);
ctx.fillStyle = p.c;
ctx.beginPath(); ctx.arc(p.x, p.y, p.s, 0, 7); ctx.fill();
});
ctx.globalAlpha = 1;
raf = parts.length ? requestAnimationFrame(tick) : null;
}
btn.addEventListener('click', function (e) { fire(e.clientX, e.clientY); });
if ('IntersectionObserver' in window && !reduced) {
var io = new IntersectionObserver(function (es) { if (es[0].isIntersecting) { setTimeout(function () { fire(); }, 450); io.disconnect(); } }, { threshold: .6 });
io.observe(wrap);
}
size();
});
Installation
CLI
node kata-ui.mjs add burst-button
Writes the part’s CSS and JS into your project. New to the CLI? See the CLI doc.
Manual
- Load
tokens.cssonce, before any part. - Copy the CSS tab into your stylesheet.
- Copy the HTML where it belongs. The part has a script — include it after the markup; it initializes itself.
Usage
The button is an ordinary primary button; the burst is its click feedback, fired from the exact point of the click, in the token palette. Use it on the one action a page exists for — deploy, purchase, publish. A burst on every button is a fireworks stall; a burst on the button is punctuation.
Accessibility
The click still does its job with the script removed, and the burst is aria-hidden canvas. Under prefers-reduced-motion there is no burst — the button relies on its pressed state like its ancestors, which is sufficient because it is, first, a button.
Anatomy
The public surface of this part, read from its own source. Class names are the API — the CSS tab above is the full contract.
.k-burst | class |
.k-burst-btn | class |
.teal | class |
data-burst | data hook |
aria-hidden | ARIA |
Related parts
Accordion Gallery beta
Five scenes in a row; the one you touch opens up and tells its caption.
Aurora beta
A slow wash of color behind a hero — the accent and the core, drifting under glass.
Beam border beta
A single point of light travels the edge of a card. The beam is the core color — the one accent, in motion.
Blur In beta
Words arrive out of focus and sharpen one after another, like eyes adjusting.