diff --git a/src/_includes/system-override.njk b/src/_includes/system-override.njk index a2de958..ac76407 100644 --- a/src/_includes/system-override.njk +++ b/src/_includes/system-override.njk @@ -17,9 +17,10 @@ - diff --git a/src/assets/css/style.css b/src/assets/css/style.css index 6655fa0..3bdf775 100644 --- a/src/assets/css/style.css +++ b/src/assets/css/style.css @@ -534,22 +534,6 @@ body[data-level="6"]::after { } } -/* The Active Class */ -.force-glow { - --glow-color: #38bdf8; /* Default Jedi Blue */ - position: relative; - z-index: 10; - transition: all 0.5s ease; - animation: force-pulse 10s infinite ease-in-out; -} - -/* Sith Variant (Red Glow) */ -[data-level^="13"], -[data-level^="14"], -[data-level^="15"] .force-glow { - --glow-color: #ef4444; /* Sith Red */ -} - /* Ensure the parent container has a background so you can see the 'empty' part */ #game-stats .bg-black\/10 { background-color: rgba(0, 0, 0, 0.1) !important; @@ -873,3 +857,58 @@ a:hover { #matrix-console-container.is-dragging { user-select: none; } + +/* Full-screen Force Field */ +.force-field-overlay { + position: fixed !important; + inset: 0 !important; + z-index: 999999 !important; + background: radial-gradient( + circle, + rgba(0, 150, 255, 0.1) 0%, + rgba(0, 0, 50, 0.6) 100% + ); + pointer-events: none; + box-shadow: inset 0 0 150px rgba(0, 190, 255, 0.5); + backdrop-filter: blur(2px) contrast(1.2); + animation: force-throb 4s ease-in-out infinite; +} + +@keyframes force-throb { + 0%, + 100% { + opacity: 0.7; + } + 50% { + opacity: 1; + } +} + +/* Bright Lightning Arcs */ +.lightning-flash { + position: fixed; + inset: 0; + z-index: 1000000; + pointer-events: none; + background: white; + opacity: 0; +} + +@keyframes bolt { + 0% { + opacity: 0; + } + 10% { + opacity: 1; + background: #99f6ff; + } + 20% { + opacity: 0; + } + 25% { + opacity: 0.8; + } + 30% { + opacity: 0; + } +} diff --git a/src/assets/js/script.js b/src/assets/js/script.js index 4acf338..2815b4b 100644 --- a/src/assets/js/script.js +++ b/src/assets/js/script.js @@ -369,17 +369,82 @@ function updateThemeIcon(theme) { /** * 5. EASTER EGG LOGIC & TRIGGERS */ -function triggerForceSurge() { - if (isSurging) return; // Prevent overlapping surges +function playForceSoundtrack(duration = 8000) { + initAudio(); + if (!audioCtx) return; + + // 1. Create a Master Compressor to prevent distortion + const compressor = audioCtx.createDynamicsCompressor(); + compressor.threshold.setValueAtTime(-24, audioCtx.currentTime); + compressor.knee.setValueAtTime(40, audioCtx.currentTime); + compressor.ratio.setValueAtTime(12, audioCtx.currentTime); + compressor.attack.setValueAtTime(0, audioCtx.currentTime); + compressor.release.setValueAtTime(0.25, audioCtx.currentTime); + compressor.connect(audioCtx.destination); + + const now = audioCtx.currentTime; + const masterGain = audioCtx.createGain(); + masterGain.connect(compressor); + + // Smooth volume swell + masterGain.gain.setValueAtTime(0, now); + masterGain.gain.linearRampToValueAtTime(0.6, now + 1.5); + masterGain.gain.setValueAtTime(0.6, now + duration / 1000 - 2); + masterGain.gain.exponentialRampToValueAtTime(0.001, now + duration / 1000); + + // Create the "Harmonic Stack" (Multiple notes for a rich sound) + [55, 110, 164.81].forEach((freq, i) => { + const osc = audioCtx.createOscillator(); + osc.type = i === 0 ? "sawtooth" : "triangle"; // Mix textures + osc.frequency.setValueAtTime(freq, now); + + // Add a slight "wobble" (detune) for realism + osc.detune.setValueAtTime(i * 5, now); + osc.connect(masterGain); + osc.start(now); + osc.stop(now + duration / 1000); + }); +} + +function triggerForceSurge() { + if (isSurging) return; isSurging = true; - initAudio(); - addExperience(1000); - // Reset after the animation duration (e.g., 1 second) + // 1. Audio + playForceSoundtrack(8000); + + // 2. Add Overlay + const overlay = document.createElement("div"); + overlay.className = "force-field-overlay"; + document.body.appendChild(overlay); + + // 3. Lightning Bolts (Flash every 1.5 seconds) + const flash = document.createElement("div"); + flash.className = "lightning-flash"; + document.body.appendChild(flash); + + const boltInterval = setInterval(() => { + flash.style.animation = "none"; + void flash.offsetWidth; // Reset animation + flash.style.animation = "bolt 0.4s ease-out"; + }, 1800); + + // 4. XP Logic + let currentXPAdded = 0; + const xpInt = setInterval(() => { + addExperience(10); + currentXPAdded += 10; + if (currentXPAdded >= 1000) clearInterval(xpInt); + }, 50); + + // 5. Cleanup setTimeout(() => { + clearInterval(boltInterval); + overlay.remove(); + flash.remove(); isSurging = false; - }, 10000); + }, 8000); } function triggerMagicXP() {