diff --git a/src/script.js b/src/script.js index bc67533..0c33963 100644 --- a/src/script.js +++ b/src/script.js @@ -178,8 +178,7 @@ function createServerRack() { activeTerminal = terminal; - terminal.addEventListener('click', (e) => { - e.stopPropagation(); + terminal.addEventListener('click', () => { mobileInput.focus(); }); @@ -529,12 +528,42 @@ function createServerRack() { mobileInput.focus(); terminal.style.boxShadow = '0 0 8px rgba(234, 179, 8, 0.3), inset 0 0 20px rgba(34, 197, 94, 0.1)'; terminal.style.borderColor = '#eab308'; + terminal.classList.add('grown'); + const face = terminal.closest('.server-face'); + const unit = face?.closest('.rack-unit'); + face?.classList.add('grown'); + unit?.classList.add('grown'); + document.getElementById('hero').classList.add('shifted'); }); terminal.addEventListener('blur', () => { + if (heroMouseDown) return; terminal.style.boxShadow = ''; terminal.style.borderColor = '#2a2a2e'; - mobileInput.blur(); + terminal.classList.remove('grown'); + const face = terminal.closest('.server-face'); + const unit = face?.closest('.rack-unit'); + face?.classList.remove('grown'); + unit?.classList.remove('grown'); + document.getElementById('hero').classList.remove('shifted'); + }); + + mobileInput.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + mobileInput.blur(); + } + }); + + mobileInput.addEventListener('blur', () => { + if (heroMouseDown) return; + terminal.style.boxShadow = ''; + terminal.style.borderColor = '#2a2a2e'; + terminal.classList.remove('grown'); + const face = terminal.closest('.server-face'); + const unit = face?.closest('.rack-unit'); + face?.classList.remove('grown'); + unit?.classList.remove('grown'); + document.getElementById('hero').classList.remove('shifted'); }); let lastInputValue = ''; @@ -737,10 +766,32 @@ function createServerRack() { let activeTerminal = null; createServerRack(); -document.getElementById('hero').addEventListener('click', (e) => { +const heroEl = document.getElementById('hero'); +let heroMouseDown = false; + +heroEl.addEventListener('mousedown', () => { heroMouseDown = true; }); +heroEl.addEventListener('mouseup', () => { heroMouseDown = false; }); + +heroEl.addEventListener('click', (e) => { if (e.target.closest('.btn')) return; if (activeTerminal && activeTerminal._mobileInput) { - activeTerminal._mobileInput.focus(); + if (activeTerminal.classList.contains('grown')) { + activeTerminal.classList.remove('grown'); + const face = activeTerminal.closest('.server-face'); + const unit = face?.closest('.rack-unit'); + face?.classList.remove('grown'); + unit?.classList.remove('grown'); + heroEl.classList.remove('shifted'); + activeTerminal._mobileInput.blur(); + } else { + activeTerminal._mobileInput.focus(); + activeTerminal.classList.add('grown'); + const face = activeTerminal.closest('.server-face'); + const unit = face?.closest('.rack-unit'); + face?.classList.add('grown'); + unit?.classList.add('grown'); + heroEl.classList.add('shifted'); + } } }); @@ -823,6 +874,9 @@ function checkAchievements(cmdText, isRoot) { achieved.push(key); newAchievements.push(achievement); } else if (achievement.prefix ? cmdText.startsWith(achievement.cmd) : achievement.cmd === cmdText) { + if ((key === 'nice_try' && isRoot) || (key === 'restore_backup' && !isRoot)) { + continue; + } achieved.push(key); newAchievements.push(achievement); } diff --git a/src/style.css b/src/style.css index beb4dda..6c68e0c 100644 --- a/src/style.css +++ b/src/style.css @@ -201,7 +201,25 @@ body { position: relative; overflow: hidden; cursor: text; - z-index: 2; + transition: height 0.5s cubic-bezier(0.16, 1, 0.3, 1); +} + +.terminal-display.grown { + height: calc(100% - 4px); +} + +.server-face { + transition: height 0.5s cubic-bezier(0.16, 1, 0.3, 1); +} + +.rack-unit { + transition: max-height 0.5s cubic-bezier(0.16, 1, 0.3, 1); + max-height: 90px; + overflow: visible; +} + +.rack-unit.grown { + max-height: 500px; } .terminal-display::before { @@ -279,6 +297,7 @@ body { .rack-unit { width: 100%; + max-height: 90px; height: 90px; background: linear-gradient(180deg, #1a1a1f 0%, #151518 100%); border: 1px solid #2a2a30; @@ -290,6 +309,13 @@ body { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03), 0 2px 8px rgba(0, 0, 0, 0.4); + overflow: visible; + transition: height 0.5s cubic-bezier(0.16, 1, 0.3, 1), max-height 0.5s cubic-bezier(0.16, 1, 0.3, 1); +} + +.rack-unit.grown { + height: 290px; + max-height: none; } .rack-unit::before { @@ -353,7 +379,7 @@ body { align-items: center; justify-content: center; position: relative; - overflow: hidden; + overflow: visible; } .server-drive-bay { @@ -745,6 +771,12 @@ nav .nav-inner { justify-content: center; padding: 6rem 2rem 4rem; position: relative; + z-index: 10; + transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1); +} + +.hero.shifted { + transform: translateY(400px); } .hero-content {