add achievements
Build and Push Container / build-and-push (push) Successful in 1m19s

This commit is contained in:
2026-05-28 13:02:10 -04:00
parent 5004b68817
commit 79c491d7ee
3 changed files with 462 additions and 88 deletions
+15 -2
View File
@@ -3,6 +3,9 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>Reese Wells - Self-Hosting & Infrastructure</title>
<link rel="stylesheet" href="style.css">
</head>
@@ -17,6 +20,7 @@
<div class="logo">&lt;Reese /&gt;</div>
<ul class="nav-links" id="navLinks">
<li><a href="#about">About</a></li>
<li><a href="#experience">Experience</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#contact">Contact</a></li>
@@ -558,8 +562,17 @@ XwEAnes79w4eYeMUjIytQWACEvy4QoO7X2MLTKliSqc4Ag8=
</div>
</section>
<!-- Footer -->
<footer>
<!-- Achievements Tracker -->
<section id="achievements" class="achievements-section" style="display: none;">
<div class="section-label">Achievements</div>
<div class="section-title">Terminal Achievements</div>
<p class="section-desc" style="margin: 0 auto 2rem;">Explore every corner of the terminal to unlock achievements.</p>
<div id="achievements-count" style="text-align: center; margin-bottom: 2rem; color: var(--text-muted); font-size: 0.9rem;"></div>
<div id="achievements-grid" class="achievements-grid"></div>
</section>
<!-- Footer -->
<footer>
<p style="font-size: 0.75rem; color: var(--text-muted);">
Built with a 100% self-hosted LLM stack running
<a href="https://github.com/ggml-org/llama.cpp" target="_blank" rel="noopener" style="color: var(--accent-hover); text-decoration: none;">llama.cpp</a>,
+290 -86
View File
@@ -274,92 +274,99 @@ function createServerRack() {
content.innerHTML = '';
}
if (cmdText === 'exit') {
if (!isRoot) {
isLoginScreen = true;
document.body.innerHTML = '';
document.body.style.background = '#000';
document.body.style.color = '#fff';
document.body.style.fontFamily = 'monospace';
document.body.style.padding = '20px';
document.body.style.minHeight = '100vh';
document.body.style.margin = '0';
document.body.style.lineHeight = '1.6';
const loginContainer = document.createElement('div');
loginContainer.style.marginBottom = '10px';
loginContainer.textContent = 'homelab tty1';
document.body.appendChild(loginContainer);
const loginInput = document.createElement('input');
loginInput.type = 'text';
loginInput.style.background = 'transparent';
loginInput.style.border = 'none';
loginInput.style.outline = 'none';
loginInput.style.color = '#fff';
loginInput.style.fontFamily = 'monospace';
loginInput.style.fontSize = '14px';
loginInput.style.width = '300px';
loginInput.style.caretColor = '#fff';
loginInput.autofocus = true;
const loginLine = document.createElement('div');
loginLine.style.marginBottom = '20px';
loginLine.appendChild(document.createTextNode('homelab login: '));
loginLine.appendChild(loginInput);
document.body.appendChild(loginLine);
loginInput.focus();
const handleLogin = (e) => {
if (e.key === 'Enter') {
const deniedLine = document.createElement('div');
deniedLine.textContent = 'Access denied';
deniedLine.style.marginTop = '10px';
document.body.appendChild(deniedLine);
const newLoginLine = document.createElement('div');
newLoginLine.style.marginTop = '10px';
const newInput = document.createElement('input');
newInput.type = 'text';
newInput.style.background = 'transparent';
newInput.style.border = 'none';
newInput.style.outline = 'none';
newInput.style.color = '#fff';
newInput.style.fontFamily = 'monospace';
newInput.style.fontSize = '14px';
newInput.style.width = '300px';
newInput.style.caretColor = '#fff';
newInput.autofocus = true;
newLoginLine.appendChild(document.createTextNode('homelab login: '));
newLoginLine.appendChild(newInput);
document.body.appendChild(newLoginLine);
loginInput.remove();
newInput.focus();
newInput.addEventListener('keydown', handleLogin);
}
};
loginInput.addEventListener('keydown', handleLogin);
return;
} else {
isRoot = false;
}
const newLine = document.createElement('div');
newLine.innerHTML = '<span class="terminal-prompt">$</span> ';
content.appendChild(newLine);
const newCursor = document.createElement('span');
newCursor.className = 'terminal-cursor';
newLine.appendChild(newCursor);
content.scrollTop = content.scrollHeight;
return;
}
if (cmdText === 'exit') {
if (!isRoot) {
const newAchievements = checkAchievements(cmdText, false);
if (newAchievements.length > 0) {
revealAchievements();
newAchievements.forEach(a => showToast(a));
}
isLoginScreen = true;
document.body.innerHTML = '';
document.body.style.background = '#000';
document.body.style.color = '#fff';
document.body.style.fontFamily = 'monospace';
document.body.style.padding = '20px';
document.body.style.minHeight = '100vh';
document.body.style.margin = '0';
document.body.style.lineHeight = '1.6';
const loginContainer = document.createElement('div');
loginContainer.style.marginBottom = '10px';
loginContainer.textContent = 'homelab tty1';
document.body.appendChild(loginContainer);
const loginInput = document.createElement('input');
loginInput.type = 'text';
loginInput.style.background = 'transparent';
loginInput.style.border = 'none';
loginInput.style.outline = 'none';
loginInput.style.color = '#fff';
loginInput.style.fontFamily = 'monospace';
loginInput.style.fontSize = '14px';
loginInput.style.width = '300px';
loginInput.style.caretColor = '#fff';
loginInput.autofocus = true;
const loginLine = document.createElement('div');
loginLine.style.marginBottom = '20px';
loginLine.appendChild(document.createTextNode('homelab login: '));
loginLine.appendChild(loginInput);
document.body.appendChild(loginLine);
loginInput.focus();
const handleLogin = (e) => {
if (e.key === 'Enter') {
const deniedLine = document.createElement('div');
deniedLine.textContent = 'Access denied';
deniedLine.style.marginTop = '10px';
document.body.appendChild(deniedLine);
const newLoginLine = document.createElement('div');
newLoginLine.style.marginTop = '10px';
const newInput = document.createElement('input');
newInput.type = 'text';
newInput.style.background = 'transparent';
newInput.style.border = 'none';
newInput.style.outline = 'none';
newInput.style.color = '#fff';
newInput.style.fontFamily = 'monospace';
newInput.style.fontSize = '14px';
newInput.style.width = '300px';
newInput.style.caretColor = '#fff';
newInput.autofocus = true;
newLoginLine.appendChild(document.createTextNode('homelab login: '));
newLoginLine.appendChild(newInput);
document.body.appendChild(newLoginLine);
loginInput.remove();
newInput.focus();
newInput.addEventListener('keydown', handleLogin);
}
};
loginInput.addEventListener('keydown', handleLogin);
return;
} else {
isRoot = false;
}
const newLine = document.createElement('div');
newLine.innerHTML = '<span class="terminal-prompt">$</span> ';
content.appendChild(newLine);
const newCursor = document.createElement('span');
newCursor.className = 'terminal-cursor';
newLine.appendChild(newCursor);
content.scrollTop = content.scrollHeight;
return;
}
if (cmdText === 'rm -rf /') {
if (!isRoot) {
@@ -392,6 +399,13 @@ function createServerRack() {
newCursor.className = 'terminal-cursor' + (isRoot ? ' red' : '');
newLine.appendChild(newCursor);
content.scrollTop = content.scrollHeight;
const newAchievements = checkAchievements(cmdText, isRoot);
if (newAchievements.length > 0) {
revealAchievements();
newAchievements.forEach(a => showToast(a));
}
return;
}
@@ -412,6 +426,13 @@ function createServerRack() {
newCursor.className = 'terminal-cursor red';
newLine.appendChild(newCursor);
content.scrollTop = content.scrollHeight;
const newAchievements = checkAchievements(cmdText, isRoot);
if (newAchievements.length > 0) {
revealAchievements();
newAchievements.forEach(a => showToast(a));
}
return;
}
@@ -464,6 +485,12 @@ function createServerRack() {
content.appendChild(outLine);
}
const newAchievements = checkAchievements(cmdText, isRoot);
if (newAchievements.length > 0) {
revealAchievements();
newAchievements.forEach(a => showToast(a));
}
const newLine = document.createElement('div');
if (isRoot) {
newLine.innerHTML = '<span class="terminal-prompt">#</span> ';
@@ -716,3 +743,180 @@ document.getElementById('hero').addEventListener('click', (e) => {
activeTerminal._mobileInput.focus();
}
});
// Achievement System
const ACHIEVEMENTS_STORAGE_KEY = 'reese-terminal-achievements';
const ACHIEVEMENTS = {
time_flies: { name: 'Time Flies', desc: 'Check the system uptime', icon: '⏱️', cmd: 'uptime' },
curious: { name: 'Curious', desc: 'List directory contents', icon: '📁', cmd: 'ls', prefix: true },
port_scanner: { name: 'Port Scanner', desc: 'Check listening ports', icon: '🔍', cmd: 'ss', prefix: true },
password_reset: { name: 'Password Reset Request', desc: 'Submit a SNOW request', icon: '🚪', cmd: 'exit' },
power_user: { name: 'Power User', desc: 'Gain root access', icon: '👑', cmd: 'sudo su -' },
nice_try: { name: 'Nice Try', desc: 'Attempt rm -rf / as a normal user', icon: '😏', cmd: 'rm -rf /' },
restore_backup: { name: 'Restore from Backup', desc: 'Actually destroy the system as root', icon: '💥', cmd: 'rm -rf / root' },
where_am_i: { name: 'Where Am I?', desc: 'Print working directory', icon: '📍', cmd: 'pwd' },
self_aware: { name: 'Self-Aware', desc: 'Print current user', icon: '🪞', cmd: 'whoami' },
identity: { name: 'Identity Crisis', desc: 'Print hostname', icon: '🖥️', cmd: 'hostname' },
time_keeper: { name: 'Time Keeper', desc: 'Print current date', icon: '📅', cmd: 'date' },
system_explorer: { name: 'System Explorer', desc: 'Print system information', icon: '🔧', cmd: 'uname' },
access_granted: { name: 'Access Granted', desc: 'Check user identity', icon: '🆔', cmd: 'id' },
os_detective: { name: 'OS Detective', desc: 'Read the OS release file', icon: '🐧', cmd: 'cat /etc/os-release' },
ssh_explorer: { name: 'SSH Explorer', desc: 'View SSH public key', icon: '🔑', cmd: 'cat ~/.ssh/id_ed25519.pub' },
container_watcher: { name: 'Container Watcher', desc: 'List Docker containers', icon: '🐳', cmd: 'docker ps', prefix: true },
docker_confused: { name: 'Docker Confused', desc: 'Use wrong Docker command', icon: '🤔', cmd: 'docker ls', prefix: true },
container_pro: { name: 'Container Pro', desc: 'Use correct container command', icon: '✅', cmd: 'docker container ls', prefix: true },
podman_fan: { name: 'Podman Fan', desc: 'List Podman containers', icon: '📦', cmd: 'podman ps', prefix: true },
podman_confused: { name: 'Podman Confused', desc: 'Use wrong Podman command', icon: '🤔', cmd: 'podman ls', prefix: true },
podman_pro: { name: 'Podman Pro', desc: 'Use correct Podman command', icon: '✅', cmd: 'podman container ls', prefix: true },
service_hunter: { name: 'Service Hunter', desc: 'List systemd units', icon: '🔎', cmd: 'systemctl list-units', prefix: true },
service_filter: { name: 'Service Filter', desc: 'Filter running services', icon: '🎯', cmd: 'systemctl list-units --type=service --state=running --no-pager' },
network_ninja: { name: 'Network Ninja', desc: 'Show network interfaces', icon: '🌐', cmd: 'ip addr show', prefix: true },
disk_detective: { name: 'Disk Detective', desc: 'Check disk usage', icon: '💾', cmd: 'df -h' },
memory_minded: { name: 'Memory Minded', desc: 'Check memory usage', icon: '🧠', cmd: 'free -h' },
process_watcher: { name: 'Process Watcher', desc: 'List running processes', icon: '👁️', cmd: 'ps aux', prefix: true },
memory_hog: { name: 'Memory Hog', desc: 'Find top memory consumers', icon: '🐗', cmd: 'ps aux --sort=-%mem | head -10' },
aesthetic_mode: { name: 'Aesthetic Mode', desc: 'Display system info with style', icon: '✨', cmd: 'neofetch' },
help_seeker: { name: 'Help Seeker', desc: 'Look up available commands', icon: '📖', cmd: 'help' },
clean_slate: { name: 'Clean Slate', desc: 'Clear the terminal', icon: '🧹', cmd: 'clear' },
};
function loadAchievements() {
try {
const saved = localStorage.getItem(ACHIEVEMENTS_STORAGE_KEY);
return saved ? JSON.parse(saved) : [];
} catch {
return [];
}
}
function saveAchievements(achieved) {
localStorage.setItem(ACHIEVEMENTS_STORAGE_KEY, JSON.stringify(achieved));
}
function checkAchievements(cmdText, isRoot) {
const achieved = loadAchievements();
const newAchievements = [];
for (const [key, achievement] of Object.entries(ACHIEVEMENTS)) {
if (achieved.includes(key)) continue;
if (key === 'restore_backup' && cmdText === 'rm -rf /' && isRoot) {
achieved.push(key);
newAchievements.push(achievement);
} else if (key === 'power_user' && (cmdText === 'sudo su -' || cmdText === 'sudo -i')) {
achieved.push(key);
newAchievements.push(achievement);
} else if (key === 'password_reset' && cmdText === 'exit' && !isRoot) {
achieved.push(key);
newAchievements.push(achievement);
} else if (key === 'nice_try' && cmdText === 'rm -rf /' && !isRoot) {
achieved.push(key);
newAchievements.push(achievement);
} else if (key === 'system_explorer' && (cmdText === 'uname' || cmdText === 'uname -a')) {
achieved.push(key);
newAchievements.push(achievement);
} else if (key === 'docker_confused' && cmdText === 'docker ls') {
achieved.push(key);
newAchievements.push(achievement);
} else if (key === 'podman_confused' && cmdText === 'podman ls') {
achieved.push(key);
newAchievements.push(achievement);
} else if (achievement.prefix ? cmdText.startsWith(achievement.cmd) : achievement.cmd === cmdText) {
achieved.push(key);
newAchievements.push(achievement);
}
}
if (newAchievements.length > 0) {
saveAchievements(achieved);
}
return newAchievements;
}
function showToast(achievement) {
const container = document.getElementById('toast-container') || createToastContainer();
const toast = document.createElement('div');
toast.className = 'toast';
toast.innerHTML = `
<div class="toast-icon">${achievement.icon}</div>
<div class="toast-content">
<div class="toast-label">Achievement Unlocked</div>
<div class="toast-title">${achievement.name}</div>
</div>
`;
container.appendChild(toast);
setTimeout(() => {
toast.classList.add('removing');
setTimeout(() => toast.remove(), 300);
}, 4000);
}
function createToastContainer() {
const container = document.createElement('div');
container.id = 'toast-container';
container.className = 'toast-container';
document.body.appendChild(container);
return container;
}
function revealAchievements() {
const section = document.getElementById('achievements');
if (section.style.display === 'none' || !section.style.display) {
section.style.display = 'block';
section.classList.add('fade-in');
setTimeout(() => section.classList.add('visible'), 50);
addAchievementsNav();
}
renderAchievements();
}
function renderAchievements() {
const achieved = loadAchievements();
const total = Object.keys(ACHIEVEMENTS).length;
const count = achieved.length;
const countEl = document.getElementById('achievements-count');
countEl.textContent = `${count} / ${total} achievements unlocked`;
const grid = document.getElementById('achievements-grid');
grid.innerHTML = '';
for (const [key, achievement] of Object.entries(ACHIEVEMENTS)) {
const isUnlocked = achieved.includes(key);
const card = document.createElement('div');
card.className = `achievement-card ${isUnlocked ? 'unlocked' : 'locked'}`;
card.innerHTML = `
<div class="achievement-icon">${achievement.icon}</div>
<div class="achievement-info">
<h3>${isUnlocked ? achievement.name : '???'}</h3>
<p>${isUnlocked ? achievement.desc : 'Keep exploring the terminal...'}</p>
</div>
`;
grid.appendChild(card);
}
}
function addAchievementsNav() {
const navLinks = document.getElementById('navLinks');
const existing = document.getElementById('nav-achievements');
if (!existing && loadAchievements().length > 0) {
const li = document.createElement('li');
li.id = 'nav-achievements';
li.innerHTML = '<a href="#achievements">Achievements</a>';
navLinks.appendChild(li);
}
}
// Initialize
(function initAchievements() {
const achieved = loadAchievements();
if (achieved.length > 0) {
revealAchievements();
addAchievementsNav();
}
})();
+157
View File
@@ -1454,6 +1454,163 @@ footer p {
transform: translateY(0);
}
/* Achievements Section */
.achievements-section {
background: var(--bg-secondary);
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
}
.achievements-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1rem;
max-width: 1200px;
margin: 0 auto;
}
.achievement-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 1.25rem;
display: flex;
align-items: flex-start;
gap: 1rem;
transition: all 0.3s ease;
}
.achievement-card.locked {
opacity: 0.4;
}
.achievement-card.unlocked {
border-color: rgba(234, 179, 8, 0.3);
box-shadow: 0 0 20px rgba(234, 179, 8, 0.08);
}
.achievement-icon {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: var(--accent-glow);
border: 1px solid rgba(234, 179, 8, 0.2);
border-radius: 10px;
font-size: 1.2rem;
flex-shrink: 0;
}
.achievement-card.locked .achievement-icon {
filter: grayscale(1);
opacity: 0.5;
}
.achievement-info h3 {
font-size: 0.9rem;
font-weight: 700;
margin-bottom: 0.25rem;
}
.achievement-info p {
color: var(--text-muted);
font-size: 0.8rem;
line-height: 1.4;
}
.achievement-card.locked .achievement-info h3 {
color: var(--text-muted);
}
.achievement-card.locked .achievement-info p {
color: var(--text-muted);
opacity: 0.5;
}
/* Toast Notification */
.toast-container {
position: fixed;
top: 80px;
right: 20px;
z-index: 1000;
display: flex;
flex-direction: column;
gap: 0.75rem;
pointer-events: none;
}
.toast {
background: var(--bg-card);
border: 1px solid var(--accent);
border-radius: 12px;
padding: 1rem 1.25rem;
display: flex;
align-items: center;
gap: 0.75rem;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4), 0 0 20px var(--accent-glow);
pointer-events: auto;
animation: toastIn 0.4s cubic-bezier(0.16, 1, 0.3, 1);
max-width: 340px;
}
.toast.removing {
animation: toastOut 0.3s ease forwards;
}
.toast-icon {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
background: var(--accent-glow);
border: 1px solid rgba(234, 179, 8, 0.3);
border-radius: 8px;
font-size: 1.1rem;
flex-shrink: 0;
}
.toast-content {
flex: 1;
}
.toast-label {
font-size: 0.65rem;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--accent);
font-weight: 600;
margin-bottom: 0.15rem;
}
.toast-title {
font-size: 0.9rem;
font-weight: 700;
}
@keyframes toastIn {
from {
opacity: 0;
transform: translateX(100px) scale(0.9);
}
to {
opacity: 1;
transform: translateX(0) scale(1);
}
}
@keyframes toastOut {
from {
opacity: 1;
transform: translateX(0) scale(1);
}
to {
opacity: 0;
transform: translateX(100px) scale(0.9);
}
}
/* Responsive */
@media (max-width: 768px) {
.nav-links {