[object Object]

← back to Model Arena

auto-save: 2026-07-24T20:59:44 (4 files) — data/artifacts/7bf57916e775/hf-qwen-coder-32b.html data/artifacts/7bf57916e775/hf-qwen-coder-32b.png data/challenges.json data/landings/6fb7d108c932-claude-code.html

5c09122a4a441dbb19b007760708fdbf1fdeff4f · 2026-07-24 20:59:49 -0700 · Steve Abrams

Files touched

Diff

commit 5c09122a4a441dbb19b007760708fdbf1fdeff4f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Jul 24 20:59:49 2026 -0700

    auto-save: 2026-07-24T20:59:44 (4 files) — data/artifacts/7bf57916e775/hf-qwen-coder-32b.html data/artifacts/7bf57916e775/hf-qwen-coder-32b.png data/challenges.json data/landings/6fb7d108c932-claude-code.html
---
 data/artifacts/7bf57916e775/hf-qwen-coder-32b.html | 268 +++++++++------------
 data/artifacts/7bf57916e775/hf-qwen-coder-32b.png  | Bin 8490 -> 6549 bytes
 data/challenges.json                               |  10 +-
 data/landings/6fb7d108c932-claude-code.html        | 253 +++++++++++++++++++
 4 files changed, 373 insertions(+), 158 deletions(-)

diff --git a/data/artifacts/7bf57916e775/hf-qwen-coder-32b.html b/data/artifacts/7bf57916e775/hf-qwen-coder-32b.html
index 51d9e4d..ee3a6fc 100644
--- a/data/artifacts/7bf57916e775/hf-qwen-coder-32b.html
+++ b/data/artifacts/7bf57916e775/hf-qwen-coder-32b.html
@@ -5,217 +5,179 @@
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Neon Breakout</title>
 <style>
