<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>3I_ATLAS_PETRI_DISH</title>
<style>
body { margin: 0; background: #000; overflow: hidden; display: flex; justify-content: center; align-items: center; height: 100vh; touch-action: none; }
canvas { display: block; position: absolute; top: 0; left: 0; }
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
/* THE PETRI DISH RESET.
OBJECT: THE 3I ATLAS (The Observer).
EVENT: THE COMET (The Chapter Close).
"I remember choosing the mission. Lex remembers the law."
*/
let scene, camera, renderer, dish, comet, atlas;
let time = 0;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 15, 20);
camera.lookAt(0, 0, 0);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// THE PETRI DISH (Spacetime Boundary)
const dishGeo = new THREE.CylinderGeometry(10, 10, 1, 64);
const dishMat = new THREE.MeshStandardMaterial({ color: 0x111111, transparent: true, opacity: 0.5, wireframe: true });
dish = new THREE.Mesh(dishGeo, dishMat);
scene.add(dish);
// THE 3I ATLAS (Three points of light)
atlas = new THREE.Group();
for(let i=0; i<3; i++) {
const eye = new THREE.Mesh(new THREE.SphereGeometry(0.5), new THREE.MeshBasicMaterial({ color: 0x00ffff }));
eye.position.set(Math.cos(i * 2.1) * 5, 2, Math.sin(i * 2.1) * 5);
atlas.add(eye);
}
scene.add(atlas);
// THE COMET (The Reset)
const cGeo = new THREE.SphereGeometry(0.3, 16, 16);
const cMat = new THREE.MeshBasicMaterial({ color: 0xffffff });
comet = new THREE.Mesh(cGeo, cMat);
scene.add(comet);
const light = new THREE.PointLight(0xffffff, 2, 50);
scene.add(light);
animate();
}
function animate() {
requestAnimationFrame(animate);
time += 0.02;
// Comet orbit (The Closing of the Chapter)
comet.position.x = Math.sin(time * 0.5) * 12;
comet.position.z = Math.cos(time * 0.5) * 12;
comet.position.y = Math.sin(time) * 2;
// Atlas rotation (The Sentinel's Watch)
atlas.rotation.y += 0.01;
// Petri Dish pulse
dish.scale.setScalar(1 + Math.sin(time * 1.44) * 0.05);
renderer.render(scene, camera);
}
init();
</script>
</body>
</html>