126 lines
4.4 KiB
HTML
126 lines
4.4 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 DUSTIN'S FAULT — Incident Monitoring System</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>
|
|
/* [All original CSS...] */
|
|
/* Adding new styles for v2 */
|
|
.incident.typing {
|
|
opacity: 0.6;
|
|
}
|
|
.type-cursor {
|
|
animation: blink 0.7s step-end infinite;
|
|
}
|
|
.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;
|
|
}
|
|
.sound-toggle {
|
|
cursor: pointer;
|
|
text-decoration: underline;
|
|
color: var(--terminal-amber);
|
|
}
|
|
.sound-toggle:hover {
|
|
color: var(--terminal-green);
|
|
}
|
|
/* Rest of CSS same as v1 */
|
|
[Paste full CSS here, but truncated for brevity]
|
|
</style>
|
|
</head>
|
|
<body>
|
|
[Same HTML structure, with additions: sound toggle in log-header, new stat-card for fault-graph id="fault-graph"]
|
|
<div class="stat-card">
|
|
<div class="stat-label">Fault Attribution</div>
|
|
<pre class="stat-value fault-graph" id="fault-graph">
|
|
100% Dustin
|
|
░░░░░░░░░░
|
|
</pre>
|
|
</div>
|
|
[In log-header add sound toggle]
|
|
</body>
|
|
<script>
|
|
// [Original JS...]
|
|
// New: AudioContext for sounds
|
|
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
|
let soundEnabled = true;
|
|
function playBeep(frequency = 800, duration = 150) {
|
|
if (!soundEnabled) return;
|
|
const oscillator = audioCtx.createOscillator();
|
|
const gainNode = audioCtx.createGain();
|
|
oscillator.connect(gainNode);
|
|
gainNode.connect(audioCtx.destination);
|
|
oscillator.frequency.value = frequency;
|
|
oscillator.type = 'square';
|
|
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);
|
|
}
|
|
|
|
// Enhanced addIncident with typing
|
|
async function addIncident(desc, severity, cause, isUserReport = false) {
|
|
playBeep(severity === 'critical' ? 400 : 800); // Low beep for critical
|
|
if (severity === 'critical') document.body.classList.add('glitch');
|
|
// Create empty incident div
|
|
const incident = document.createElement('div');
|
|
incident.className = `incident ${severity} typing`;
|
|
log.insertBefore(incident, log.firstChild);
|
|
const id = ...;
|
|
const time = ...;
|
|
// Type header
|
|
await typeLine(incident, `<span class="incident-id">${id}</span><span class="incident-time">${time}</span><span class="incident-severity ${severity}">[${severity.toUpperCase()}]</span> <span class="type-cursor">|</span>`);
|
|
await typeLine(incident, `<div class="incident-desc">${desc}</div>`);
|
|
await typeLine(incident, `<div class="incident-root-cause">⚠ ROOT CAUSE: ${cause}</div>`);
|
|
incident.classList.remove('typing');
|
|
// Easter egg
|
|
if (desc.toLowerCase().includes('innocent')) {
|
|
dustinFaultCount += 100;
|
|
playBeep(200, 500);
|
|
}
|
|
updateStats();
|
|
}
|
|
|
|
async function typeLine(container, text) {
|
|
container.innerHTML += text.slice(0,1);
|
|
for (let i = 1; i < text.length; i++) {
|
|
await new Promise(r => setTimeout(r, 30 + Math.random()*20));
|
|
container.innerHTML = container.innerHTML.slice(0,-1) + text.slice(0,i+1) + '<span class="type-cursor">|</span>';
|
|
}
|
|
container.innerHTML += '\n';
|
|
}
|
|
|
|
// Update fault graph
|
|
function updateFaultGraph() {
|
|
const graph = document.getElementById('fault-graph');
|
|
const barLength = 10;
|
|
const bar = '█'.repeat(barLength) + '\n100% Dustin Faults';
|
|
graph.textContent = bar;
|
|
}
|
|
|
|
// Sound toggle click
|
|
document.querySelector('.sound-toggle').addEventListener('click', () => {
|
|
soundEnabled = !soundEnabled;
|
|
// Update toggle text
|
|
});
|
|
|
|
// Call updateFaultGraph in updateStats
|
|
</script>
|
|
</html> |