1. Mechanisme — kopieer 1-op-1, geen styling-keuzes
// Mechanisme: form-physics-feedback-playful
import gsap from 'https://esm.sh/gsap@3.12.5';
import Matter from 'https://esm.sh/matter-js@0.20.0';
const reduce=window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const form=document.querySelector('.physics-form');
const cv=document.querySelector('.physics-canvas');
const fb=document.querySelector('.physics-fallback');
if(!form||!cv)return;
form.querySelectorAll('input,textarea').forEach(i=>{
i.addEventListener('focus',()=>gsap.to(i,{scale:1.02,duration:0.5,ease:'back.out(1.7)'}));
i.addEventListener('blur',()=>gsap.to(i,{scale:1,duration:0.5,ease:'back.out(1.7)'}));
});
form.addEventListener('submit',e=>{
e.preventDefault();
if(reduce){fb.style.display='flex';gsap.fromTo(fb,{opacity:0,scale:0.8},{opacity:1,scale:1,duration:0.4});return;}
const r=cv.getBoundingClientRect();const W=r.width,H=r.height;
const{Engine,Render,Runner,Bodies,Composite}=Matter;
const eng=Engine.create();eng.world.gravity.y=1;
const rend=Render.create({canvas:cv,engine:eng,options:{width:W,height:H,wireframes:false,background:'transparent'}});
Composite.add(eng.world,[
Bodies.rectangle(W/2,H+10,W,20,{isStatic:true,render:{visible:false}}),
Bodies.rectangle(-10,H/2,20,H,{isStatic:true,render:{visible:false}}),
Bodies.rectangle(W+10,H/2,20,H,{isStatic:true,render:{visible:false}})
]);
const colors=['#FF4A1C','#FFB5A7','#F4F1EB'];
for(let i=0;i<24;i++){
setTimeout(()=>{
Composite.add(eng.world,Bodies.circle(W/2+(Math.random()-0.5)*40,-20,8+Math.random()*8,{
restitution:0.75,friction:0.02,
render:{fillStyle:colors[i%3]}
}));
},i*60);
}
Render.run(rend);Runner.run(Runner.create(),eng);
});