102 lines
3.0 KiB
HTML
102 lines
3.0 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Fleet Pulse — Collective Stability</title>
|
|
<style>
|
|
body { margin: 0; background: #050505; overflow: hidden; display: flex; align-items: center; justify-content: center; height: 100vh; }
|
|
#pulseCanvas { display: block; }
|
|
#info {
|
|
position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);
|
|
color: #66fcf1; font-family: system-ui, sans-serif; font-size: 14px; opacity: 0.8;
|
|
text-align: center;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<canvas id="pulseCanvas"></canvas>
|
|
<div id="info">Fleet Pulse — Lazarus Pit Registry</div>
|
|
<script>
|
|
const canvas = document.getElementById('pulseCanvas');
|
|
const ctx = canvas.getContext('2d');
|
|
let width, height, centerX, centerY;
|
|
|
|
function resize() {
|
|
width = canvas.width = window.innerWidth;
|
|
height = canvas.height = window.innerHeight;
|
|
centerX = width / 2;
|
|
centerY = height / 2;
|
|
}
|
|
window.addEventListener('resize', resize);
|
|
resize();
|
|
|
|
let syncLevel = 0.5;
|
|
let targetSync = 0.5;
|
|
|
|
async function fetchRegistry() {
|
|
try {
|
|
const res = await fetch('https://forge.alexanderwhitestone.com/Timmy_Foundation/the-nexus/raw/branch/main/lazarus-registry.yaml');
|
|
const text = await res.text();
|
|
const healthy = (text.match(/status: healthy/g) || []).length;
|
|
const degraded = (text.match(/status: degraded/g) || []).length;
|
|
const dead = (text.match(/status: dead/g) || []).length;
|
|
const total = healthy + degraded + dead + 1;
|
|
targetSync = Math.max(0.1, Math.min(1.0, (healthy + 0.5 * degraded) / total));
|
|
} catch (e) {
|
|
targetSync = 0.2;
|
|
}
|
|
}
|
|
|
|
fetchRegistry();
|
|
setInterval(fetchRegistry, 30000);
|
|
|
|
let time = 0;
|
|
function draw() {
|
|
time += 0.02;
|
|
syncLevel += (targetSync - syncLevel) * 0.02;
|
|
|
|
ctx.fillStyle = 'rgba(5, 5, 5, 0.2)';
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
|
const baseRadius = 60 + syncLevel * 80;
|
|
const pulseSpeed = 0.5 + syncLevel * 1.5;
|
|
const colorHue = syncLevel > 0.7 ? 170 : syncLevel > 0.4 ? 45 : 0;
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
const offset = i * 1.2;
|
|
const radius = baseRadius + Math.sin(time * pulseSpeed + offset) * (20 + syncLevel * 40);
|
|
const alpha = 0.6 - i * 0.1;
|
|
|
|
ctx.beginPath();
|
|
ctx.arc(centerX, centerY, Math.abs(radius), 0, Math.PI * 2);
|
|
ctx.strokeStyle = `hsla(${colorHue}, 80%, 60%, ${alpha})`;
|
|
ctx.lineWidth = 3 + syncLevel * 4;
|
|
ctx.stroke();
|
|
}
|
|
|
|
// Orbiting agents
|
|
const agents = 5;
|
|
for (let i = 0; i < agents; i++) {
|
|
const angle = time * 0.3 * (i % 2 === 0 ? 1 : -1) + (i * Math.PI * 2 / agents);
|
|
const orbitR = baseRadius + 80 + i * 25;
|
|
const x = centerX + Math.cos(angle) * orbitR;
|
|
const y = centerY + Math.sin(angle) * orbitR;
|
|
|
|
ctx.beginPath();
|
|
ctx.arc(x, y, 4 + syncLevel * 4, 0, Math.PI * 2);
|
|
ctx.fillStyle = `hsl(${colorHue}, 80%, 70%)`;
|
|
ctx.fill();
|
|
}
|
|
|
|
ctx.fillStyle = '#fff';
|
|
ctx.font = '16px system-ui';
|
|
ctx.textAlign = 'center';
|
|
ctx.fillText(`Collective Stability: ${Math.round(syncLevel * 100)}%`, centerX, centerY + 8);
|
|
|
|
requestAnimationFrame(draw);
|
|
}
|
|
draw();
|
|
</script>
|
|
</body>
|
|
</html>
|