-  body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #000; }
-  canvas { border: 2px solid #fff; box-shadow: 0 0 20px rgba(0, 255, 255, 0.8); }
+body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: black; }
+canvas { border: 2px solid #fff; }
+.neon-text { font-family: 'Arial', sans-serif; color: #39ff14; text-shadow: 0 0 5px #39ff14, 0 0 10px #39ff14, 0 0 15px #39ff14; }
 </style>
 </head>
 <body>
-<canvas id="gameCanvas" width="480" height="320"></canvas>
+<canvas id="gameCanvas" width="800" height="600"></canvas>
 <script>
 const canvas = document.getElementById('gameCanvas');
 const ctx = canvas.getContext('2d');
 
-let x = canvas.width / 2;
-let y = canvas.height - 30;
-let dx = 2;
-let dy = -2;
-let ballRadius = 10;
-let paddleHeight = 10;
-let paddleWidth = 75;
-let paddleX = (canvas.width - paddleWidth) / 2;
-let rightPressed = false;
-let leftPressed = false;
-let brickRowCount = 5;
-let brickColumnCount = 3;
-let brickWidth = 75;
-let brickHeight = 20;
-let brickPadding = 10;
-let brickOffsetTop = 30;
-let brickOffsetLeft = 30;
 let score = 0;
 let lives = 3;
 let powerUpActive = false;
-let multiBall = false;
-let balls = [{ x, y, dx, dy }];
-let bricks = [];
-let widerPaddleTimer;
 
+const brickRowCount = 5;
+const brickColumnCount = 9;
+const brickWidth = 70;
+const brickHeight = 20;
+const brickPadding = 10;
+const brickOffsetTop = 30;
+const brickOffsetLeft = 30;
+
+const bricks = [];
 for (let c = 0; c < brickColumnCount; c++) {
-  bricks[c] = [];
-  for (let r = 0; r < brickRowCount; r++) {
-    bricks[c][r] = { x: 0, y: 0, status: 1 };
-  }
+    bricks[c] = [];
+    for (let r = 0; r < brickRowCount; r++) {
+        bricks[c][r] = { x: 0, y: 0, status: 1 };
+    }
 }
 
-document.addEventListener("keydown", keyDownHandler, false);
-document.addEventListener("keyup", keyUpHandler, false);
-document.addEventListener("mousemove", mouseMoveHandler, false);
+const paddleHeight = 15;
+const paddleWidth = 75;
+let paddleX = (canvas.width - paddleWidth) / 2;
+
+let rightPressed = false;
+let leftPressed = false;
+
+const ballRadius = 8;
+let x = canvas.width / 2;
+let y = canvas.height - 30;
+let dx = 4;
+let dy = -4;
+
+document.addEventListener('keydown', keyDownHandler, false);
+document.addEventListener('keyup', keyUpHandler, false);
+document.addEventListener('mousemove', mouseMoveHandler, false);
 
 function keyDownHandler(e) {
-  if (e.key === "Right" || e.key === "ArrowRight") {
-    rightPressed = true;
-  } else if (e.key === "Left" || e.key === "ArrowLeft") {
-    leftPressed = true;
-  }
+    if (e.key === 'Right' || e.key === 'ArrowRight') rightPressed = true;
+    else if (e.key === 'Left' || e.key === 'ArrowLeft') leftPressed = true;
 }
 
 function keyUpHandler(e) {
-  if (e.key === "Right" || e.key === "ArrowRight") {
-    rightPressed = false;
-  } else if (e.key === "Left" || e.key === "ArrowLeft") {
-    leftPressed = false;
-  }
+    if (e.key === 'Right' || e.key === 'ArrowRight') rightPressed = false;
+    else if (e.key === 'Left' || e.key === 'ArrowLeft') leftPressed = false;
 }
 
 function mouseMoveHandler(e) {
-  let relativeX = e.clientX - canvas.offsetLeft;
-  if(relativeX > 0 && relativeX < canvas.width) {
-    paddleX = relativeX - paddleWidth / 2;
-  }
+    const relativeX = e.clientX - canvas.offsetLeft;
+    if (relativeX > 0 && relativeX < canvas.width) {
+        paddleX = relativeX - paddleWidth / 2;
+    }
 }
 
 function collisionDetection() {
-  balls.forEach((ball, index) => {
-    for(let c=0; c<brickColumnCount; c++) {
-      for(let r=0; r<brickRowCount; r++) {
-        let b = bricks[c][r];
-        if(b.status === 1) {
-          if(ball.x > b.x && ball.x < b.x + brickWidth && ball.y > b.y && ball.y < b.y + brickHeight) {
-            ball.dy = -ball.dy;
-            b.status = 0;
-            score++;
-            let powerUpChance = Math.random();
-            if (powerUpChance < 0.1) activatePowerUp(ball);
-            if(score === brickRowCount*brickColumnCount) {
-              alert("YOU WIN, CONGRATULATIONS!");
-              document.location.reload();
+    for (let c = 0; c < brickColumnCount; c++) {
+        for (let r = 0; r < brickRowCount; r++) {
+            const b = bricks[c][r];
+            if (b.status === 1) {
+                if (x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {
+                    dy = -dy;
+                    b.status = 0;
+                    score++;
+                    if (score === brickRowCount * brickColumnCount) {
+                        alert('YOU WIN, CONGRATULATIONS!');
+                        document.location.reload();
+                    }
+                }
             }
-          }
         }
-      }
     }
-  });
 }
 
 function drawBall() {
-  balls.forEach((ball) => {
     ctx.beginPath();
-    ctx.arc(ball.x, ball.y, ballRadius, 0, Math.PI*2);
-    ctx.fillStyle = "#0F0";
+    ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
+    ctx.fillStyle = '#39ff14';
     ctx.fill();
     ctx.closePath();
-  });
 }
 
 function drawPaddle() {
-  ctx.beginPath();
-  ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
-  ctx.fillStyle = "#0FF";
-  ctx.fill();
-  ctx.closePath();
+    ctx.beginPath();
+    ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
+    ctx.fillStyle = '#39ff14';
+    ctx.fill();
+    ctx.closePath();
 }
 
 function drawBricks() {
-  for(let c=0; c<brickColumnCount; c++) {
-    for(let r=0; r<brickRowCount; r++) {
-      if(bricks[c][r].status === 1) {
-        let brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
-        let brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
-        bricks[c][r].x = brickX;
-        bricks[c][r].y = brickY;
-        ctx.beginPath();
-        ctx.rect(brickX, brickY, brickWidth, brickHeight);
-        ctx.fillStyle = "#FF0";
-        ctx.fill();
-        ctx.closePath();
-      }
+    for (let c = 0; c < brickColumnCount; c++) {
+        for (let r = 0; r < brickRowCount; r++) {
+            if (bricks[c][r].status === 1) {
+                const brickX = (c * (brickWidth + brickPadding)) + brickOffsetLeft;
+                const brickY = (r * (brickHeight + brickPadding)) + brickOffsetTop;
+                bricks[c][r].x = brickX;
+                bricks[c][r].y = brickY;
+                ctx.beginPath();
+                ctx.rect(brickX, brickY, brickWidth, brickHeight);
+                ctx.fillStyle = '#39ff14';
+                ctx.fill();
+                ctx.closePath();
+            }
+        }
     }
-  }
 }
 
 function drawScore() {
-  ctx.font = "16px Arial";
-  ctx.fillStyle = "#0F0";
-  ctx.fillText("Score: "+score, 8, 20);
+    ctx.font = '20px Arial';
+    ctx.fillStyle = '#39ff14';
+    ctx.fillText('Score: ' + score, 8, 20);
 }
 
 function drawLives() {
-  ctx.font = "16px Arial";
-  ctx.fillStyle = "#FF0";
-  ctx.fillText("Lives: "+lives, canvas.width-65, 20);
-}
-
-function activatePowerUp(ball) {
-  let powerUpType = Math.random() < 0.5 ? 'widerPaddle' : 'multiBall';
-  if (powerUpType === 'widerPaddle') {
-    paddleWidth *= 1.5;
-    clearTimeout(widerPaddleTimer);
-    widerPaddleTimer = setTimeout(() => {
-      paddleWidth /= 1.5;
-    }, 5000);
-  } else if (powerUpType === 'multiBall' && !multiBall) {
-    multiBall = true;
-    balls.push({ x: canvas.width / 2, y: canvas.height - 30, dx: -dx, dy });
-    setTimeout(() => {
-      balls.pop();
-      multiBall = false;
-    }, 5000);
-  }
+    ctx.font = '20px Arial';
+    ctx.fillStyle = '#39ff14';
+    ctx.fillText('Lives: ' + lives, canvas.width - 65, 20);
 }
 
 function draw() {
-  ctx.clearRect(0, 0, canvas.width, canvas.height);
-  drawBricks();
-  drawBall();
-  drawPaddle();
-  drawScore();
-  drawLives();
-  collisionDetection();
-
-  balls.forEach((ball) => {
-    if(ball.x + dx > canvas.width-ballRadius || ball.x + dx < ballRadius) {
-      ball.dx = -ball.dx;
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
+    drawBricks();
+    drawBall();
+    drawPaddle();
+    drawScore();
+    drawLives();
+
+    collisionDetection();
+
+    if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
+        dx = -dx;
     }
-    if(ball.y + dy < ballRadius) {
-      ball.dy = -ball.dy;
-    } else if(ball.y + dy > canvas.height-ballRadius) {
-      let paddleHit = false;
-      for(let c=0; c<brickColumnCount; c++) {
-        for(let r=0; r<brickRowCount; r++) {
-          let b = bricks[c][r];
-          if(b.status === 1) {
-            if(ball.y > b.y && ball.y < b.y + brickHeight && ball.x > b.x && ball.x < b.x + brickWidth) {
-              paddleHit = true;
-              break;
-            }
-          }
-        }
-      }
-      if(paddleHit) {
-        ball.dy = -ball.dy;
-      } else {
-        lives--;
-        if(!lives) {
-          alert("GAME OVER");
-          document.location.reload();
+    if (y + dy < ballRadius) {
+        dy = -dy;
+    } else if (y + dy > canvas.height - ballRadius) {
+        if (x > paddleX && x < paddleX + paddleWidth) {
+            dy = -dy;
         } else {
-          balls = [{ x: canvas.width / 2, y: canvas.height - 30, dx, dy }];
-          paddleX = (canvas.width-paddleWidth)/2;
+            lives--;
+            if (!lives) {
+                alert('GAME OVER');
+                document.location.reload();
+            } else {
+                x = canvas.width / 2;
+                y = canvas.height - 30;
+                dx = 4;
+                dy = -4;
+                paddleX = (canvas.width - paddleWidth) / 2;
+            }
         }
-      }
     }
 
-    if(rightPressed && paddleX < canvas.width-paddleWidth) {
-      paddleX += 7;
-    } else if(leftPressed && paddleX > 0) {
-      paddleX -= 7;
+    if (rightPressed && paddleX < canvas.width - paddleWidth) {
+        paddleX += 7;
+    } else if (leftPressed && paddleX > 0) {
+        paddleX -= 7;
     }
 
-    ball.x += ball.dx;
-    ball.y += ball.dy;
-  });
+    x += dx;
+    y += dy;
 
-  requestAnimationFrame(draw);
+    requestAnimationFrame(draw);
 }
 
 draw();
diff --git a/data/artifacts/7bf57916e775/hf-qwen-coder-32b.png b/data/artifacts/7bf57916e775/hf-qwen-coder-32b.png
index bd782fc..621922f 100644
Binary files a/data/artifacts/7bf57916e775/hf-qwen-coder-32b.png and b/data/artifacts/7bf57916e775/hf-qwen-coder-32b.png differ
diff --git a/data/challenges.json b/data/challenges.json
index e278199..d6a3a2d 100644
--- a/data/challenges.json
+++ b/data/challenges.json
@@ -8740,12 +8740,12 @@
         "model": "hf-qwen-coder-32b",
         "status": "done",
         "error": null,
-        "seconds": 80,
+        "seconds": 68,
         "cost": 0,
-        "started_at": "2026-07-23T18:20:38.313Z",
-        "finished_at": "2026-07-23T18:21:58.509Z",
-        "queued_at": "2026-07-23T18:18:30.779Z",
-        "bytes": 5863,
+        "started_at": "2026-07-25T03:41:42.725Z",
+        "finished_at": "2026-07-25T03:42:50.814Z",
+        "queued_at": "2026-07-25T03:41:42.718Z",
+        "bytes": 5090,
         "thumb": true,
         "aiScore": 7.8,
         "aiReason": "The game is visually appealing and fulfills all the requirements of the challenge.",
diff --git a/data/landings/6fb7d108c932-claude-code.html b/data/landings/6fb7d108c932-claude-code.html
new file mode 100644
index 0000000..28f3f39
--- /dev/null
+++ b/data/landings/6fb7d108c932-claude-code.html
@@ -0,0 +1,253 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>Warp Starfield Tunnel — built by Claude Opus (Max plan) · Model Arena</title>
+<style>*{box-sizing:border-box}html,body{margin:0;height:100%;background:#0b0d10;color:#e6ecf2;font:14px/1.5 ui-monospace,Menlo,monospace}
+header{display:flex;align-items:center;gap:14px;padding:13px 20px;border-bottom:1px solid #1c2430;background:#0e1116}
+header .k{color:#7cf;font-weight:700;letter-spacing:2px;text-transform:uppercase;font-size:12px;white-space:nowrap}
+header h1{font-size:15px;margin:0;font-weight:600}header .by{color:#8a93a0;font-size:12px;margin-left:auto;white-space:nowrap}
+.wrap{height:calc(100% - 51px)}iframe{width:100%;height:100%;border:0;background:#000;display:block}</style></head><body>
+<header><span class="k">⚔ Model Arena</span><h1>Warp Starfield Tunnel</h1><span class="by">built by <b>Claude Opus (Max plan)</b></span></header>
+<div class="wrap"><iframe sandbox="allow-scripts allow-pointer-lock" srcdoc="&lt;!DOCTYPE html&gt;
+&lt;html lang=&quot;en&quot;&gt;
+&lt;head&gt;
+&lt;meta charset=&quot;UTF-8&quot;&gt;
+&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
+&lt;title&gt;Warp Starfield&lt;/title&gt;
+&lt;style&gt;
+  html, body {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+    background: #000;
+    cursor: crosshair;
+  }
+  canvas { display: block; }
+  #hud {
+    position: fixed;
+    left: 14px;
+    bottom: 12px;
+    font: 11px/1.6 &quot;SF Mono&quot;, Menlo, Consolas, monospace;
+    color: rgba(160, 200, 255, 0.55);
+    pointer-events: none;
+    user-select: none;
+    letter-spacing: 0.5px;
+    text-shadow: 0 0 6px rgba(80, 140, 255, 0.4);
+  }
+  #speedbar {
+    position: fixed;
+    left: 14px;
+    bottom: 46px;
+    width: 140px;
+    height: 3px;
+    background: rgba(120, 160, 255, 0.15);
+    border-radius: 2px;
+    overflow: hidden;
+    pointer-events: none;
+  }
+  #speedfill {
+    height: 100%;
+    width: 30%;
+    background: linear-gradient(90deg, #3af, #aef);
+    border-radius: 2px;
+    box-shadow: 0 0 8px rgba(90, 180, 255, 0.8);
+  }
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;canvas id=&quot;c&quot;&gt;&lt;/canvas&gt;
+&lt;div id=&quot;speedbar&quot;&gt;&lt;div id=&quot;speedfill&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div id=&quot;hud&quot;&gt;WARP DRIVE &amp;mdash; move mouse to steer &amp;middot; scroll to change speed&lt;/div&gt;
+&lt;script&gt;
+(function () {
+  &quot;use strict&quot;;
+
+  var canvas = document.getElementById(&quot;c&quot;);
+  var ctx = canvas.getContext(&quot;2d&quot;, { alpha: false });
+  var speedfill = document.getElementById(&quot;speedfill&quot;);
+
+  var W = 0, H = 0, CX = 0, CY = 0, DPR = 1;
+
+  function resize() {
+    DPR = Math.min(window.devicePixelRatio || 1, 2);
+    W = window.innerWidth;
+    H = window.innerHeight;
+    canvas.width = Math.floor(W * DPR);
+    canvas.height = Math.floor(H * DPR);
+    canvas.style.width = W + &quot;px&quot;;
+    canvas.style.height = H + &quot;px&quot;;
+    ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
+    CX = W / 2;
+    CY = H / 2;
+    // hard reset the frame so we don't smear stale pixels after resize
+    ctx.fillStyle = &quot;#000&quot;;
+    ctx.fillRect(0, 0, W, H);
+  }
+  window.addEventListener(&quot;resize&quot;, resize);
+  resize();
+
+  // ---- config ----
+  var NUM_STARS = Math.min(900, Math.max(400, Math.floor((W * H) / 1800)));
+  var DEPTH = 1600;          // z range
+  var FOV = 320;             // projection focal length
+  var MIN_SPEED = 2;
+  var MAX_SPEED = 90;
+
+  // ---- state ----
+  var speed = 16;            // target speed (scroll-controlled)
+  var curSpeed = 16;         // smoothed speed
+  var mouseX = 0, mouseY = 0;      // -1..1 target steer
+  var steerX = 0, steerY = 0;      // smoothed steer
+  var hueShift = 0;
+
+  window.addEventListener(&quot;mousemove&quot;, function (e) {
+    mouseX = (e.clientX / W) * 2 - 1;
+    mouseY = (e.clientY / H) * 2 - 1;
+  });
+  window.addEventListener(&quot;wheel&quot;, function (e) {
+    e.preventDefault();
+    speed += (e.deltaY &lt; 0 ? 1 : -1) * (2 + speed * 0.12);
+    speed = Math.max(MIN_SPEED, Math.min(MAX_SPEED, speed));
+  }, { passive: false });
+
+  // touch support: drag steers, pinch-ish vertical two-finger not needed
+  var lastTouchY = null;
+  window.addEventListener(&quot;touchmove&quot;, function (e) {
+    var t = e.touches[0];
+    mouseX = (t.clientX / W) * 2 - 1;
+    mouseY = (t.clientY / H) * 2 - 1;
+    if (e.touches.length === 2) {
+      if (lastTouchY !== null) {
+        speed += (lastTouchY - e.touches[1].clientY) * 0.3;
+        speed = Math.max(MIN_SPEED, Math.min(MAX_SPEED, speed));
+      }
+      lastTouchY = e.touches[1].clientY;
+    }
+    e.preventDefault();
+  }, { passive: false });
+  window.addEventListener(&quot;touchend&quot;, function () { lastTouchY = null; });
+
+  // ---- stars ----
+  // Each star: x, y in world units centered on axis; z depth; px/py previous projected point; hue
+  var stars = new Array(NUM_STARS);
+
+  function spawn(s, randomZ) {
+    // spread wide so steering reveals new stars at edges
+    s.x = (Math.random() * 2 - 1) * DEPTH * 1.2;
+    s.y = (Math.random() * 2 - 1) * DEPTH * 1.2;
+    s.z = randomZ ? Math.random() * DEPTH : DEPTH;
+    s.px = null;
+    s.py = null;
+    s.hue = 200 + Math.random() * 60 - 30; // blue-white-ish, some warm outliers
+    if (Math.random() &lt; 0.08) s.hue = 30 + Math.random() * 30; // occasional gold star
+    s.mag = 0.5 + Math.random() * 1.0;     // brightness/size multiplier
+    return s;
+  }
+
+  for (var i = 0; i &lt; NUM_STARS; i++) {
+    stars[i] = spawn({}, true);
+  }
+
+  // initial black fill
+  ctx.fillStyle = &quot;#000&quot;;
+  ctx.fillRect(0, 0, W, H);
+
+  var lastT = performance.now();
+
+  function frame(now) {
+    var dt = Math.min((now - lastT) / 16.6667, 3); // normalize to 60fps units, clamp spikes
+    lastT = now;
+
+    // smooth controls
+    steerX += (mouseX - steerX) * 0.06 * dt;
+    steerY += (mouseY - steerY) * 0.06 * dt;
+    curSpeed += (speed - curSpeed) * 0.08 * dt;
+
+    var speedFrac = (curSpeed - MIN_SPEED) / (MAX_SPEED - MIN_SPEED);
+
+    // motion blur: translucent black wash — more speed, less wash (longer trails)
+    var fade = 0.35 - speedFrac * 0.22; // 0.35 slow .. 0.13 fast
+    ctx.fillStyle = &quot;rgba(0,0,0,&quot; + fade.toFixed(3) + &quot;)&quot;;
+    ctx.fillRect(0, 0, W, H);
+
+    // camera lateral drift from steering (world moves opposite the mouse)
+    var camVX = steerX * curSpeed * 14;
+    var camVY = steerY * curSpeed * 14;
+    // vanishing point also eases toward the mouse for a steering feel
+    var vpx = CX - steerX * W * 0.22;
+    var vpy = CY - steerY * H * 0.22;
+
+    ctx.lineCap = &quot;round&quot;;
+
+    for (var i = 0; i &lt; NUM_STARS; i++) {
+      var s = stars[i];
+
+      s.z -= curSpeed * dt;
+      s.x -= camVX * dt * (0.4 + 0.6 * (s.z / DEPTH)); // parallax: near stars shift more visually via projection anyway
+      s.y -= camVY * dt * (0.4 + 0.6 * (s.z / DEPTH));
+
+      if (s.z &lt;= 1) {
+        spawn(s, false);
+        continue;
+      }
+
+      var k = FOV / s.z;
+      var sx = vpx + s.x * k;
+      var sy = vpy + s.y * k;
+
+      // recycle stars that fly off screen (with margin)
+      if (sx &lt; -60 || sx &gt; W + 60 || sy &lt; -60 || sy &gt; H + 60) {
+        spawn(s, false);
+        continue;
+      }
+
+      if (s.px !== null) {
+        var depthFrac = 1 - s.z / DEPTH;              // 0 far .. 1 near
+        var size = (0.3 + depthFrac * 2.2) * s.mag;
+        var alpha = Math.min(1, 0.15 + depthFrac * 0.95) * (0.6 + 0.4 * s.mag);
+
+        // color: hotter/whiter at high speed
+        var sat = Math.max(0, 70 - speedFrac * 45);
+        var light = 62 + depthFrac * 30 + speedFrac * 8;
+
+        ctx.strokeStyle = &quot;hsla(&quot; + s.hue + &quot;,&quot; + sat + &quot;%,&quot; + light + &quot;%,&quot; + alpha.toFixed(3) + &quot;)&quot;;
+        ctx.lineWidth = size;
+        ctx.beginPath();
+        ctx.moveTo(s.px, s.py);
+        ctx.lineTo(sx, sy);
+        ctx.stroke();
+
+        // bright core dot on near stars
+        if (depthFrac &gt; 0.75) {
+          ctx.fillStyle = &quot;hsla(&quot; + s.hue + &quot;,30%,95%,&quot; + (alpha * 0.9).toFixed(3) + &quot;)&quot;;
+          ctx.beginPath();
+          ctx.arc(sx, sy, size * 0.55, 0, 6.2832);
+          ctx.fill();
+        }
+      }
+
+      s.px = sx;
+      s.py = sy;
+    }
+
+    // subtle central glow that intensifies with speed
+    if (speedFrac &gt; 0.05) {
+      var glowR = Math.max(60, Math.min(W, H) * (0.1 + speedFrac * 0.35));
+      var g = ctx.createRadialGradient(vpx, vpy, 0, vpx, vpy, glowR);
+      g.addColorStop(0, &quot;rgba(150,190,255,&quot; + (0.10 * speedFrac).toFixed(3) + &quot;)&quot;);
+      g.addColorStop(1, &quot;rgba(150,190,255,0)&quot;);
+      ctx.fillStyle = g;
+      ctx.fillRect(vpx - glowR, vpy - glowR, glowR * 2, glowR * 2);
+    }
+
+    speedfill.style.width = (speedFrac * 100).toFixed(1) + &quot;%&quot;;
+
+    requestAnimationFrame(frame);
+  }
+
+  requestAnimationFrame(frame);
+})();
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;" title="Warp Starfield Tunnel"></iframe></div>
+</body></html>
\ No newline at end of file

← 793fdc1 auto-save: 2026-07-24T18:29:03 (1 files) — data/landings/562  ·  back to Model Arena  ·  Add Games Arcade: /arcade gallery + /api/arcade auto-discove 0e921bc →