A credential or status badge held aloft by drifting sparks that rise on curl-noise paths, glow and cool to ash, with a soft heat glow, a pointer lean and click bursts.

  • badge
  • pill
  • sparks
  • embers
  • particles
  • canvas
  • status
  • hover
Preset

Installation

pnpm dlx shadcn@latest add https://kagadmodyaa.vercel.app/r/ember-badge.json

Needs a React + Tailwind project set up with shadcn. Copies the effect into your project, along with lib/effect-runtime.ts, the small WebGL layer it runs on. No other dependencies.

Or from npm

pnpm add @kagadmodyaa/effects
import { EmberBadge } from '@kagadmodyaa/effects/ember-badge'

One package with every free effect, one import path each. No Tailwind or shadcn needed, and no stylesheet to import: the few layout rules an effect needs come with it. The npm package and the command above ship the same source.

Usage

Use it like any other component. Choose a theme with preset; any prop you pass as well overrides the preset.

import { EmberBadge } from '@/components/effects/ember-badge/ember-badge'

export function Hero() {
  return (
    <>
      <EmberBadge preset="Forge" size="lg">Early access</EmberBadge>
      <h1>Light the way for launch day</h1>

      {/* A link, a button, an inline credential */}
      <EmberBadge preset="Frost" href="/changelog" label="v2.0 shipped" />
      <EmberBadge preset="Aurora" onClick={() => openProfile()} label="Top 1% creator" />
      <p>Built by Mira <EmberBadge preset="Ink" size="sm" label="Founding member" /></p>
    </>
  )
}

// href makes it an <a>, onClick makes it a <button>, otherwise it is a <span>. Any normal prop works (ref, aria-*, id).
// The stage above is <EmberBadgeShowcase />, also exported, if you want the same scene.
<EmberBadge preset="Frost" label={"Early access"} />

Presets

  • Forge
  • Frost
  • Verdant
  • Ink
  • Aurora

Props

NameTypeDefaultDescription
preset'Forge' | 'Frost' | 'Verdant' | 'Ink' | 'Aurora'none (the defaults below)A named theme. Any prop you pass as well overrides the preset’s value.
label'Early access' | 'v2.0 shipped' | 'Top 1% creator' | 'Founding member' | 'Now in beta''Early access'The badge text, when you do not pass children. Always real text.
size'sm' | 'md' | 'lg''lg'sm 24px, md 30px or lg 38px tall.
finish'enamel' | 'glass' | 'outline''enamel'Lacquered metal rim, frosted glass or a gradient hairline.
dotbooleantrueShow the small glowing dot before the label.
tone'auto' | 'dark' | 'light''auto'Which surface the badge sits on. auto follows the page theme.
interactivebooleantrueHover lifts the fire and leans the sparks toward the pointer; a click releases a burst.
densitynumber1How many sparks are in the air. 0 leaves only the glow. Range 0 to 2.
riseSpeednumber1How fast sparks climb. Range 0.2 to 2.
turbulencenumber1How strongly the curl noise swirls them sideways. Range 0 to 2.
sparkSizenumber1Size of each spark and its halo. Range 0.5 to 2.
heatnumber1Strength of the soft light behind and around the badge. Range 0 to 1.5.
colorHotstring'#fff2d9'A fresh spark's core. A hex colour.
colorAstring'#ffab3d'Sparks as they cool; also the rim and glow colour. A hex colour.
colorBstring'#d9361c'Sparks just before they turn to ash. A hex colour.
badgeColorstring'#3a170f'Enamel colour (and the tint of glass and outline). A hex colour.
hueSpreadnumber0How far each spark's hue may wander from the palette. 0 keeps one hue. Range 0 to 1.
lightSparks'vivid' | 'ink''vivid'Sparks on a light surface: keep the palette, or draw dark ink sparks.
classNamestring—Extra class on the root element. The effect fills its parent: give the parent a height.
styleCSSProperties—Inline style on the root element.

Files

What the command adds to your project, and where.

  • components/effects/ember-badge/ember-badge.tsx

    The component.

  • components/effects/ember-badge/badge.tsx

    The component.

  • components/effects/ember-badge/showcase.tsx

    The component.

  • components/effects/ember-badge/engine.ts

    The component.

  • components/effects/ember-badge/styles.ts

    The component.

  • components/effects/ember-badge/stage-styles.ts

    The component.

  • lib/effect-runtime.ts

    Shared by every shader effect: resizing, pausing, reduced motion, context loss and the no-WebGL fallback. Installed once.

Behaviour

  • The badge is ordinary DOM text. With href it is an <a>, with onClick (or as="button") a <button>, otherwise a <span>. Links and buttons get a focus-visible ring and work from the keyboard.
  • Sparks are drawn on a Canvas2D layer behind the badge by one shared loop. It draws only badges near the viewport, sleeps in background tabs, and thins the sparks out automatically if frames run slow, so several badges on a page stay cheap.
  • Hovering lifts the fire and leans the sparks toward the pointer; keyboard focus lifts it too. A click (or Enter / Space) releases a burst. interactive={false} turns all of that off.
  • Under prefers-reduced-motion the sparks freeze in one still frame, the heat glow stops breathing and the dot stops pulsing. Nothing moves and bursts are skipped.
  • Tone is 'auto' by default: it follows a dark or light class on <html> (or the OS setting). On light pages sparks switch from additive light to inked, normally blended sparks; the Ink preset draws dark sparks there.
  • The spark canvas reaches out around the badge but never widens the page: it is clamped to the viewport and ignores the pointer.

See all effects