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 @@
+
{% 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) }}"