Files

101 lines
3.8 KiB
JavaScript
Raw Permalink Normal View History

/*
camhak.seteclabs.io boot sequence + reveals + hud
*/
// ─── HUD live clock ──────────────────────────────────────
(function clock() {
const el = document.getElementById("hud-clock");
if (!el) return;
function tick() {
const d = new Date();
const pad = n => String(n).padStart(2, "0");
el.textContent = `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}Z`;
}
tick();
setInterval(tick, 1000);
})();
// ─── Boot sequence (typewriter) ──────────────────────────
(function boot() {
const el = document.getElementById("boot");
if (!el) return;
const lines = [
{ t: "[boot] setec-rom v3.41 init", c: "ok" },
{ t: "[boot] cpu: armv7l-thumb / 2 cores / 1.0ghz", c: "ok" },
{ t: "[boot] memory map ........................ ok", c: "ok" },
{ t: "[boot] crt phosphor warmup .................. ok", c: "ok" },
{ t: "[net] link: enP4p65s0 / 192.168.1.172", c: "ok" },
{ t: "[net] upstream: setec.fun / verified", c: "ok" },
{ t: "[svc] loading payload: camhak/index", c: "" },
{ t: "[svc] decrypting findings ............... 18 records", c: "ok" },
{ t: "[warn] subject vendor unresponsive (CISA)", c: "warn" },
{ t: "[scan] uplink stable. handing off to renderer.", c: "ok" },
{ t: "", c: "" },
];
let li = 0, ci = 0;
let buf = "";
const speed = 6; // ms per char
function step() {
if (li >= lines.length) {
el.innerHTML = buf + '<span class="cur">█</span>';
return;
}
const line = lines[li];
if (ci === 0 && line.t.length === 0) {
buf += "\n";
li++;
setTimeout(step, 60);
return;
}
if (ci < line.t.length) {
ci++;
} else {
// line complete; wrap with class
const wrapped = line.c ? `<span class="${line.c}">${line.t}</span>` : line.t;
// replace the in-progress text with the wrapped version
buf = buf.replace(line.t, wrapped) + "\n";
li++;
ci = 0;
setTimeout(step, 90);
return;
}
// render in-progress (without span coloring while typing)
el.innerHTML = buf + line.t.slice(0, ci) + '<span class="cur">█</span>';
setTimeout(step, speed + Math.random() * 8);
}
step();
})();
// ─── Section reveal on scroll (one-shot) ─────────────────
(function reveal() {
if (!("IntersectionObserver" in window)) {
document.querySelectorAll(".reveal").forEach(el => el.classList.add("in-view"));
return;
}
const io = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add("in-view");
io.unobserve(e.target);
}
});
}, { rootMargin: "0px 0px -10% 0px", threshold: 0.05 });
document.querySelectorAll(".reveal").forEach(el => io.observe(el));
})();
// ─── Random subtle glitch on the hero every ~10s ─────────
(function periodicGlitch() {
const el = document.getElementById("ascii-logo");
if (!el) return;
setInterval(() => {
el.style.animation = "none";
void el.offsetWidth;
el.style.animation = "glitch-shake 0.4s linear";
}, 9000 + Math.random() * 5000);
})();