Models 44

Muse Ember

Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
13.8 s
Cost
$0.0035
Output tokens
6,870
Spent thinking
955 tokens
Speed
609.6 tok/s
Console errors
0
First token after
2.6 s
First visible text after
4.5 s
Prompt tokens
441
Code size
17.6 KB
Finish reason
stop
Served by
Meta
Model id
meta/muse-ember
Reasoning sent
{"effort":"low"}
Max output
943,718 tokens
Generated
Nov 12, 2026

What it was asked

The prompt
“a 3D aquarium with Three.js where the fish swim away when I move the mouse near them (Load Three.js only through this import map: <script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"}}</script>)”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task.

Output rules:
- Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block.
- Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task.
- Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw.
- The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar.
- Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction.
- Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session.
- Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing.
- The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message.
- The code must run with zero errors in the console of the latest Chrome.

Code run-1.html · 388 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Aquarium — Fish Flee From Your Cursor</title>
<style>
  *{margin:0;padding:0;box-sizing:border-box}
  html,body{width:100%;height:100%;overflow:hidden;background:#021a2e;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;color:#e8f6ff}
  #app{position:fixed;inset:0}
  canvas{display:block}
  .ui{position:fixed;inset:0;pointer-events:none;display:flex;flex-direction:column;justify-content:space-between;padding:18px}
  .top{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap}
  .card{background:rgba(2,32,56,.62);backdrop-filter:blur(12px);border:1px solid rgba(125,211,252,.35);border-radius:18px;padding:14px 18px;box-shadow:0 10px 30px rgba(0,0,0,.35)}
  h1{font-size:clamp(22px,4vw,38px);line-height:1;letter-spacing:.02em}
  h1 span{color:#38e1ff}
  .sub{margin-top:6px;font-size:13px;color:#b9e6ff;max-width:520px;line-height:1.4}
  .stats{display:flex;gap:16px;text-align:center}
  .stat b{font-size:22px;color:#fff;display:block}
  .stat small{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:#7dd3fc}
  .fleeBox{min-width:170px}
  .bar{height:10px;background:rgba(255,255,255,.15);border-radius:99px;overflow:hidden;margin-top:8px}
  .bar i{display:block;height:100%;width:0%;background:linear-gradient(90deg,#38e1ff,#ffb020,#ff4d6d);transition:width .15s}
  .bottom{display:flex;justify-content:space-between;align-items:flex-end;gap:12px;flex-wrap:wrap}
  .hint{font-size:13px;line-height:1.6}
  .hint b{color:#fff}
  .pill{display:inline-block;background:#0ea5e9;color:#fff;font-weight:700;font-size:11px;letter-spacing:.08em;text-transform:uppercase;padding:5px 9px;border-radius:99px;margin-right:6px}
  #toast{background:#ff3b5c;color:#fff;font-weight:800;padding:10px 14px;border-radius:99px;font-size:13px;box-shadow:0 8px 20px rgba(255,59,92,.45);transform:translateY(20px);opacity:0;transition:.25s}
  #toast.show{transform:translateY(0);opacity:1}
  .controls{pointer-events:auto;display:flex;gap:8px}
  button{pointer-events:auto;border:1px solid rgba(125,211,252,.5);background:rgba(3,43,72,.8);color:#fff;padding:9px 13px;border-radius:99px;font-weight:700;cursor:pointer}
  button:hover{background:#0369a1}
  @media(max-width:640px){.stats{display:none}.sub{display:none}.ui{padding:12px}}
</style>
<script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"}}</script>
</head>
<body>
<div id="app"></div>
<div class="ui">
  <div class="top">
    <div class="card">
      <h1>🐠 3D <span>AQUARIUM</span></h1>
      <p class="sub">Move your mouse through the tank — nearby fish get startled and dart away. Drag to orbit, scroll to zoom. When idle, a demo cursor swims through so you can watch them flee.</p>
    </div>
    <div class="card stats">
      <div class="stat"><b id="fishCount">18</b><small>Fish</small></div>
      <div class="stat"><b id="fleeCount">0</b><small>Startled</small></div>
      <div class="stat fleeBox"><b id="danger">CALM</b><small>Flee intensity</small><div class="bar"><i id="barFill"></i></div></div>
    </div>
  </div>
  <div class="bottom">
    <div class="card hint"><span class="pill">Move mouse</span> <b>Sweep cursor near fish</b> &nbsp;•&nbsp; <b>Drag</b> orbit &nbsp;•&nbsp; <b>Scroll</b> zoom<br><span style="color:#93c5fd">The glowing orb is your cursor inside the water. Fish within ~3m scatter!</span></div>
    <div style="display:flex;gap:10px;align-items:center">
      <div id="toast">⚡ FISH STARTLED!</div>
      <div class="controls"><button id="feedBtn">🍤 Drop Food</button><button id="scatterBtn">💨 Scatter All</button></div>
    </div>
  </div>
</div>

<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const app=document.getElementById('app');
const scene=new THREE.Scene();
scene.background=new THREE.Color(0x042e4d);
scene.fog=new THREE.FogExp2(0x073a5e,0.018);

const camera=new THREE.PerspectiveCamera(55,innerWidth/innerHeight,0.1,100);
camera.position.set(0,3.2,17);

const renderer=new THREE.WebGLRenderer({antialias:true});
renderer.setSize(innerWidth,innerHeight);
renderer.setPixelRatio(Math.min(devicePixelRatio,2));
renderer.shadowMap.enabled=true;
renderer.toneMapping=THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure=1.1;
app.appendChild(renderer.domElement);

const controls=new OrbitControls(camera,renderer.domElement);
controls.enableDamping=true; controls.dampingFactor=0.06;
controls.target.set(0,0.3,0);
controls.minDistance=6; controls.maxDistance=28;
controls.maxPolarAngle=Math.PI*0.62;

// Lights
scene.add(new THREE.AmbientLight(0x7dd3fc,0.7));
const sun=new THREE.DirectionalLight(0xffffff,1.6); sun.position.set(6,12,8); sun.castShadow=true; scene.add(sun);
const topLight=new THREE.SpotLight(0xaee9ff,120,40,0.6,0.5); topLight.position.set(0,10,0); scene.add(topLight);
const blueGlow=new THREE.PointLight(0x0ea5e9,30,20); blueGlow.position.set(-6,2,3); scene.add(blueGlow);

// Tank dimensions
const W=22,H=11,D=9;
const bounds={x:W/2-1.2,y:H/2-1.2,z:D/2-1.2};

// Water volume (inner box, very transparent)
const water=new THREE.Mesh(new THREE.BoxGeometry(W,H,D),new THREE.MeshPhysicalMaterial({color:0x0ea5e9,transparent:true,opacity:0.08,roughness:0.1,metalness:0,side:THREE.BackSide}));
scene.add(water);

// Glass
const glass=new THREE.Mesh(new THREE.BoxGeometry(W+0.3,H+0.3,D+0.3),new THREE.MeshPhysicalMaterial({color:0xffffff,transparent:true,opacity:0.07,roughness:0.05,metalness:0.1,side:THREE.BackSide}));
scene.add(glass);
// Frame edges
const frameMat=new THREE.MeshStandardMaterial({color:0x0f172a,roughness:0.4,metalness:0.6});
function edge(w,h,d,x,y,z){const m=new THREE.Mesh(new THREE.BoxGeometry(w,h,d),frameMat);m.position.set(x,y,z);scene.add(m);}
edge(W+0.4,0.35,D+0.4,0,-H/2-0.15,0); edge(W+0.4,0.35,D+0.4,0,H/2+0.15,0);
edge(0.35,H+0.4,0.35,-W/2-0.15,0,-D/2); edge(0.35,H+0.4,0.35,W/2+0.15,0,-D/2);
edge(0.35,H+0.4,0.35,-W/2-0.15,0,D/2); edge(0.35,H+0.4,0.35,W/2+0.15,0,D/2);

// Sand
const sand=new THREE.Mesh(new THREE.PlaneGeometry(W,D,32,16),new THREE.MeshStandardMaterial({color:0xe8cf9a,roughness:1}));
sand.rotation.x=-Math.PI/2; sand.position.y=-H/2+0.02; sand.receiveShadow=true;
{ const pos=sand.geometry.attributes.position; for(let i=0;i<pos.count;i++){ pos.setZ(i,(Math.random()-0.5)*0.35);} sand.geometry.computeVertexNormals(); }
scene.add(sand);

// Pebbles & rocks
for(let i=0;i<70;i++){
  const s=0.15+Math.random()*0.45;
  const m=new THREE.Mesh(new THREE.SphereGeometry(s,7,6),new THREE.MeshStandardMaterial({color:new THREE.Color().setHSL(Math.random()*0.1,0.2,0.45+Math.random()*0.3),roughness:1}));
  m.scale.y=0.5; m.position.set((Math.random()-0.5)*(W-2),-H/2+0.15,(Math.random()-0.5)*(D-1.5));
  scene.add(m);
}
for(let i=0;i<7;i++){
  const m=new THREE.Mesh(new THREE.DodecahedronGeometry(0.8+Math.random()*0.9),new THREE.MeshStandardMaterial({color:0x64748b,roughness:1,flatShading:true}));
  m.position.set(-9+i*3+Math.random(),-H/2+0.4,(Math.random()-0.5)*5); m.rotation.set(Math.random(),Math.random(),Math.random()); m.castShadow=true; scene.add(m);
}

// Plants (swaying)
const plants=[];
function makePlant(x,z,scale){
  const g=new THREE.Group();
  const mat=new THREE.MeshStandardMaterial({color:0x22c55e,roughness:0.8,side:THREE.DoubleSide});
  for(let i=0;i<6;i++){
    const h=1.6+Math.random()*2.2;
    const leaf=new THREE.Mesh(new THREE.ConeGeometry(0.16,h,6),mat);
    leaf.position.set((Math.random()-0.5)*0.7,h/2,(Math.random()-0.5)*0.5);
    leaf.rotation.z=(Math.random()-0.5)*0.5; leaf.rotation.x=(Math.random()-0.5)*0.4;
    g.add(leaf);
  }
  g.position.set(x,-H/2+0.2,z); g.scale.setScalar(scale); scene.add(g); plants.push(g);
}
[[-9,-2],[-7.5,2],[-4,-3],[3,-2.5],[6,2],[8.5,-3],[9.5,1.5],[-2,3.2],[4.5,3]].forEach(p=>makePlant(p[0],p[1],0.9+Math.random()*0.6));

// Bubbles
const bubbleGeo=new THREE.SphereGeometry(0.07,8,8);
const bubbleMat=new THREE.MeshPhysicalMaterial({color:0xccf6ff,transparent:true,opacity:0.55,roughness:0});
const bubbles=[];
for(let i=0;i<90;i++){
  const b=new THREE.Mesh(bubbleGeo,bubbleMat);
  b.position.set((Math.random()-0.5)*(W-2),(Math.random()-0.5)*H,(Math.random()-0.5)*(D-2));
  b.userData.speed=0.6+Math.random()*1.4; b.userData.wob=Math.random()*Math.PI*2;
  const s=0.6+Math.random()*1.4; b.scale.setScalar(s); scene.add(b); bubbles.push(b);
}

// Light rays
const rayMat=new THREE.MeshBasicMaterial({color:0xa5f3fc,transparent:true,opacity:0.07,side:THREE.DoubleSide,depthWrite:false});
for(let i=0;i<5;i++){
  const r=new THREE.Mesh(new THREE.PlaneGeometry(1.2, H+2),rayMat);
  r.position.set(-7+i*3.5,0,-0.5); r.rotation.z=0.35; scene.add(r);
}

// Cursor orb
const orb=new THREE.Mesh(new THREE.SphereGeometry(0.34,20,20),new THREE.MeshBasicMaterial({color:0xff3b5c}));
const orbGlow=new THREE.Mesh(new THREE.SphereGeometry(0.6,20,20),new THREE.MeshBasicMaterial({color:0xff3b5c,transparent:true,opacity:0.25}));
orb.add(orbGlow); orb.position.set(4,1,0); scene.add(orb);
const ring=new THREE.Mesh(new THREE.TorusGeometry(0.85,0.03,8,32),new THREE.MeshBasicMaterial({color:0xff8fa3}));
orb.add(ring);

// Food particles
const foods=[];
function dropFood(){
  for(let i=0;i<14;i++){
    const f=new THREE.Mesh(new THREE.SphereGeometry(0.09,6,6),new THREE.MeshStandardMaterial({color:0xffb020}));
    f.position.set((Math.random()-0.5)*6, H/2-0.5,(Math.random()-0.5)*3);
    f.userData.v=new THREE.Vector3((Math.random()-0.5)*0.2,-0.3,(Math.random()-0.5)*0.2);
    scene.add(f); foods.push(f);
  }
}

// Fish creation
const fishes=[];
const palette=[0xff7b1c,0xffc107,0x38bdf8,0xf472b6,0xa78bfa,0x34d399,0xff4d4d,0xfacc15,0x22d3ee,0xfb923c];
function makeFish(color,scale){
  const g=new THREE.Group();
  const mat=new THREE.MeshStandardMaterial({color,roughness:0.45,metalness:0.15});
  const body=new THREE.Mesh(new THREE.SphereGeometry(0.55,20,16),mat);
  body.scale.set(1.6,0.75,0.45); body.castShadow=true; g.add(body);
  // tail
  const tailShape=new THREE.Shape(); tailShape.moveTo(0,0); tailShape.lineTo(-0.7,0.45); tailShape.lineTo(-0.55,0); tailShape.lineTo(-0.7,-0.45); tailShape.closePath();
  const tail=new THREE.Mesh(new THREE.ShapeGeometry(tailShape),new THREE.MeshStandardMaterial({color,side:THREE.DoubleSide,roughness:0.5}));
  tail.position.x=-0.8; g.add(tail);
  // dorsal fin
  const fin=new THREE.Mesh(new THREE.ConeGeometry(0.22,0.5,4),new THREE.MeshStandardMaterial({color:0xffffff,transparent:true,opacity:0.65,side:THREE.DoubleSide}));
  fin.position.set(0,0.45,0); fin.scale.set(1.4,1,0.3); g.add(fin);
  // eyes
  const eyeMat=new THREE.MeshBasicMaterial({color:0x111111});
  [-0.18,0.18].forEach(z=>{
    const eye=new THREE.Mesh(new THREE.SphereGeometry(0.08,10,10),eyeMat);
    eye.position.set(0.62,0.12,z); g.add(eye);
    const spark=new THREE.Mesh(new THREE.SphereGeometry(0.03,6,6),new THREE.MeshBasicMaterial({color:0xffffff}));
    spark.position.set(0.68,0.16,z+(z>0?0.04:-0.04)); g.add(spark);
  });
  // stripes for clown-like
  for(let i=0;i<2;i++){
    const stripe=new THREE.Mesh(new THREE.TorusGeometry(0.38,0.05,6,20),new THREE.MeshBasicMaterial({color:0xffffff,transparent:true,opacity:0.85}));
    stripe.position.x=0.2-i*0.5; stripe.rotation.y=Math.PI/2; stripe.scale.set(1,0.85,1); g.add(stripe);
  }
  g.scale.setScalar(scale);
  g.userData={body,tail,fin,phase:Math.random()*Math.PI*2,speed:1.6+Math.random()*1.2};
  return g;
}

for(let i=0;i<18;i++){
  const color=palette[i%palette.length];
  const fish=makeFish(color,0.65+Math.random()*0.55);
  fish.position.set((Math.random()-0.5)*16,(Math.random()-0.5)*7,(Math.random()-0.5)*5);
  scene.add(fish);
  fishes.push({
    group:fish, vel:new THREE.Vector3(Math.random()-0.5,0,Math.random()-0.5).normalize().multiplyScalar(2),
    target:new THREE.Vector3(), flee:0, wasFleeing:false, baseSpeed:1.8+Math.random()*1.4
  });
}

// Mouse / demo cursor
const mousePoint=new THREE.Vector3(4,1,0);
const raycaster=new THREE.Raycaster();
const pointerNDC=new THREE.Vector2();
let lastRealMouse=0;
let demoTime=0;
let totalStartled=0;
const fleeCountEl=document.getElementById('fleeCount'), dangerEl=document.getElementById('danger'), barEl=document.getElementById('barFill'), toast=document.getElementById('toast');

addEventListener('pointermove',e=>{
  lastRealMouse=performance.now();
  pointerNDC.x=(e.clientX/innerWidth)*2-1;
  pointerNDC.y=-(e.clientY/innerHeight)*2+1;
  raycaster.setFromCamera(pointerNDC,camera);
  const planeZ=new THREE.Plane(new THREE.Vector3(0,0,1),0);
  const hit=new THREE.Vector3();
  if(raycaster.ray.intersectPlane(planeZ,hit)){
    mousePoint.copy(hit);
    mousePoint.x=THREE.MathUtils.clamp(mousePoint.x,-bounds.x,bounds.x);
    mousePoint.y=THREE.MathUtils.clamp(mousePoint.y,-bounds.y,bounds.y);
    mousePoint.z=0;
  }
});

document.getElementById('feedBtn').onclick=dropFood;
document.getElementById('scatterBtn').onclick=()=>{
  fishes.forEach(f=>{
    const away=f.group.position.clone().sub(mousePoint);
    if(away.lengthSq()<0.01) away.set(Math.random()-0.5,0,Math.random()-0.5);
    f.vel.copy(away.normalize().multiplyScalar(9));
    f.flee=1;
  });
  showToast();
};
let toastTimer;
function showToast(){
  toast.classList.add('show'); clearTimeout(toastTimer);
  toastTimer=setTimeout(()=>toast.classList.remove('show'),1200);
}

const clock=new THREE.Clock();
function animate(){
  requestAnimationFrame(animate);
  const dt=Math.min(clock.getDelta(),0.05);
  const t=clock.elapsedTime;

  // Demo cursor when idle >2.5s
  if(performance.now()-lastRealMouse>2500){
    demoTime+=dt;
    mousePoint.set(Math.sin(demoTime*0.55)*7, Math.sin(demoTime*0.9)*2.8+0.5, Math.cos(demoTime*0.4)*0.5);
  }
  orb.position.copy(mousePoint);
  orbGlow.scale.setScalar(1+Math.sin(t*6)*0.2);
  ring.rotation.x=t*1.5; ring.rotation.y=t*2;

  // Plants sway
  plants.forEach((p,i)=>{ p.rotation.z=Math.sin(t*1.2+i)*0.07; p.rotation.x=Math.cos(t*0.9+i)*0.05; });

  // Bubbles
  bubbles.forEach(b=>{
    b.position.y+=b.userData.speed*dt;
    b.position.x+=Math.sin(t*2+b.userData.wob)*0.003;
    if(b.position.y>H/2-0.3){ b.position.y=-H/2+0.3; b.position.x=(Math.random()-0.5)*(W-2); }
  });

  // Food sink
  for(let i=foods.length-1;i>=0;i--){
    const f=foods[i]; f.position.addScaledVector(f.userData.v,dt);
    let eaten=false;
    fishes.forEach(fs=>{
      if(fs.group.position.distanceTo(f.position)<0.7){
        fs.vel.add(new THREE.Vector3(0,0.5,0));
        eaten=true;
      }
    });
    if(eaten||f.position.y<-H/2+0.3){ scene.remove(f); foods.splice(i,1); }
  }

  let fleeingNow=0;
  // Fish AI
  fishes.forEach((f,idx)=>{
    const pos=f.group.position;
    const distToMouse=pos.distanceTo(mousePoint);
    const dangerRadius=3.4;
    let isFleeing=false;

    if(distToMouse<dangerRadius){
      isFleeing=true; fleeingNow++;
      const away=pos.clone().sub(mousePoint).normalize();
      // also push away from walls
      away.y+= (Math.random()-0.5)*0.4;
      f.vel.lerp(away.multiplyScalar(8.5),0.18);
      f.flee=Math.min(1,f.flee+dt*3);
      if(!f.wasFleeing){ totalStartled++; fleeCountEl.textContent=totalStartled; showToast(); }
    } else {
      f.flee=Math.max(0,f.flee-dt*1.2);
      // wander
      if(pos.distanceTo(f.target)<1.2 || f.target.lengthSq()===0){
        f.target.set((Math.random()-0.5)*(W-4),(Math.random()-0.5)*(H-4),(Math.random()-0.5)*(D-3));
      }
      const desired=f.target.clone().sub(pos).normalize().multiplyScalar(f.baseSpeed);
      f.vel.lerp(desired,0.03);
      // separation
      fishes.forEach(o=>{
        if(o!==f){
          const d=pos.distanceTo(o.group.position);
          if(d<1.2 && d>0.001) f.vel.add(pos.clone().sub(o.group.position).normalize().multiplyScalar(0.08));
        }
      });
    }
    f.wasFleeing=isFleeing;

    // wall avoidance
    if(Math.abs(pos.x)>bounds.x) f.vel.x-=Math.sign(pos.x)*2.5*dt*10;
    if(Math.abs(pos.y)>bounds.y) f.vel.y-=Math.sign(pos.y)*2.5*dt*10;
    if(Math.abs(pos.z)>bounds.z) f.vel.z-=Math.sign(pos.z)*2.5*dt*10;
    // food attraction
    if(foods.length){
      const nearest=foods.reduce((a,b)=>a.position.distanceTo(pos)<b.position.distanceTo(pos)?a:b);
      if(nearest.position.distanceTo(pos)<6) f.vel.lerp(nearest.position.clone().sub(pos).normalize().multiplyScalar(3),0.04);
    }

    const maxSpeed=isFleeing?9:4.2;
    if(f.vel.length()>maxSpeed) f.vel.setLength(maxSpeed);
    if(f.vel.length()<0.5) f.vel.setLength(0.5);

    pos.addScaledVector(f.vel,dt);
    pos.x=THREE.MathUtils.clamp(pos.x,-bounds.x,bounds.x);
    pos.y=THREE.MathUtils.clamp(pos.y,-bounds.y,bounds.y);
    pos.z=THREE.MathUtils.clamp(pos.z,-bounds.z,bounds.z);

    // orient fish toward velocity
    const look=pos.clone().add(f.vel);
    f.group.lookAt(look);
    // tail wag (faster when fleeing)
    const wagSpeed=6+f.flee*22;
    const wag=Math.sin(t*wagSpeed+f.group.userData.phase)*(0.45+f.flee*0.5);
    f.group.userData.tail.rotation.y=wag;
    f.group.userData.body.rotation.z=Math.sin(t*wagSpeed*0.5+f.group.userData.phase)*0.08;
    f.group.userData.fin.rotation.z=Math.sin(t*5+f.group.userData.phase)*0.2;
    f.group.position.y+=Math.sin(t*2+f.group.userData.phase)*0.002;
  });

  const intensity=fleeingNow/fishes.length;
  barEl.style.width=(intensity*100)+'%';
  dangerEl.textContent=intensity>0.4?'PANIC!':intensity>0.15?'STARTLED':'CALM';
  dangerEl.style.color=intensity>0.4?'#ff8fa3':intensity>0.15?'#fbbf24':'#fff';
  orb.material.color.setHSL(0.98-intensity*0.4,0.9,0.55);

  controls.update();
  renderer.render(scene,camera);
}
animate();

// initial food for movement interest
setTimeout(dropFood,800);

addEventListener('resize',()=>{
  camera.aspect=innerWidth/innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth,innerHeight);
});
</script>
</body>
</html>
Reasoning trace (955 tokens)
Designing a single-file ThreeJS aquarium with procedural fish, physics-based flee behavior via mouse raycasting, and environment rendering.Adding OrbitControls, UI overlay, particles, plants, caustics, and idle demo mouse behavior.