import * as THREE from 'three';
function makeMatcap() {
const size = 256;
const c = document.createElement('canvas');
c.width = size; c.height = size;
const ctx = c.getContext('2d');
ctx.fillStyle = '#14141f';
ctx.fillRect(0, 0, size, size);
const cx = size / 2, cy = size / 2, r = size / 2;
const base = ctx.createRadialGradient(cx - r * 0.3, cy - r * 0.35, r * 0.05, cx, cy, r);
base.addColorStop(0, '#dfe7ff');
base.addColorStop(0.35, '#7f8fe0');
base.addColorStop(0.7, '#3a3f8a');
base.addColorStop(1, '#0d0d20');
ctx.fillStyle = base;
ctx.fillRect(0, 0, size, size);
const spec = ctx.createRadialGradient(cx - r * 0.32, cy - r * 0.38, 0, cx - r * 0.32, cy - r * 0.38, r * 0.22);
spec.addColorStop(0, 'rgba(255,255,255,0.95)');
spec.addColorStop(1, 'rgba(255,255,255,0)');
ctx.fillStyle = spec;
ctx.fillRect(0, 0, size, size);
return c;
}
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0b0b14);
const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100);
camera.position.set(0, 0, 5);
const matcapTex = new THREE.CanvasTexture(makeMatcap());
matcapTex.colorSpace = THREE.SRGBColorSpace;
const mesh = new THREE.Mesh(new THREE.SphereGeometry(1.4, 64, 64), new THREE.MeshMatcapMaterial({ matcap: matcapTex }));
scene.add(mesh);
function resize() { renderer.setSize(innerWidth, innerHeight); camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); }
addEventListener('resize', resize); resize();
renderer.setAnimationLoop((t) => {
mesh.rotation.y = t * 0.0004;
mesh.rotation.x = Math.sin(t * 0.0002) * 0.3;
renderer.render(scene, camera);
});