diff --git a/src/_includes/footer.njk b/src/_includes/footer.njk index 1b350ac7..71de0b1b 100644 --- a/src/_includes/footer.njk +++ b/src/_includes/footer.njk @@ -79,6 +79,14 @@ +
+ +
+
+

Secret Console: 'D'

diff --git a/src/_includes/header.njk b/src/_includes/header.njk index 4c7b52f5..3612dbe7 100644 --- a/src/_includes/header.njk +++ b/src/_includes/header.njk @@ -35,7 +35,7 @@
{% if page.url == "/" %} {% endif %} diff --git a/src/assets/css/style.css b/src/assets/css/style.css index 48d22e1c..04d2193f 100644 --- a/src/assets/css/style.css +++ b/src/assets/css/style.css @@ -1,5 +1,5 @@ /** - * 1. THEME VARIABLES + * 1. THEME VARIABLES & CORE RESET */ :root { --bg-page: #f8fafc; @@ -8,8 +8,10 @@ --text-main: #0f172a; --text-muted: #64748b; --border-color: #e2e8f0; - --accent: #4f46e5; - --accent-rgb: 79, 70, 229; + --accent: #2563eb; + --accent-light: #dbeafe; + --accent-rgb: 37, 99, 235; + --danger: #ef4444; } .dark { @@ -19,16 +21,12 @@ --text-main: #f8fafc; --text-muted: #94a3b8; --border-color: #1e293b; - --accent: #818cf8; - --accent-rgb: 129, 140, 248; + --accent: #60a5fa; + --accent-light: rgba(96, 165, 250, 0.15); } -/** - * 2. BASE STYLES & STICKY FIXES - */ html, body { - overflow-x: clip; /* Important: prevents sticky break and horizontal scroll */ - height: auto; + overflow-x: clip; min-height: 100%; background-color: var(--bg-page); color: var(--text-main); @@ -37,201 +35,248 @@ html, body { } /** - * 3. STICKY HEADER + * 2. USER CARDS & BLUE LEGIBILITY */ -header { - position: -webkit-sticky; - position: sticky; - top: 0; - width: 100%; - z-index: 100; - background-color: var(--bg-page); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border-bottom: 2px solid var(--border-color); - box-sizing: border-box; +.user-card h2 { + color: #1e40af !important; + font-weight: 800; + transition: all 0.3s ease; } -h1 { - line-height: 0.85; - text-shadow: 2px 2px 0px transparent; +.dark .user-card h2 { + color: #60a5fa !important; } -.dark h1 { - text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.3); +.user-card:hover h2 { + color: var(--accent) !important; + transform: translateX(4px); } /** - * 4. CARD STYLES + * 3. PILL-SHAPED INTERACTIVES (SKILLS & SURPRISE) */ -.user-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), - border-color 0.3s ease, - box-shadow 0.3s ease; +.skill-item { + position: relative; + overflow: hidden; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.4rem; + padding: 0.4rem 0.9rem; + background-color: var(--accent-light) !important; + color: var(--accent) !important; + border: 1px solid rgba(var(--accent-rgb), 0.2); + border-radius: 9999px; + font-size: 0.7rem; + font-weight: 800; + text-transform: uppercase; + transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + line-height: 1; } -.user-card:hover { - border-color: var(--accent); - box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); +.skill-item:hover { + background-color: var(--accent) !important; + color: #ffffff !important; + transform: translateY(-3px) scale(1.05); + box-shadow: 0 4px 12px rgba(var(--accent-rgb), 0.4); } -.card-footer { - background-color: var(--bg-footer); - border-top: 1px solid var(--border-color); +.surprise-btn { + background-color: var(--accent) !important; + color: #ffffff !important; + display: inline-flex !important; + align-items: center; + justify-content: center; + border-radius: 9999px; + font-weight: 900; + box-shadow: 0 4px 20px rgba(var(--accent-rgb), 0.4); + transition: 0.3s; } -/** - * 5. GAME & UTILITY - */ -.text-accent { color: var(--accent); } -.bg-accent { background-color: var(--accent); } - -#game-stats { transition: all 0.3s ease; } -#level-progress { box-shadow: 0 0 8px var(--accent); } - -/** - * 6. ANIMATIONS - */ - -/* Konami Barrel Roll - Applied to HTML */ -.konami-roll { - transition: transform 2s cubic-bezier(0.65, 0, 0.35, 1); - transform: rotate(360deg); - transform-style: preserve-3d; - pointer-events: none; +.surprise-btn:hover { + filter: brightness(1.1); + box-shadow: 0 8px 30px rgba(var(--accent-rgb), 0.6); + transform: translateY(-2px); } -/* Fix sticky header jitter during rotation */ -header { - backface-visibility: hidden; - transform: translateZ(0); +.surprise-btn::after, .skill-item:hover::after { + content: ''; + position: absolute; + top: -50%; left: -50%; width: 200%; height: 200%; + background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent); + transform: rotate(45deg); + transition: 0.5s; } +.surprise-btn:hover::after, .skill-item:hover::after { left: 120%; } -/* Matrix Overlay */ -#matrix-overlay { - background-color: black; - z-index: 9999 !important; +/** + * 4. DEVELOPER TOOLS & SELF DESTRUCT + */ +#dev-tools { + backdrop-filter: blur(20px); + background-color: rgba(15, 23, 42, 0.95); + border: 2px solid var(--accent); + padding: 1.5rem; + border-radius: 1rem; } -#matrix-canvas { - display: block; - position: fixed; - top: 0; - left: 0; +#dev-tools button { + font-family: 'Courier New', monospace; + background: rgba(0, 0, 0, 0.4); + color: white; + display: flex; + justify-content: space-between; + width: 100%; + padding: 0.6rem 0.8rem; + margin-bottom: 0.5rem; + border-radius: 0.5rem; + border: 1px solid rgba(255, 255, 255, 0.1); + transition: 0.2s; + cursor: pointer; } -/* Surprise Me Pulse */ -@keyframes glow-pulse { - 0% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.4); opacity: 1; } - 70% { box-shadow: 0 0 0 20px rgba(var(--accent-rgb), 0); } - 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0); } +/* Console Neon Overrides */ +#dev-tools button[onclick*="matrix"] { color: #00ff41 !important; border-color: rgba(0, 255, 65, 0.4) !important; } +#dev-tools button[onclick*="konami"] { color: #ffcc00 !important; border-color: rgba(255, 204, 0, 0.4) !important; } +#dev-tools button[onclick*="gravity"] { color: #ff3333 !important; border-color: rgba(255, 51, 51, 0.4) !important; } +#dev-tools button[onclick*="badge_click"] { color: #bc13fe !important; border-color: rgba(188, 19, 254, 0.4) !important; } +#dev-tools button[onclick*="resetPlayer"] { color: #f97316 !important; border-color: rgba(249, 115, 22, 0.4) !important; } + +/* Animated Self Destruct Styling */ +#dev-tools button[onclick*="selfDestruct"] { + color: #ef4444 !important; + border-color: rgba(239, 68, 68, 0.4) !important; + font-weight: 900; } -.highlight-pulse { - animation: glow-pulse 2s infinite; - transform: translateY(-8px); - border-color: var(--accent) !important; +#dev-tools button[onclick*="selfDestruct"].is-destructing { + background: linear-gradient(270deg, #2563eb, #f97316, #ef4444) !important; + background-size: 400% 400% !important; + animation: heat-up 2s ease infinite !important; + color: white !important; + border-color: white !important; } -/* Level Up Popups */ -.fixed.top-24 { - margin-top: 1.5rem; - z-index: 10000; -} +#dev-tools button::after { opacity: 0; transition: 0.3s; } +#dev-tools button[onclick*="resetPlayer"]::after { content: '🔄'; } +#dev-tools button[onclick*="selfDestruct"]::after { content: '💣'; } +#dev-tools button:hover::after { opacity: 1; margin-left: 10px; } -footer { - background-color: var(--bg-footer); - border-top: 1px solid var(--border-color); - color: var(--text-muted); - transition: background-color 0.4s ease; +#dev-tools button:hover { + background: rgba(255, 255, 255, 0.1); + box-shadow: 0 0 15px currentColor; + transform: translateX(4px); } -#footer-heart { - display: inline-block; - transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); +/** + * 5. ANIMATIONS & GAME SYSTEMS + */ +@keyframes heat-up { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } } -/* Add this class via JS if you want it to bounce on change */ -.heart-pop { - animation: pop 0.4s ease-out; +@keyframes violent-shake { + 0%, 100% { transform: translate(0, 0); } + 25% { transform: translate(3px, -3px); } + 50% { transform: translate(-3px, 3px); } } -@keyframes pop { - 0% { transform: scale(1); } - 50% { transform: scale(1.4); } - 100% { transform: scale(1); } +#level-progress { box-shadow: 0 0 10px var(--accent); transition: width 1s ease; } +.glitch-shake { animation: violent-shake 0.1s infinite; overflow: hidden; } + +#repair-btn { + background-color: var(--danger) !important; + color: #fff !important; + border: 4px solid #fff; + border-radius: 9999px; + padding: 1.5rem 3rem; + font-weight: 900; + box-shadow: 0 0 60px rgba(239, 68, 68, 0.6); + z-index: 10001; } -@keyframes bounce { - 0%, 100% { transform: translateY(0) scale(1); } - 50% { transform: translateY(-10px) scale(1.1); } +/* Animation for the button background */ +#dev-tools button.is-destructing { + background: linear-gradient(270deg, #2563eb, #f97316, #ef4444) !important; + background-size: 400% 400% !important; + animation: heat-up 2s linear infinite !important; + color: white !important; + pointer-events: none; } -#level-badge.animate-bounce { - animation: bounce 0.6s ease-in-out; +/* High-Priority Console Stacking */ +#dev-tools { + z-index: 99999 !important; /* Above everything else */ + position: fixed !important; } -/** - * 7. ARCHITECT MODE & LEVEL GLOW - */ +/* Loading Bar Styling */ +/* Jitter effect for the last 2 seconds */ -/* Glowing effect for the Level Badge when reaching higher levels */ -#level-badge { - transition: all 0.5s ease; +.bar-jitter { + animation: jitter 0.1s infinite; } -/* Specific styling for when Level 10 (Architect) is reached */ -.level-architect #level-badge { - box-shadow: 0 0 20px var(--accent), 0 0 40px var(--accent); - animation: architect-pulse 2s infinite ease-in-out; +@keyframes jitter { + 0% { transform: translateX(0); } + 50% { transform: translateX(2px); filter: brightness(1.5); } + 100% { transform: translateX(-1px); } } -@keyframes architect-pulse { - 0%, 100% { filter: brightness(1) drop-shadow(0 0 5px var(--accent)); } - 50% { filter: brightness(1.3) drop-shadow(0 0 15px var(--accent)); } +/* Lock the dev tools during the countdown */ +#dev-tools[data-lock="true"] { + display: block !important; + visibility: visible !important; + opacity: 1 !important; + z-index: 999999 !important; + position: fixed !important; + /* This stops the glitch-shake from moving the panel */ + transform: none !important; + pointer-events: auto !important; } -/* Intensify the progress bar at Level 10 */ -.level-architect #level-progress { - background: linear-gradient(90deg, var(--accent), #ffffff, var(--accent)); - background-size: 200% 100%; - animation: gradient-flow 2s linear infinite; +/* Ensure the progress bar is high-contrast */ +#destruct-bar-container { + width: 100%; + height: 14px; + background: #000; + border: 2px solid #333; + margin-top: 15px; + border-radius: 4px; } -@keyframes gradient-flow { - 0% { background-position: 100% 0%; } - 100% { background-position: -100% 0%; } +#destruct-bar-progress { + height: 100%; + width: 0%; + background: #22c55e; + transition: width 1s linear, background-color 0.3s; } -/** - * 8. DEVELOPER CONSOLE & UI UTILITIES - */ - -/* Glassmorphism for the Dev Tools */ -#dev-tools { - backdrop-filter: blur(16px) saturate(180%); - -webkit-backdrop-filter: blur(16px) saturate(180%); - background-color: rgba(15, 23, 42, 0.8); /* Slate-900 with transparency */ +/* Specific button styling during destruction */ +.is-destructing { + background: #ef4444 !important; + animation: pulse 0.5s infinite !important; + border: 2px solid white !important; } - -/* Glitch effect for the Gravity Trigger */ -.glitch-shake { - animation: glitch 0.2s infinite; -} - -@keyframes glitch { - 0% { transform: translate(0); } - 20% { transform: translate(-2px, 2px); } - 40% { transform: translate(-2px, -2px); } - 60% { transform: translate(2px, 2px); } - 80% { transform: translate(2px, -2px); } - 100% { transform: translate(0); } +/* This selector is extremely specific to override any other styles */ +html body #dev-tools[data-lock="true"] { + display: block !important; + visibility: visible !important; + opacity: 1 !important; + position: fixed !important; + top: 20px !important; + right: 20px !important; + z-index: 2147483647 !important; /* Maximum possible z-index */ + transform: none !important; /* Prevents gravity/shake from moving it */ + transition: none !important; /* Prevents fading out */ + pointer-events: auto !important; } -/* Utility to ensure the Matrix ESC button is always visible */ -#matrix-overlay button { - box-shadow: 0 0 20px rgba(0, 255, 0, 0.2); - text-shadow: 0 0 5px rgba(255, 255, 255, 0.5); +/* Ensure the progress bar is always visible inside the locked console */ +#dev-tools[data-lock="true"] #destruct-bar-container, +#dev-tools[data-lock="true"] #destruct-bar-progress { + visibility: visible !important; + opacity: 1 !important; } diff --git a/src/assets/js/script.js b/src/assets/js/script.js index 22e41d38..1260bdbc 100644 --- a/src/assets/js/script.js +++ b/src/assets/js/script.js @@ -264,11 +264,12 @@ let konamiPosition = 0; window.addEventListener('keydown', (e) => { const key = e.key.toLowerCase(); - // Developer Toggle if (key === 'd' && e.target.tagName !== 'INPUT') { const devPanel = document.getElementById('dev-tools'); if (devPanel) { const isHidden = devPanel.classList.toggle('hidden'); + // SAVE STATE: Store whether it's hidden or not + localStorage.setItem('devToolsVisible', !isHidden); playSound(isHidden ? 'click' : 'secret'); } return; @@ -370,24 +371,102 @@ function closeMatrix() { window.removeEventListener('keydown', handleMatrixEsc); } +let destructInterval; +/** + * SELF DESTRUCT ENGINE + * Forces console visibility and manages the dynamic loading bar + */ +window.startSelfDestruct = function() { + const btn = document.getElementById('self-destruct-btn'); + const devPanel = document.getElementById('dev-tools'); + + if (destructInterval) return; + + // 1. Move console to BODY to escape parent container collapses + document.body.appendChild(devPanel); + + // 2. Lock and Audio Resume + devPanel.setAttribute('data-lock', 'true'); + if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)(); + audioCtx.resume(); + + let barContainer = document.getElementById('destruct-bar-container') || createBar(btn); + const progressBar = document.getElementById('destruct-bar-progress'); + + btn.classList.add('is-destructing'); + let timeLeft = 10; + + destructInterval = setInterval(() => { + timeLeft--; + + // FORCE RE-CHECK (The 4-second fix) + devPanel.classList.remove('hidden'); + devPanel.style.display = 'block'; + + const progressPercent = ((10 - timeLeft) / 10) * 100; + progressBar.style.width = `${progressPercent}%`; + + // Color Change: Green -> Yellow -> Red + progressBar.style.backgroundColor = timeLeft > 5 ? "#22c55e" : (timeLeft > 2 ? "#eab308" : "#ef4444"); + + btn.innerHTML = `HALT SYSTEM IN ${timeLeft}s 💣`; + + // Sound Engine (scheduling precisely) + if (audioCtx) { + const osc = audioCtx.createOscillator(); + const gain = audioCtx.createGain(); + osc.connect(gain); gain.connect(audioCtx.destination); + osc.frequency.setValueAtTime(200 + (progressPercent * 10), audioCtx.currentTime); + gain.gain.setValueAtTime(0.1, audioCtx.currentTime); + gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.1); + osc.start(); osc.stop(audioCtx.currentTime + 0.1); + } + + if (timeLeft <= 4) { + document.body.classList.add('glitch-shake'); + } + + if (timeLeft <= 0) { + clearInterval(destructInterval); + destructInterval = null; + devPanel.setAttribute('data-lock', 'false'); // Finally release the lock + triggerSecretUnlock('gravity'); + } + }, 1000); +}; +// Internal helper to ensure bar exists +function createBar(btn) { + const container = document.createElement('div'); + container.id = 'destruct-bar-container'; + container.innerHTML = '
'; + btn.parentNode.insertBefore(container, btn.nextSibling); + return container; +} + document.addEventListener('DOMContentLoaded', () => { - // Secret: Triple-tap the copyright year in the footer to open Dev Tools on mobile + // 1. Restore Console Visibility + const devToolsVisible = localStorage.getItem('devToolsVisible') === 'true'; + const devPanel = document.getElementById('dev-tools'); + if (devToolsVisible && devPanel) { + devPanel.classList.remove('hidden'); + } + + // 2. Setup Mobile Override const footerYear = document.getElementById('current-year'); let tapCount = 0; - if (footerYear) { footerYear.addEventListener('touchstart', () => { tapCount++; if (tapCount === 3) { - const devPanel = document.getElementById('dev-tools'); devPanel.classList.toggle('hidden'); + localStorage.setItem('devToolsVisible', !devPanel.classList.contains('hidden')); playSound('secret'); tapCount = 0; } - // Reset count if they stop tapping for 1 second setTimeout(() => { tapCount = 0; }, 1000); }); } + applyTheme(localStorage.getItem('theme') || 'light'); updateGameUI(); }); diff --git a/src/index.njk b/src/index.njk index d9a54bd3..3be6d00f 100644 --- a/src/index.njk +++ b/src/index.njk @@ -32,9 +32,13 @@ layout: false
{% set skills = person.data.languages.split(' ') %} - {% for skill in skills %} - {{ skill }} - {% endfor %} +
+ {% for skill in skills %} + + {{ skill }} + + {% endfor %} +

"{{ person.data.bio | truncate(120) }}"