Files
dustins-fault/www/index.html
hobokenchicken 0d0963198e refactor: simplify deployment for existing Apache Docker container
- Move web files to www/ directory for easy copying to data folder
- Remove Docker setup since user has existing Apache container
- Add custom 404.html page
- Update README with simple deployment instructions
- Keep CGI script as optional bonus feature
2026-02-25 12:02:55 -05:00

990 lines
30 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IT'S FUCKING DUSTIN'S FAULT — Official Blame Portal</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600;700&family=Share+Tech+Mono&display=swap" rel="stylesheet">
<style>
:root {
--terminal-bg: #000;
--terminal-text: #0f0;
--terminal-red: #f00;
--terminal-yellow: #ff0;
--terminal-cyan: #0ff;
--terminal-magenta: #f0f;
--terminal-amber: #ff9900;
--terminal-green: #00ff00;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'IBM Plex Mono', monospace;
background: var(--terminal-bg);
color: var(--terminal-text);
min-height: 100vh;
padding: 20px;
overflow-x: hidden;
position: relative;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: repeating-linear-gradient(
0deg,
rgba(0, 255, 0, 0.03) 0px,
rgba(0, 255, 0, 0.03) 1px,
transparent 1px,
transparent 2px
);
pointer-events: none;
z-index: 9999;
}
.scanline {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(to bottom, transparent, rgba(0, 255, 0, 0.3), transparent);
animation: scan 3s linear infinite;
pointer-events: none;
z-index: 10000;
}
@keyframes scan {
0% { top: 0; }
100% { top: 100%; }
}
.header {
text-align: center;
margin-bottom: 30px;
padding: 20px;
border: 3px solid var(--terminal-red);
background: rgba(255, 0, 0, 0.1);
position: relative;
overflow: hidden;
}
.header::before {
content: '⚠ WARNING: DUSTIN DETECTED ⚠';
position: absolute;
top: 0;
left: 0;
right: 0;
background: var(--terminal-red);
color: black;
font-weight: bold;
padding: 5px;
animation: warning-blink 1s infinite;
}
@keyframes warning-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.title {
font-family: 'Share Tech Mono', monospace;
font-size: 3.5em;
color: var(--terminal-red);
text-shadow: 0 0 10px var(--terminal-red);
margin: 20px 0;
letter-spacing: 2px;
}
.subtitle {
color: var(--terminal-yellow);
font-size: 1.2em;
margin-bottom: 10px;
}
.tagline {
color: var(--terminal-cyan);
font-style: italic;
margin-bottom: 20px;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.stat-card {
background: rgba(0, 255, 0, 0.05);
border: 1px solid var(--terminal-green);
padding: 20px;
border-radius: 5px;
position: relative;
overflow: hidden;
}
.stat-card.critical {
border-color: var(--terminal-red);
background: rgba(255, 0, 0, 0.1);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { box-shadow: 0 0 5px var(--terminal-red); }
50% { box-shadow: 0 0 20px var(--terminal-red); }
}
.stat-label {
color: var(--terminal-cyan);
font-size: 0.9em;
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 10px;
}
.stat-value {
font-size: 2.5em;
font-weight: bold;
color: var(--terminal-red);
}
.stat-value.green {
color: var(--terminal-green);
}
.stat-value.yellow {
color: var(--terminal-yellow);
}
.main-content {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 30px;
margin-bottom: 30px;
}
@media (max-width: 768px) {
.main-content {
grid-template-columns: 1fr;
}
}
.incident-log {
background: rgba(0, 0, 0, 0.8);
border: 2px solid var(--terminal-green);
padding: 20px;
border-radius: 5px;
max-height: 600px;
overflow-y: auto;
}
.log-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid var(--terminal-green);
}
.log-title {
font-size: 1.5em;
color: var(--terminal-yellow);
}
.controls {
display: flex;
gap: 10px;
}
.control-btn {
background: var(--terminal-bg);
border: 1px solid var(--terminal-cyan);
color: var(--terminal-cyan);
padding: 8px 15px;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
border-radius: 3px;
transition: all 0.3s;
}
.control-btn:hover {
background: var(--terminal-cyan);
color: var(--terminal-bg);
}
.control-btn.danger {
border-color: var(--terminal-red);
color: var(--terminal-red);
}
.control-btn.danger:hover {
background: var(--terminal-red);
color: var(--terminal-bg);
}
.incident {
margin-bottom: 15px;
padding: 15px;
border-left: 4px solid var(--terminal-green);
background: rgba(0, 255, 0, 0.05);
animation: fadeIn 0.5s;
}
.incident.critical {
border-left-color: var(--terminal-red);
background: rgba(255, 0, 0, 0.1);
}
.incident.warning {
border-left-color: var(--terminal-yellow);
background: rgba(255, 255, 0, 0.1);
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
.incident-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
font-size: 0.9em;
}
.incident-id {
color: var(--terminal-cyan);
}
.incident-time {
color: var(--terminal-magenta);
}
.incident-severity {
font-weight: bold;
}
.incident-severity.critical {
color: var(--terminal-red);
}
.incident-severity.warning {
color: var(--terminal-yellow);
}
.incident-desc {
margin-bottom: 10px;
line-height: 1.5;
}
.incident-root-cause {
color: var(--terminal-red);
font-weight: bold;
font-style: italic;
}
.sidebar {
display: flex;
flex-direction: column;
gap: 20px;
}
.blame-generator {
background: rgba(255, 0, 0, 0.1);
border: 2px solid var(--terminal-red);
padding: 20px;
border-radius: 5px;
}
.blame-title {
color: var(--terminal-red);
font-size: 1.3em;
margin-bottom: 15px;
text-align: center;
}
.blame-form {
display: flex;
flex-direction: column;
gap: 15px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 5px;
}
label {
color: var(--terminal-cyan);
font-size: 0.9em;
}
select, textarea {
background: var(--terminal-bg);
border: 1px solid var(--terminal-green);
color: var(--terminal-text);
padding: 10px;
font-family: 'IBM Plex Mono', monospace;
border-radius: 3px;
resize: vertical;
}
textarea {
min-height: 100px;
}
.submit-btn {
background: var(--terminal-red);
color: var(--terminal-bg);
border: none;
padding: 12px;
font-family: 'IBM Plex Mono', monospace;
font-weight: bold;
cursor: pointer;
border-radius: 3px;
transition: all 0.3s;
text-transform: uppercase;
letter-spacing: 1px;
}
.submit-btn:hover {
background: var(--terminal-yellow);
color: var(--terminal-red);
}
.apology-generator {
background: rgba(0, 255, 255, 0.1);
border: 2px solid var(--terminal-cyan);
padding: 20px;
border-radius: 5px;
}
.apology-title {
color: var(--terminal-cyan);
font-size: 1.3em;
margin-bottom: 15px;
text-align: center;
}
.apology-display {
background: rgba(0, 0, 0, 0.5);
border: 1px solid var(--terminal-magenta);
padding: 15px;
min-height: 100px;
margin-bottom: 15px;
border-radius: 3px;
font-style: italic;
color: var(--terminal-magenta);
}
.generate-btn {
background: var(--terminal-cyan);
color: var(--terminal-bg);
border: none;
padding: 12px;
font-family: 'IBM Plex Mono', monospace;
font-weight: bold;
cursor: pointer;
border-radius: 3px;
transition: all 0.3s;
width: 100%;
}
.generate-btn:hover {
background: var(--terminal-magenta);
}
.footer {
text-align: center;
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid var(--terminal-green);
color: var(--terminal-cyan);
font-size: 0.9em;
}
.easter-egg {
cursor: pointer;
color: var(--terminal-magenta);
text-decoration: underline;
}
.easter-egg:hover {
color: var(--terminal-yellow);
}
.sound-toggle {
cursor: pointer;
color: var(--terminal-amber);
text-decoration: underline;
}
.sound-toggle:hover {
color: var(--terminal-green);
}
.type-cursor {
animation: blink 0.7s step-end infinite;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.glitch {
animation: glitch 0.2s;
}
@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); }
}
.fault-graph {
font-size: 10px;
line-height: 1.2;
white-space: pre;
text-align: left;
color: var(--terminal-red);
}
.rage-meter {
width: 100%;
height: 20px;
background: rgba(255, 0, 0, 0.2);
border: 1px solid var(--terminal-red);
border-radius: 10px;
overflow: hidden;
margin-top: 10px;
}
.rage-fill {
height: 100%;
background: linear-gradient(90deg, var(--terminal-red), var(--terminal-yellow));
width: 100%;
transition: width 0.5s;
}
.shit-list {
background: rgba(255, 0, 0, 0.1);
border: 1px solid var(--terminal-red);
padding: 15px;
margin-top: 20px;
border-radius: 5px;
}
.shit-list-title {
color: var(--terminal-red);
font-size: 1.1em;
margin-bottom: 10px;
}
.shit-item {
color: var(--terminal-yellow);
margin-bottom: 5px;
padding-left: 15px;
position: relative;
}
.shit-item::before {
content: '💩';
position: absolute;
left: 0;
}
.nuclear-option {
background: linear-gradient(45deg, #ff0000, #ff9900, #ffff00);
color: black;
border: none;
padding: 15px 30px;
font-family: 'IBM Plex Mono', monospace;
font-weight: bold;
cursor: pointer;
border-radius: 5px;
margin-top: 20px;
text-transform: uppercase;
letter-spacing: 2px;
animation: nuclear-pulse 2s infinite;
}
@keyframes nuclear-pulse {
0%, 100% { box-shadow: 0 0 10px #ff0000; }
50% { box-shadow: 0 0 30px #ffff00; }
}
.nuclear-option:hover {
background: linear-gradient(45deg, #ffff00, #ff9900, #ff0000);
animation: none;
box-shadow: 0 0 50px #ff0000;
}
.dustin-face {
text-align: center;
margin: 20px 0;
font-size: 3em;
animation: face-shake 5s infinite;
}
@keyframes face-shake {
0%, 100% { transform: rotate(0deg); }
25% { transform: rotate(5deg); }
75% { transform: rotate(-5deg); }
}
</style>
</head>
<body>
<div class=\"scanline\"></div>
<div class=\"header\">
<div class=\"dustin-face\">🤦‍♂️</div>
<h1 class=\"title\">IT'S FUCKING DUSTIN'S FAULT</h1>
<div class=\"subtitle\">Official Corporate Blame Allocation System</div>
<div class=\"tagline\">Because someone has to take responsibility for this clusterfuck</div>
</div>
<div class=\"stats-grid\">
<div class=\"stat-card critical\">
<div class=\"stat-label\">Total Fuckups Blamed on Dustin</div>
<div class=\"stat-value\" id=\"total-fuckups\">1,247</div>
<div class=\"rage-meter\">
<div class=\"rage-fill\" id=\"rage-meter\" style=\"width: 100%\"></div>
</div>
</div>
<div class=\"stat-card\">
<div class=\"stat-label\">Current Blame Percentage</div>
<div class=\"stat-value\" id=\"blame-percentage\">100%</div>
<div class=\"stat-label\">(Yes, even for things that haven't happened yet)</div>
</div>
<div class=\"stat-card\">
<div class=\"stat-label\">Dustin's Apologies Generated</div>
<div class=\"stat-value green\" id=\"apologies-count\">42</div>
<div class=\"stat-label\">(All of them bullshit)</div>
</div>
<div class=\"stat-card\">
<div class=\"stat-label\">Hours Wasted Blaming Dustin</div>
<div class=\"stat-value yellow\" id=\"hours-wasted\">3,728</div>
<div class=\"stat-label\">(Productivity: -∞)</div>
</div>
</div>
<div class=\"main-content\">
<div class=\"incident-log\">
<div class=\"log-header\">
<div class=\"log-title\">LIVE INCIDENT FEED — Everything is Dustin's Fault</div>
<div class=\"controls\">
<button class=\"control-btn\" id=\"auto-add\">Auto-Blame Dustin</button>
<button class=\"control-btn danger\" id=\"clear-log\">Clear Log (Dustin's Idea)</button>
<span class=\"sound-toggle\" id=\"sound-toggle\">🔊 Sound: ON</span>
</div>
</div>
<div id=\"log\">
<!-- Incidents will be added here -->
</div>
<div class=\"shit-list\">
<div class=\"shit-list-title\">Dustin's Greatest Hits (Recent Fuckups):</div>
<div class=\"shit-item\">Spilled coffee on the CEO's laptop during board meeting</div>
<div class=\"shit-item\">Accidentally deleted the entire customer database (twice)</div>
<div class=\"shit-item\">Set the office thermostat to \"Sahara Desert\" mode</div>
<div class=\"shit-item\">Replied-all to company-wide email with \"who gives a shit?\"</div>
<div class=\"shit-item\">Scheduled server maintenance for Christmas Day</div>
</div>
</div>
<div class=\"sidebar\">
<div class=\"blame-generator\">
<div class=\"blame-title\">OFFICIAL BLAME SUBMISSION FORM</div>
<form class=\"blame-form\" id=\"blame-form\">
<div class=\"form-group\">
<label for=\"severity\">How Bad Did Dustin Fuck Up?</label>
<select id=\"severity\" required>
<option value=\"minor\">Minor Inconvenience (Dustin's specialty)</option>
<option value=\"warning\">Warning Level (Dustin was involved)</option>
<option value=\"critical\" selected>Critical Failure (Classic Dustin)</option>
<option value=\"apocalyptic\">Apocalyptic Disaster (Dustin was in charge)</option>
</select>
</div>
<div class=\"form-group\">
<label for=\"description\">Describe Dustin's Latest Fuckup:</label>
<textarea id=\"description\" placeholder=\"Be specific. Use profanity. We won't judge.\" required></textarea>
</div>
<div class=\"form-group\">
<label for=\"cause\">Root Cause (Always Dustin):</label>
<select id=\"cause\">
<option>Dustin didn't read the documentation</option>
<option>Dustin pushed to production on Friday</option>
<option>Dustin thought \"it would be fine\"</option>
<option>Dustin was \"just trying to help\"</option>
<option>Dustin forgot to commit the code</option>
<option>Dustin spilled something on the server</option>
<option>Dustin was distracted by shiny objects</option>
<option>Dustin said \"trust me, I know what I'm doing\"</option>
</select>
</div>
<button type=\"submit\" class=\"submit-btn\">BLAME DUSTIN OFFICIALLY</button>
</form>
</div>
<div class=\"apology-generator\">
<div class=\"apology-title\">DUSTIN'S APOLOGY GENERATOR™</div>
<div class=\"apology-display\" id=\"apology-display\">
Click below to generate a fresh bullshit apology from Dustin...
</div>
<button class=\"generate-btn\" id=\"generate-apology\">GENERATE BULLSHIT APOLOGY</button>
<div style=\"text-align: center; margin-top: 10px; font-size: 0.8em; color: var(--terminal-magenta);\">
Sincerity Level: <span id=\"sincerity-level\">0%</span>
</div>
</div>
<button class=\"nuclear-option\" id=\"nuclear-option\">
🚨 NUCLEAR OPTION: FIRE DUSTIN 🚨
</button>
<div style=\"text-align: center; margin-top: 20px;\">
<a href=\"/cgi-bin/blame-dustin.cgi\" style=\"color: var(--terminal-cyan); text-decoration: none; border: 1px solid var(--terminal-cyan); padding: 10px; display: block;\">
🐮 ACCESS THE COWSAY BLAME INTERFACE 🐮
</a>
</div>
</div>
</div>
<div class=\"footer\">
<p>© 2026 Corporate Blame Allocation Division — All faults reserved.</p>
<p>This system is 100% accurate because Dustin is always at fault. Don't @ us.</p>
<p>Total system uptime: <span id=\"uptime\">99.9%</span> (the 0.1% downtime was Dustin's fault too)</p>
<p class=\"easter-egg\" id=\"easter-egg\">Click here if you actually like Dustin (you monster)</p>
</div>
<script>
// Initialize variables
let soundEnabled = true;
let totalFuckups = 1247;
let apologiesCount = 42;
let hoursWasted = 3728;
let incidentId = 1000;
let autoAddInterval;
let rageLevel = 100;
// DOM elements
const log = document.getElementById('log');
const soundToggle = document.getElementById('sound-toggle');
const autoAddBtn = document.getElementById('auto-add');
const clearLogBtn = document.getElementById('clear-log');
const blameForm = document.getElementById('blame-form');
const generateApologyBtn = document.getElementById('generate-apology');
const apologyDisplay = document.getElementById('apology-display');
const sincerityLevel = document.getElementById('sincerity-level');
const nuclearOption = document.getElementById('nuclear-option');
const easterEgg = document.getElementById('easter-egg');
const totalFuckupsEl = document.getElementById('total-fuckups');
const apologiesCountEl = document.getElementById('apologies-count');
const hoursWastedEl = document.getElementById('hours-wasted');
const rageMeter = document.getElementById('rage-meter');
const uptimeEl = document.getElementById('uptime');
// Sound functions
function playBeep(frequency = 800, duration = 150, type = 'square') {
if (!soundEnabled) return;
try {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
oscillator.frequency.value = frequency;
oscillator.type = type;
gainNode.gain.setValueAtTime(0.3, audioCtx.currentTime);
gainNode.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + duration / 1000);
oscillator.start(audioCtx.currentTime);
oscillator.stop(audioCtx.currentTime + duration / 1000);
} catch (e) {
console.log('Audio context not supported or blocked');
}
}
function playErrorSound() {
if (!soundEnabled) return;
playBeep(200, 300, 'sawtooth');
setTimeout(() => playBeep(150, 400, 'sawtooth'), 150);
}
function playSuccessSound() {
if (!soundEnabled) return;
playBeep(1000, 100, 'sine');
setTimeout(() => playBeep(1200, 100, 'sine'), 100);
}
// Incident data
const incidents = [
{ desc: \"Production database went down during peak hours\", severity: \"critical\", cause: \"Dustin was 'optimizing' queries without testing\" },
{ desc: \"Company-wide email sent with embarrassing typo\", severity: \"warning\", cause: \"Dustin didn't use spell check (obviously)\" },
{ desc: \"Server room flooded from coffee spill\", severity: \"critical\", cause: \"Dustin brought an open cup near the racks (again)\" },
{ desc: \"Customer data leaked to public GitHub repo\", severity: \"critical\", cause: \"Dustin thought '.gitignore' was optional\" },
{ desc: \"Annual budget report contains meme references\", severity: \"warning\", cause: \"Dustin 'wanted to make it more engaging'\" },
{ desc: \"Firewall configured to block all internal traffic\", severity: \"critical\", cause: \"Dustin misread 'allow' as 'deny'\" },
{ desc: \"Backup system hasn't worked in 6 months\", severity: \"critical\", cause: \"Dustin disabled alerts because they were 'annoying'\" },
{ desc: \"Passwords set to 'password123' for 'security'\", severity: \"warning\", cause: \"Dustin's brilliant security strategy\" },
{ desc: \"CEO's presentation corrupted right before board meeting\", severity: \"critical\", cause: \"Dustin 'updated' PowerPoint without saving\" },
{ desc: \"Entire office network down for 8 hours\", severity: \"critical\", cause: \"Dustin was 'cleaning up cables' with scissors\" }
];
const causes = [
\"Dustin didn't read the fucking manual\",
\"Dustin thought he knew better than everyone else\",
\"Dustin was distracted by cat videos\",
\"Dustin said 'how hard could it be?'\",
\"Dustin was hungover from last night's 'team building'\",
\"Dustin forgot to commit the goddamn code\",
\"Dustin pushed straight to production (like a moron)\",
\"Dustin was trying to impress someone (and failed)\",
\"Dustin didn't test anything (classic Dustin)\",
\"Dustin was 'just experimenting' (with our production data)\"
];
const apologies = [
\"My bad, I thought it would work.\",
\"Sorry not sorry, it seemed like a good idea at the time.\",
\"I apologize for the inconvenience (but really it's your fault for trusting me).\",
\"Oopsie daisy! My finger slipped.\",
\"I'm sorry you feel that way about my brilliant solution.\",
\"My cat walked on the keyboard, what can I say?\",
\"It worked on my machine, so technically it's your fault.\",
\"I was following a tutorial I found on Reddit.\",
\"The voices in my head told me to do it.\",
\"I was trying to save us time (by skipping all the important steps).\",
\"It's not a bug, it's a feature you don't understand yet.\",
\"I blame the full moon/mercury retrograde/my horoscope.\",
\"I was optimizing for 'developer happiness' (mine, not yours).\",
\"The documentation was unclear (because I didn't read it).\",
\"I thought we were still in the testing phase (we're not).\"
];
// Initialize with some incidents
function initIncidents() {
for (let i = 0; i < 3; i++) {
const incident = incidents[Math.floor(Math.random() * incidents.length)];
addIncident(incident.desc, incident.severity, incident.cause);
}
}
// Add incident function
function addIncident(desc, severity, cause, isUserReport = false) {
incidentId++;
totalFuckups++;
hoursWasted += Math.floor(Math.random() * 10) + 1;
rageLevel = Math.min(100, rageLevel + 5);
// Update stats
updateStats();
// Play sound
if (severity === 'critical') {
playErrorSound();
document.body.classList.add('glitch');
setTimeout(() => document.body.classList.remove('glitch'), 200);
} else {
playBeep(severity === 'warning' ? 600 : 800);
}
// Create incident element
const incident = document.createElement('div');
incident.className = `incident ${severity}`;
const time = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
const date = new Date().toLocaleDateString();
incident.innerHTML = `
<div class=\"incident-header\">
<span class=\"incident-id\">#${incidentId}</span>
<span class=\"incident-time\">${date} ${time}</span>
<span class=\"incident-severity ${severity}\">[${severity.toUpperCase()}]</span>
</div>
<div class=\"incident-desc\">${desc}</div>
<div class=\"incident-root-cause\">⚠ ROOT CAUSE: ${cause}</div>
${isUserReport ? '<div style=\"color: var(--terminal-cyan); font-size: 0.8em; margin-top: 5px;\">📝 User-Submitted Blame</div>' : ''}
`;
// Add to log
log.insertBefore(incident, log.firstChild);
// Limit log size
if (log.children.length > 20) {
log.removeChild(log.lastChild);
}
return incident;
}
// Auto-add incident
function autoAddIncident() {
const incident = incidents[Math.floor(Math.random() * incidents.length)];
const cause = causes[Math.floor(Math.random() * causes.length)];
addIncident(incident.desc, incident.severity, cause);
}
// Update stats
function updateStats() {
totalFuckupsEl.textContent = totalFuckups.toLocaleString();
apologiesCountEl.textContent = apologiesCount;
hoursWastedEl.textContent = hoursWasted.toLocaleString();
rageMeter.style.width = `${rageLevel}%`;
// Update blame percentage (always 100%, but let's pretend it fluctuates)
const blamePercentage = document.getElementById('blame-percentage');
blamePercentage.textContent = '100%';
// Update uptime with random slight variations
const uptime = 99.9 - (Math.random() * 0.1);
uptimeEl.textContent = `${uptime.toFixed(1)}%`;
}
// Generate apology
function generateApology() {
const apology = apologies[Math.floor(Math.random() * apologies.length)];
const sincerity = Math.floor(Math.random() * 21); // 0-20%
apologyDisplay.textContent = `\"${apology}\"`;
sincerityLevel.textContent = `${sincerity}%`;
apologiesCount++;
updateStats();
playSuccessSound();
// Add apology to incident log
addIncident(
`Dustin issued another bullshit apology`,
'warning',
`Dustin's sincerity level: ${sincerity}% (pathetic)`
);
}
// Nuclear option
function fireDustin() {
playErrorSound();
document.body.classList.add('glitch');
// Add critical incident
addIncident(
'🚨 NUCLEAR OPTION ACTIVATED: ATTEMPTING TO FIRE DUSTIN 🚨',
'critical',
'System override failed: Dustin has tenure (somehow)'
);
// Show alert
setTimeout(() => {
alert('SYSTEM OVERRIDE FAILED\\n\\nDustin cannot be fired because:\\n1. He knows where the bodies are buried\\n2. He has blackmail material on the CEO\\n3. The HR system is also his fault and broken\\n\\nTry blaming him harder instead.');
document.body.classList.remove('glitch');
}, 500);
}
// Easter egg
function triggerEasterEgg() {
playBeep(300, 500);
playBeep(400, 500);
playBeep(500, 500);
// Add hilarious incident
addIncident(
'SOME MONSTER ACTUALLY LIKES DUSTIN',
'critical',
'This person needs psychological evaluation immediately'
);
// Change title temporarily
const title = document.querySelector('.title');
const originalTitle = title.textContent;
title.textContent = 'SOMEONE ACTUALLY LIKES DUSTIN?!';
title.style.color = 'var(--terminal-magenta)';
setTimeout(() => {
title.textContent = originalTitle;
title.style.color = 'var(--terminal-red)';
}, 3000);
}
// Event listeners
soundToggle.addEventListener('click', () => {
soundEnabled = !soundEnabled;
soundToggle.textContent = soundEnabled ? '🔊 Sound: ON' : '🔇 Sound: OFF';
playBeep();
});
autoAddBtn.addEventListener('click', () => {
if (autoAddInterval) {
clearInterval(autoAddInterval);
autoAddInterval = null;
autoAddBtn.textContent = 'Auto-Blame Dustin';
playSuccessSound();
} else {
autoAddInterval = setInterval(autoAddIncident, 5000);
autoAddBtn.textContent = 'Stop Auto-Blame';
playSuccessSound();
autoAddIncident(); // Add one immediately
}
});
clearLogBtn.addEventListener('click', () => {
if (confirm('Clear the incident log? (This was probably Dustin\\'s idea)')) {
log.innerHTML = '';
playErrorSound();
addIncident(
'Incident log cleared (Dustin\\'s brilliant idea)',
'warning',
'Dustin thought \"out of sight, out of mind\" applies to fuckups'
);
}
});
blameForm.addEventListener('submit', (e) => {
e.preventDefault();
const severity = document.getElementById('severity').value;
const description = document.getElementById('description').value;
const cause = document.getElementById('cause').value;
if (description.trim()) {
addIncident(description, severity, cause, true);
document.getElementById('description').value = '';
playSuccessSound();
}
});
generateApologyBtn.addEventListener('click', generateApology);
nuclearOption.addEventListener('click', fireDustin);
easterEgg.addEventListener('click', triggerEasterEgg);
// Initialize the page
initIncidents();
</script>
</body>
</html>