The fireball sets the bar, and the rest of the catalog rises to it

Eric's fireball lands as the house style — layered construction,
gradient core, glow halo, a directional tail riding rotate="auto" —
with its defs scoped per instance via $props.id(), so simultaneous
fireballs cannot steal each other's gradients. The rest of the
catalog is rebuilt in its image: the waterbolt becomes its cold
sibling (spray tail, no turbulence — one heavy filter stack is
enough); lightning grows a glowing core and branching forks; the
burst blooms through a fire gradient with a shockwave and flying
embers; the splash throws a crown of droplets; the shield raises a
gradient dome with a rim strike; the pow star flashes white and
radiates speed dashes; claws leave tapered gashes; the absorbed card
spirals in along a pull ring; the soul is a proper little ghost with
eyes, swaying as it rises; fireworks ride colored trails; Chaos
catches card slips in its vortex; the pit opens a gradient hole that
swallows a faller; ooze splats and flings blobs; the thornbush sheds
leaves; slime closes over and pops bubbles; masonry dust goes soft
with falling grit. Whiff, tacks, portal, and the sector ghosts keep
their simpler forms on purpose — restraint is part of the style.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-17 10:16:01 -04:00
co-authored by Claude Fable 5
parent fe0318b99b
commit 308f1b6ff9
19 changed files with 688 additions and 167 deletions
+14 -4
View File
@@ -1,26 +1,36 @@
<script lang="ts">
import type { FxOf } from "../fx";
import { center } from "./geom";
let { fx }: { fx: FxOf<"thorn-snap"> } = $props();
const c = $derived(center(fx.at));
</script>
<path class="thorn"
<path class="thorn" style={`transform-origin: ${c.x}px ${c.y}px`}
d={`M ${c.x - 12} ${c.y} l 6 -4 2 -8 4 6 8 -4 -3 8 7 5 -9 1 -2 9 -5 -7 -8 2 z`} />
<g class="leaves">
<ellipse cx={c.x - 12} cy={c.y - 10} rx="3" ry="1.6" class="leaf" transform={`rotate(-30 ${c.x - 12} ${c.y - 10})`} />
<ellipse cx={c.x + 13} cy={c.y - 8} rx="2.6" ry="1.4" class="leaf late" transform={`rotate(40 ${c.x + 13} ${c.y - 8})`} />
</g>
<style>
.thorn {
fill: rgba(70, 120, 50, 0.7);
fill: rgba(70, 120, 50, 0.75);
stroke: #2f5423;
stroke-width: 1.5;
transform-box: fill-box;
transform-origin: center;
animation: snap 0.55s ease-out forwards;
}
.leaf { fill: #7fae55; animation: leaf-fall 0.7s ease-in 0.1s forwards; opacity: 0; }
.leaf.late { animation-delay: 0.18s; }
@keyframes snap {
0% { opacity: 0; transform: scale(0.3) rotate(-15deg); }
25% { opacity: 1; transform: scale(1.25) rotate(5deg); }
55% { transform: scale(1) rotate(0deg); }
100% { opacity: 0; transform: scale(1.05); }
}
@keyframes leaf-fall {
0% { opacity: 0; transform: translateY(0) rotate(0deg); }
25% { opacity: 0.9; }
100% { opacity: 0; transform: translateY(10px) rotate(50deg); }
}
</style>