From 0b24cfeeac7fbd6cf7e8de54a6c89d2c32a4c132 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Thu, 21 May 2026 05:02:44 +0200 Subject: [PATCH] update sigil --- frontend/src/components/CyberFx.astro | 41 +++++++++++++++++++ .../src/styles/partials/70-cybersigil.css | 25 ++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/CyberFx.astro b/frontend/src/components/CyberFx.astro index 2afe9f1..29124eb 100644 --- a/frontend/src/components/CyberFx.astro +++ b/frontend/src/components/CyberFx.astro @@ -103,6 +103,7 @@ const hudTL = fx.querySelector('.cs-hud--tl'); const hudTR = fx.querySelector('.cs-hud--tr'); + const hudBL = fx.querySelector('.cs-hud--bl'); const apply = () => { raf = 0; @@ -118,6 +119,46 @@ if (hudTL) hudTL.textContent = `0x${Math.floor(depth * 255).toString(16).toUpperCase().padStart(2, '0')} // ADDR`; if (hudTR) hudTR.textContent = `SYS.PTR // ${mx.toFixed(2)}, ${my.toFixed(2)}`; }; + + /* ─── Terminal Command Echo ─── */ + const onBtnClick = (e: MouseEvent) => { + const btn = (e.target as HTMLElement).closest('button, a.btn'); + if (!btn || !hudBL) return; + const label = btn.textContent?.trim().slice(0, 12).toUpperCase() || 'NULL'; + hudBL.textContent = `> CMD: [${label}] ... [OK]`; + hudBL.classList.remove('cs-hud-flicker'); + void hudBL.offsetWidth; + hudBL.classList.add('cs-hud-flicker'); + }; + window.addEventListener('click', onBtnClick); + off.push(() => window.removeEventListener('click', onBtnClick)); + + /* ─── Character Scramble ─── */ + const scrambleChars = '!@#$%^&*()_+{}:"<>?-=[];\',./'; + const onHover = (e: MouseEvent) => { + const el = (e.target as HTMLElement).closest('.font-display, .btn, .prose h1, .prose h2'); + if (!el || el.classList.contains('cs-is-scrambling')) return; + + const original = el.textContent || ''; + if (!original.trim()) return; + + el.classList.add('cs-is-scrambling'); + let iterations = 0; + const interval = setInterval(() => { + el.textContent = original.split('').map((char, index) => { + if (index < iterations) return original[index]; + return scrambleChars[Math.floor(Math.random() * scrambleChars.length)]; + }).join(''); + + if (iterations >= original.length) { + clearInterval(interval); + el.classList.remove('cs-is-scrambling'); + } + iterations += 1 / 3; + }, 30); + }; + window.addEventListener('mouseover', onHover); + off.push(() => window.removeEventListener('mouseover', onHover)); const schedule = () => { if (!raf) raf = requestAnimationFrame(apply); }; const onScroll = () => { diff --git a/frontend/src/styles/partials/70-cybersigil.css b/frontend/src/styles/partials/70-cybersigil.css index 815747a..b14e071 100644 --- a/frontend/src/styles/partials/70-cybersigil.css +++ b/frontend/src/styles/partials/70-cybersigil.css @@ -81,6 +81,24 @@ html.cybersigil body::after { .cybersigil .cs-hud--bl { bottom: 1.5rem; left: 1.5rem; } .cybersigil .cs-hud--br { bottom: 1.5rem; right: 1.5rem; } +.cs-hud-flicker { + animation: cs-flicker 0.4s steps(4) 1; +} + +/* Barbed Borders (Stitched Wire) */ +.cybersigil .plate, +.cybersigil .btn, +.cybersigil .glass { + border-image-source: url("data:image/svg+xml;utf8,"); + border-image-slice: 10; + border-image-repeat: stretch; +} +.cybersigil .plate:hover, +.cybersigil .btn:hover { + border-image-source: url("data:image/svg+xml;utf8,"); + animation: cs-flicker 0.2s infinite; +} + /* Boot Overlay */ .cybersigil .cs-boot { position: fixed; @@ -95,10 +113,12 @@ html.cybersigil body::after { } .cybersigil .cs-boot-log { font-family: var(--font-display); - font-size: 1.2rem; + font-size: clamp(0.9rem, 4vw, 1.2rem); color: var(--sky); line-height: 1.4; text-shadow: 0 0 8px var(--sky); + max-width: 90vw; + padding: 1rem; } .cybersigil .cs-boot-log p { overflow: hidden; @@ -113,7 +133,8 @@ html.cybersigil body::after { @keyframes cs-boot-fade { 0% { opacity: 1; visibility: visible; } - 100% { opacity: 0; visibility: hidden; } + 99% { opacity: 0; visibility: visible; } + 100% { opacity: 0; visibility: hidden; display: none; } } @keyframes cs-boot-type { to { width: 100%; }