diff --git a/frontend/src/lib/cybersigil.ts b/frontend/src/lib/cybersigil.ts
index 2d697a2..795eec0 100644
--- a/frontend/src/lib/cybersigil.ts
+++ b/frontend/src/lib/cybersigil.ts
@@ -68,11 +68,28 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
const emit = (d: string, cls: string) => {
if (strokeCount >= MAX_PATHS) return;
parts.push(
- ``,
+ ``,
);
strokeCount++;
};
+ const emitText = (x: number, y: number, txt: string, cls: string) => {
+ parts.push(
+ `${txt}`,
+ );
+ strokeCount++;
+ };
+
+ const microFilaments = (at: Pt, ang: number) => {
+ const num = 5 + Math.floor(rng() * 5);
+ for (let i = 0; i < num; i++) {
+ const a = ang + rnd(-0.5, 0.5);
+ const l = rnd(2, 8);
+ const tip: Pt = [at[0] + Math.cos(a) * l, at[1] + Math.sin(a) * l];
+ emit(`M${n(at[0])} ${n(at[1])} L${n(tip[0])} ${n(tip[1])}`, 'cs-sig-micro');
+ }
+ };
+
// Catmull-Rom → cubic Bézier through an ordered point list (organic sweep).
const spline = (pts: Pt[], tension = 6): string => {
if (pts.length < 2) return '';
@@ -158,6 +175,7 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
// terminal spike off the outermost point
barb(peak, ang + rnd(-0.4, 0.4), scale * rnd(10, 22));
+ if (rng() < 0.3) microFilaments(peak, ang);
// denser filament shadows trailing the main sweep
const numFilaments = rng() < 0.5 ? 2 : 1;
@@ -282,6 +300,14 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
emit(`M${n(n1[0])} ${n(n1[1])} L${n(n2[0])} ${n(n2[1])}`, 'cs-sig-connect');
}
+ // ── Ghost Symbols: tiny technical fragments
+ const symbols = ['0x00', 'NULL', 'VOID', 'ERR', 'INIT', 'HALT', 'RECLAIM', 'DEAD'];
+ const numSymbols = 2 + Math.floor(rng() * 3);
+ for (let i = 0; i < numSymbols; i++) {
+ const pt = pick(nodePoints);
+ emitText(pt[0] + rnd(4, 12), pt[1] + rnd(-4, 4), pick(symbols), 'cs-sig-text');
+ }
+
const half = parts.join('');
const minX = -(maxX + PAD);
const vbW = 2 * (maxX + PAD);
@@ -289,6 +315,12 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
``
diff --git a/frontend/src/styles/partials/70-cybersigil.css b/frontend/src/styles/partials/70-cybersigil.css
index f7f317d..39b74be 100644
--- a/frontend/src/styles/partials/70-cybersigil.css
+++ b/frontend/src/styles/partials/70-cybersigil.css
@@ -248,6 +248,25 @@ html.cybersigil body::after {
opacity: 0.25;
}
+/* Micro-filaments */
+.cybersigil .cs-sig-micro {
+ stroke: var(--sky);
+ stroke-width: 0.1;
+ opacity: 0.3;
+}
+
+/* Ghost Symbols */
+.cybersigil .cs-sig-text {
+ fill: var(--sky);
+ font-family: var(--font-display);
+ font-size: 7px;
+ opacity: 0.45;
+ letter-spacing: 0.05em;
+ pointer-events: none;
+ filter: drop-shadow(0 0 1px var(--sky));
+ animation: cs-flicker 4s linear infinite;
+}
+
/* Stroke-weight tiers — heavy growth, hair filaments, prickly barbs, motifs. */
.cybersigil .cs-sigil .cs-sig-main { stroke-width: 2.8; }
.cybersigil .cs-sigil .cs-sig-spine {