Spaces:
Running
Running
Add 1 files
Browse files- index.html +87 -52
index.html
CHANGED
|
@@ -63,6 +63,12 @@
|
|
| 63 |
position: relative;
|
| 64 |
overflow: hidden;
|
| 65 |
box-shadow: 0 0 20px rgba(0, 255, 65, 0.3);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
}
|
| 67 |
|
| 68 |
#terminal::before {
|
|
@@ -180,10 +186,6 @@
|
|
| 180 |
color: var(--secondary);
|
| 181 |
}
|
| 182 |
|
| 183 |
-
.hidden {
|
| 184 |
-
display: none;
|
| 185 |
-
}
|
| 186 |
-
|
| 187 |
#start-screen {
|
| 188 |
position: fixed;
|
| 189 |
top: 0;
|
|
@@ -198,6 +200,12 @@
|
|
| 198 |
z-index: 200;
|
| 199 |
text-align: center;
|
| 200 |
pointer-events: all;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
}
|
| 202 |
|
| 203 |
#start-title {
|
|
@@ -248,6 +256,15 @@
|
|
| 248 |
transform: translateY(1px);
|
| 249 |
}
|
| 250 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
/* Scrollbar styling */
|
| 252 |
#output::-webkit-scrollbar {
|
| 253 |
width: 5px;
|
|
@@ -306,11 +323,11 @@
|
|
| 306 |
<button id="start-button">INITIALIZE SIMULATION</button>
|
| 307 |
</div>
|
| 308 |
|
| 309 |
-
<div id="terminal"
|
| 310 |
<div id="output"></div>
|
| 311 |
<div id="input-container">
|
| 312 |
<span id="prompt">></span>
|
| 313 |
-
<input type="text" id="input" autocomplete="off">
|
| 314 |
</div>
|
| 315 |
</div>
|
| 316 |
|
|
@@ -592,50 +609,54 @@
|
|
| 592 |
const startButton = document.getElementById('start-button');
|
| 593 |
const terminal = document.getElementById('terminal');
|
| 594 |
const output = document.getElementById('output');
|
| 595 |
-
const
|
| 596 |
const prompt = document.getElementById('prompt');
|
| 597 |
|
| 598 |
// Initialize game with enhanced effects
|
| 599 |
function initGame() {
|
|
|
|
|
|
|
|
|
|
| 600 |
// Disable button to prevent multiple clicks
|
| 601 |
startButton.disabled = true;
|
| 602 |
-
startButton.style.opacity = '0.5';
|
| 603 |
-
startButton.style.cursor = 'not-allowed';
|
| 604 |
startButton.textContent = "INITIALIZING...";
|
|
|
|
| 605 |
|
| 606 |
// Create power effect
|
| 607 |
const powerEffect = document.createElement('div');
|
| 608 |
powerEffect.className = 'power-on-effect';
|
| 609 |
document.body.appendChild(powerEffect);
|
| 610 |
|
| 611 |
-
//
|
| 612 |
setTimeout(() => {
|
| 613 |
-
// Hide start screen after animation
|
| 614 |
startScreen.classList.add('hidden');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 615 |
|
| 616 |
-
//
|
| 617 |
-
|
| 618 |
-
|
| 619 |
-
|
| 620 |
-
|
| 621 |
-
|
| 622 |
-
// Begin typing animation
|
| 623 |
-
typeText(`SYSTEM OVERRIDE INITIALIZED\n`, 20, () => {
|
| 624 |
-
typeText(`CAREER CRISIS SIMULATION v4.3.1\n\n`, 30, () => {
|
| 625 |
-
typeText(`Assessment indicates professional existential threat:\n`, 30, () => {
|
| 626 |
-
typeText(`AI counterpart demonstrates superior capabilities\n\n`, 30, () => {
|
| 627 |
-
typeText(`This simulation will challenge your professional identity\n\n`, 30, showJobSelect);
|
| 628 |
-
});
|
| 629 |
});
|
| 630 |
});
|
| 631 |
});
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
|
|
|
| 639 |
}
|
| 640 |
|
| 641 |
// Show job selection with more personality
|
|
@@ -655,10 +676,10 @@
|
|
| 655 |
|
| 656 |
const tempHandler = (e) => {
|
| 657 |
if (e.key === 'Enter') {
|
| 658 |
-
const choice =
|
| 659 |
if (['1', '2', '3'].includes(choice)) {
|
| 660 |
-
|
| 661 |
-
|
| 662 |
|
| 663 |
const jobsList = Object.keys(jobs);
|
| 664 |
state.job = jobs[jobsList[choice-1]];
|
|
@@ -670,7 +691,7 @@
|
|
| 670 |
}
|
| 671 |
};
|
| 672 |
|
| 673 |
-
|
| 674 |
});
|
| 675 |
});
|
| 676 |
});
|
|
@@ -708,12 +729,12 @@
|
|
| 708 |
typeText(`\nSELECT RESPONSE (1-${challenge.options.length}) > `, 50, () => {
|
| 709 |
const tempHandler = (e) => {
|
| 710 |
if (e.key === 'Enter') {
|
| 711 |
-
const choice =
|
| 712 |
const validChoices = Array.from({length: challenge.options.length}, (_, i) => (i+1).toString());
|
| 713 |
|
| 714 |
if (validChoices.includes(choice)) {
|
| 715 |
-
|
| 716 |
-
|
| 717 |
handleChoice(parseInt(choice), taskIndex);
|
| 718 |
} else {
|
| 719 |
output.innerHTML += `<div class="error">INVALID SELECTION. CHOOSE 1-${challenge.options.length}</div>`;
|
|
@@ -722,7 +743,7 @@
|
|
| 722 |
}
|
| 723 |
};
|
| 724 |
|
| 725 |
-
|
| 726 |
});
|
| 727 |
});
|
| 728 |
});
|
|
@@ -858,7 +879,7 @@
|
|
| 858 |
typeText(`\nDAY ${state.day}: FINAL ANALYSIS\n`, 30, () => {
|
| 859 |
typeText(`Your skills have deteriorated below viable thresholds.\n`, 30, () => {
|
| 860 |
typeText(`Even basic tasks are now managed by ${state.aiName}.\n`, 30, () => {
|
| 861 |
-
|
| 862 |
typeText(`<span class="warning">FINAL DIAGNOSIS: FUNCTIONAL OBSOLESCENCE</span>\n`, 40, () => {
|
| 863 |
endGame();
|
| 864 |
});
|
|
@@ -933,17 +954,23 @@
|
|
| 933 |
typeText(`Press ENTER to restart existential crisis loop`, 30);
|
| 934 |
});
|
| 935 |
|
| 936 |
-
|
| 937 |
if (e.key === 'Enter') {
|
| 938 |
-
location.reload();
|
| 939 |
}
|
| 940 |
});
|
| 941 |
}
|
| 942 |
|
| 943 |
// Cyberpunk typing effect
|
| 944 |
function typeText(text, speed = 30, callback = null) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 945 |
state.typing = true;
|
| 946 |
-
|
| 947 |
let i = 0;
|
| 948 |
const typingEffect = setInterval(() => {
|
| 949 |
if (i < text.length) {
|
|
@@ -964,22 +991,27 @@
|
|
| 964 |
clearInterval(typingEffect);
|
| 965 |
output.innerHTML += '<br>';
|
| 966 |
state.typing = false;
|
| 967 |
-
|
| 968 |
if (callback) callback();
|
| 969 |
-
|
| 970 |
}
|
| 971 |
}, speed);
|
| 972 |
}
|
| 973 |
|
| 974 |
// Initialize button with improved UX
|
| 975 |
-
|
| 976 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 977 |
e.preventDefault();
|
| 978 |
initGame();
|
| 979 |
});
|
| 980 |
|
| 981 |
// Keyboard support
|
| 982 |
-
|
| 983 |
if (e.key === 'Enter') {
|
| 984 |
e.preventDefault();
|
| 985 |
initGame();
|
|
@@ -987,13 +1019,16 @@
|
|
| 987 |
});
|
| 988 |
|
| 989 |
// Focus visual
|
| 990 |
-
|
| 991 |
-
|
| 992 |
});
|
| 993 |
|
| 994 |
-
|
| 995 |
-
|
| 996 |
});
|
|
|
|
|
|
|
|
|
|
| 997 |
});
|
| 998 |
</script>
|
| 999 |
</body>
|
|
|
|
| 63 |
position: relative;
|
| 64 |
overflow: hidden;
|
| 65 |
box-shadow: 0 0 20px rgba(0, 255, 65, 0.3);
|
| 66 |
+
opacity: 0;
|
| 67 |
+
transition: opacity 0.5s ease;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
#terminal.active {
|
| 71 |
+
opacity: 1;
|
| 72 |
}
|
| 73 |
|
| 74 |
#terminal::before {
|
|
|
|
| 186 |
color: var(--secondary);
|
| 187 |
}
|
| 188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
#start-screen {
|
| 190 |
position: fixed;
|
| 191 |
top: 0;
|
|
|
|
| 200 |
z-index: 200;
|
| 201 |
text-align: center;
|
| 202 |
pointer-events: all;
|
| 203 |
+
transition: opacity 0.5s ease;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
#start-screen.hidden {
|
| 207 |
+
opacity: 0;
|
| 208 |
+
pointer-events: none;
|
| 209 |
}
|
| 210 |
|
| 211 |
#start-title {
|
|
|
|
| 256 |
transform: translateY(1px);
|
| 257 |
}
|
| 258 |
|
| 259 |
+
#start-button.loading {
|
| 260 |
+
animation: pulse 1.5s infinite;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
@keyframes pulse {
|
| 264 |
+
0%, 100% { opacity: 0.7; }
|
| 265 |
+
50% { opacity: 1; }
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
/* Scrollbar styling */
|
| 269 |
#output::-webkit-scrollbar {
|
| 270 |
width: 5px;
|
|
|
|
| 323 |
<button id="start-button">INITIALIZE SIMULATION</button>
|
| 324 |
</div>
|
| 325 |
|
| 326 |
+
<div id="terminal">
|
| 327 |
<div id="output"></div>
|
| 328 |
<div id="input-container">
|
| 329 |
<span id="prompt">></span>
|
| 330 |
+
<input type="text" id="input" autocomplete="off" disabled>
|
| 331 |
</div>
|
| 332 |
</div>
|
| 333 |
|
|
|
|
| 609 |
const startButton = document.getElementById('start-button');
|
| 610 |
const terminal = document.getElementById('terminal');
|
| 611 |
const output = document.getElementById('output');
|
| 612 |
+
const inputElement = document.getElementById('input');
|
| 613 |
const prompt = document.getElementById('prompt');
|
| 614 |
|
| 615 |
// Initialize game with enhanced effects
|
| 616 |
function initGame() {
|
| 617 |
+
// Clear any existing typing
|
| 618 |
+
state.typing = false;
|
| 619 |
+
|
| 620 |
// Disable button to prevent multiple clicks
|
| 621 |
startButton.disabled = true;
|
|
|
|
|
|
|
| 622 |
startButton.textContent = "INITIALIZING...";
|
| 623 |
+
startButton.classList.add('loading');
|
| 624 |
|
| 625 |
// Create power effect
|
| 626 |
const powerEffect = document.createElement('div');
|
| 627 |
powerEffect.className = 'power-on-effect';
|
| 628 |
document.body.appendChild(powerEffect);
|
| 629 |
|
| 630 |
+
// Hide start screen after animation begins
|
| 631 |
setTimeout(() => {
|
|
|
|
| 632 |
startScreen.classList.add('hidden');
|
| 633 |
+
}, 200);
|
| 634 |
+
|
| 635 |
+
// Set timeout for transition to ensure it completes
|
| 636 |
+
setTimeout(() => {
|
| 637 |
+
// Show terminal
|
| 638 |
+
terminal.classList.add('active');
|
| 639 |
+
inputElement.disabled = false;
|
| 640 |
+
inputElement.focus();
|
| 641 |
+
state.gameActive = true;
|
| 642 |
|
| 643 |
+
// Begin typing animation
|
| 644 |
+
typeText(`SYSTEM OVERRIDE INITIALIZED\n`, 30, () => {
|
| 645 |
+
typeText(`CAREER CRISIS SIMULATION v4.3.1\n\n`, 30, () => {
|
| 646 |
+
typeText(`Assessment indicates professional existential threat:\n`, 30, () => {
|
| 647 |
+
typeText(`AI counterpart demonstrates superior capabilities\n\n`, 30, () => {
|
| 648 |
+
typeText(`This simulation will challenge your professional identity\n\n`, 30, showJobSelect);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 649 |
});
|
| 650 |
});
|
| 651 |
});
|
| 652 |
+
});
|
| 653 |
+
|
| 654 |
+
// Remove power effect after full transition
|
| 655 |
+
setTimeout(() => {
|
| 656 |
+
powerEffect.remove();
|
| 657 |
+
startButton.classList.remove('loading');
|
| 658 |
+
}, 1200);
|
| 659 |
+
}, 500); // This delay helps with transition timing
|
| 660 |
}
|
| 661 |
|
| 662 |
// Show job selection with more personality
|
|
|
|
| 676 |
|
| 677 |
const tempHandler = (e) => {
|
| 678 |
if (e.key === 'Enter') {
|
| 679 |
+
const choice = inputElement.value.trim();
|
| 680 |
if (['1', '2', '3'].includes(choice)) {
|
| 681 |
+
inputElement.removeEventListener('keypress', tempHandler);
|
| 682 |
+
inputElement.value = '';
|
| 683 |
|
| 684 |
const jobsList = Object.keys(jobs);
|
| 685 |
state.job = jobs[jobsList[choice-1]];
|
|
|
|
| 691 |
}
|
| 692 |
};
|
| 693 |
|
| 694 |
+
inputElement.addEventListener('keypress', tempHandler);
|
| 695 |
});
|
| 696 |
});
|
| 697 |
});
|
|
|
|
| 729 |
typeText(`\nSELECT RESPONSE (1-${challenge.options.length}) > `, 50, () => {
|
| 730 |
const tempHandler = (e) => {
|
| 731 |
if (e.key === 'Enter') {
|
| 732 |
+
const choice = inputElement.value.trim();
|
| 733 |
const validChoices = Array.from({length: challenge.options.length}, (_, i) => (i+1).toString());
|
| 734 |
|
| 735 |
if (validChoices.includes(choice)) {
|
| 736 |
+
inputElement.removeEventListener('keypress', tempHandler);
|
| 737 |
+
inputElement.value = '';
|
| 738 |
handleChoice(parseInt(choice), taskIndex);
|
| 739 |
} else {
|
| 740 |
output.innerHTML += `<div class="error">INVALID SELECTION. CHOOSE 1-${challenge.options.length}</div>`;
|
|
|
|
| 743 |
}
|
| 744 |
};
|
| 745 |
|
| 746 |
+
inputElement.addEventListener('keypress', tempHandler);
|
| 747 |
});
|
| 748 |
});
|
| 749 |
});
|
|
|
|
| 879 |
typeText(`\nDAY ${state.day}: FINAL ANALYSIS\n`, 30, () => {
|
| 880 |
typeText(`Your skills have deteriorated below viable thresholds.\n`, 30, () => {
|
| 881 |
typeText(`Even basic tasks are now managed by ${state.aiName}.\n`, 30, () => {
|
| 882 |
+
typeText(`You're kept on staff for "ethical oversight".\n\n`, 30, () => {
|
| 883 |
typeText(`<span class="warning">FINAL DIAGNOSIS: FUNCTIONAL OBSOLESCENCE</span>\n`, 40, () => {
|
| 884 |
endGame();
|
| 885 |
});
|
|
|
|
| 954 |
typeText(`Press ENTER to restart existential crisis loop`, 30);
|
| 955 |
});
|
| 956 |
|
| 957 |
+
inputElement.addEventListener('keypress', (e) => {
|
| 958 |
if (e.key === 'Enter') {
|
| 959 |
+
window.location.reload();
|
| 960 |
}
|
| 961 |
});
|
| 962 |
}
|
| 963 |
|
| 964 |
// Cyberpunk typing effect
|
| 965 |
function typeText(text, speed = 30, callback = null) {
|
| 966 |
+
if (state.typing) {
|
| 967 |
+
// Finish current typing before starting new one
|
| 968 |
+
setTimeout(() => typeText(text, speed, callback), 100);
|
| 969 |
+
return;
|
| 970 |
+
}
|
| 971 |
+
|
| 972 |
state.typing = true;
|
| 973 |
+
inputElement.disabled = true;
|
| 974 |
let i = 0;
|
| 975 |
const typingEffect = setInterval(() => {
|
| 976 |
if (i < text.length) {
|
|
|
|
| 991 |
clearInterval(typingEffect);
|
| 992 |
output.innerHTML += '<br>';
|
| 993 |
state.typing = false;
|
| 994 |
+
inputElement.disabled = false;
|
| 995 |
if (callback) callback();
|
| 996 |
+
inputElement.focus();
|
| 997 |
}
|
| 998 |
}, speed);
|
| 999 |
}
|
| 1000 |
|
| 1001 |
// Initialize button with improved UX
|
| 1002 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 1003 |
+
// Clean start button event listeners to prevent duplicates
|
| 1004 |
+
const newButton = startButton.cloneNode(true);
|
| 1005 |
+
startButton.parentNode.replaceChild(newButton, startButton);
|
| 1006 |
+
const cleanButton = document.getElementById('start-button');
|
| 1007 |
+
|
| 1008 |
+
cleanButton.addEventListener('click', (e) => {
|
| 1009 |
e.preventDefault();
|
| 1010 |
initGame();
|
| 1011 |
});
|
| 1012 |
|
| 1013 |
// Keyboard support
|
| 1014 |
+
cleanButton.addEventListener('keypress', (e) => {
|
| 1015 |
if (e.key === 'Enter') {
|
| 1016 |
e.preventDefault();
|
| 1017 |
initGame();
|
|
|
|
| 1019 |
});
|
| 1020 |
|
| 1021 |
// Focus visual
|
| 1022 |
+
cleanButton.addEventListener('focus', () => {
|
| 1023 |
+
cleanButton.style.boxShadow = '0 0 10px rgba(0, 255, 65, 0.7)';
|
| 1024 |
});
|
| 1025 |
|
| 1026 |
+
cleanButton.addEventListener('blur', () => {
|
| 1027 |
+
cleanButton.style.boxShadow = '';
|
| 1028 |
});
|
| 1029 |
+
|
| 1030 |
+
// Pre-focus the button for better keyboard UX
|
| 1031 |
+
cleanButton.focus();
|
| 1032 |
});
|
| 1033 |
</script>
|
| 1034 |
</body>
|