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
+30 -9
View File
@@ -1,23 +1,44 @@
<script lang="ts">
import type { FxOf } from "../fx";
import { center } from "./geom";
let { fx }: { fx: FxOf<"streak"> } = $props();
const uid = $props.id();
const a = $derived(center(fx.from));
const b = $derived(center(fx.to));
</script>
<line x1={a.x} y1={a.y} x2={b.x} y2={b.y} class="streak" />
<defs>
<linearGradient id={`streak-trail-${uid}`}
x1={a.x} y1={a.y} x2={b.x} y2={b.y} gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#e9e1cb" stop-opacity="0" />
<stop offset="0.7" stop-color="#e9e1cb" stop-opacity="0.6" />
<stop offset="1" stop-color="#fffdf0" stop-opacity="0.95" />
</linearGradient>
</defs>
<line x1={a.x} y1={a.y} x2={b.x} y2={b.y} stroke={`url(#streak-trail-${uid})`} class="trail" />
<circle cx={b.x} cy={b.y} r="5" class="head" />
<style>
.streak {
stroke: rgba(233, 225, 203, 0.85);
stroke-width: 5;
.trail {
stroke-width: 6;
stroke-linecap: round;
stroke-dasharray: 14 9;
animation: streak-fade 0.55s ease-out forwards;
animation: trail-fade 0.55s ease-out forwards;
}
@keyframes streak-fade {
0% { opacity: 0.9; stroke-dashoffset: 46; }
100% { opacity: 0; stroke-dashoffset: 0; }
.head {
transform-box: fill-box;
transform-origin: center;
fill: rgba(255, 253, 240, 0.9);
animation: head-land 0.45s ease-out forwards;
}
@keyframes trail-fade {
0% { opacity: 0.95; }
100% { opacity: 0; }
}
@keyframes head-land {
0% { opacity: 0; transform: scale(0.4); }
35% { opacity: 1; transform: scale(1.3); }
100% { opacity: 0; transform: scale(0.9); }
}
</style>