.pf-cap{position:absolute;left:0;right:0;bottom:6%;text-align:center;font-size:clamp(9px,2.4vmin,13px);color:#f1f0eccc}
import * as THREE from 'three';
import { RoundedBoxGeometry } from 'three/addons/geometries/RoundedBoxGeometry.js';
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(0x0d0d12);
const camera = new THREE.PerspectiveCamera(40, 1, 0.1, 100);
camera.position.set(0, 0.4, 5.6);
const canvas = document.createElement('canvas');
canvas.width = 128; canvas.height = 128;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#8a8a8a'; ctx.fillRect(0, 0, 128, 128);
ctx.strokeStyle = '#6f6f6f'; ctx.lineWidth = 2;
for (let y = 4; y < 128; y += 8) { ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(128, y); ctx.stroke(); }
const layerTex = new THREE.CanvasTexture(canvas);
const geo = new RoundedBoxGeometry(1.3, 2, 0.6, 3, 0.1);
const stages = [
{ mat: new THREE.MeshStandardMaterial({ color: 0x9a9a94, roughness: 1, metalness: 0 }), label: 'stage 1 — foam block' },
{ mat: new THREE.MeshStandardMaterial({ map: layerTex, roughness: 0.85, metalness: 0 }), label: 'stage 2 — 3D print' },
{ mat: new THREE.MeshPhysicalMaterial({ color: 0x5b5bf7, roughness: 0.15, metalness: 0.1, clearcoat: 1 }), label: 'stage 3 — production finish' },
];
const mesh = new THREE.Mesh(geo, stages[0].mat);
scene.add(mesh);
const key = new THREE.DirectionalLight(0xffffff, 2.1); key.position.set(3, 4, 5); scene.add(key);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
const cap = document.querySelector('.pf-cap');
function resize() { renderer.setSize(innerWidth, innerHeight); camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); }
addEventListener('resize', resize); resize();
let idx = 0;
cap.textContent = stages[0].label;
setInterval(() => {
idx = (idx + 1) % stages.length;
mesh.material = stages[idx].mat;
cap.textContent = stages[idx].label;
}, 1600);
renderer.setAnimationLoop((t) => {
mesh.rotation.y = t * 0.00045;
camera.lookAt(0, 0, 0);
renderer.render(scene, camera);
});