diff --git a/frontend/src/lib/cybersigil.ts b/frontend/src/lib/cybersigil.ts index 1147078..490ec00 100644 --- a/frontend/src/lib/cybersigil.ts +++ b/frontend/src/lib/cybersigil.ts @@ -198,6 +198,20 @@ export function buildCybersigil(opts: SigilOptions = {}): string { } emit(spline(spinePts), 'cs-sig-main'); + // ── Terminal spike crown: long, straight, downward-converging needles + // off the spine tail — the dripping barbed point that ends the growth. + const tip = spinePts[spinePts.length - 1]; + const fan = 5 + Math.floor(rng() * 4); // 5–8 + for (let s = 0; s < fan; s++) { + const spread = (s / (fan - 1) - 0.5) * 1.5; // ~±0.75 rad around straight-down + const a = Math.PI / 2 + spread; // π/2 = +y (down) + const len = rnd(46, 78) * (1 - Math.abs(spread) * 0.35); // center longest + const base: Pt = [tip[0], tip[1] - rnd(0, 8)]; + const tt: Pt = [base[0] + Math.cos(a) * len, base[1] + Math.sin(a) * len]; + emit(`M${n(base[0])} ${n(base[1])}L${n(tt[0])} ${n(tt[1])}`, 'cs-sig-barb'); + track(tt[0]); + } + // ── Branch nodes ride the spine and throw limbs outward. Nodes are // inset from the very ends and spread the full height so growth flows // down the whole trunk rather than clumping at the top. @@ -212,13 +226,15 @@ export function buildCybersigil(opts: SigilOptions = {}): string { const node: Pt = [a[0] + (b[0] - a[0]) * sf, a[1] + (b[1] - a[1]) * sf]; // later nodes lean downward so the lower trunk fills out const bias = -0.25 + tc * 0.7; + // spike gradient: lower trunk grows longer, sharper barbs + const spike = 1 + tc * 1.4; // 1× top → ~2.3× bottom const limbs = 1 + Math.floor(rng() * 2); for (let l = 0; l < limbs; l++) { const ang = bias + rnd(-0.55, 0.55); - limb(node[0], node[1], ang, rnd(0.65, 1.05), 1); + limb(node[0], node[1], ang, rnd(0.65, 1.05) * (0.8 + tc * 0.5), 1); } // the odd bare barb straight off the spine keeps the trunk prickly - if (rng() < 0.55) barb(node, bias + rnd(-0.3, 0.3), rnd(7, 14)); + if (rng() < 0.55) barb(node, bias + rnd(-0.3, 0.3), rnd(7, 14) * spike); } const half = parts.join('');