*** Begin Patch ***
--- index.html
+++ index.html
@@ ... @@
   const MERGE_DELAY = 80;                        // 合成视觉延迟 ms（防同一帧连环合）
   const COMBO_WINDOW = 800;                      // 连击窗口 ms
   const NEW_BALL_IMMUNE = 100;                   // 新球合成免疫期 ms（仅防连环合）
+  const MIN_MOVE_THRESHOLD = 3;                  // 微动阈值：水平位移 < 3px 视为不动
   const FIXED_STEP = 1000 / 60;                  // 物理步长 16.67ms
   const OVER_LINE_GRACE = 700;                   // 超线宽限 ms
   const WALL = 6;                                // 侧墙/地面厚度
@@ ... @@
   // ---------- pointer 事件 ----------
   canvas.addEventListener('pointerdown', function (e) {
     if (state !== 'playing') return;
     canvas.setPointerCapture(e.pointerId);
-    heldX = toGameX(e.clientX);
+    heldX = lastPointerX = toGameX(e.clientX);
   });
   canvas.addEventListener('pointermove', function (e) {
     if (state !== 'playing') return;
-    heldX = toGameX(e.clientX);
+    const newX = toGameX(e.clientX);
+    if (Math.abs(newX - lastPointerX) >= MIN_MOVE_THRESHOLD) {
+      heldX = newX;
+      lastPointerX = newX;
+    }
   });
   canvas.addEventListener('pointerup', function (e) {
     if (state !== 'playing') return;
@@ ... @@
   let engine = null;
   let balls = [];            // { body, level, isRemoved, ... }
   let pendingMerges = [];
+  let lastPointerX = -1;     // 上次指针位置（防微动）
   let particles = [];        // 爆炸粒子
   let rings = [];            // 冲击环
   let floaters = [];         // 浮动得分文字
@@ ... @@
   function startCelebration() {
     const colors = ['#E53935', '#FB8C00', '#FDD835', '#43A047', '#1E88E5', '#8E24AA', '#D52B1E', '#1A3C6D', '#FFFFFF'];
     for (let i = 0; i < 90; i++) {
       confetti.push({
         x: Math.random() * W,
         y: -20 - Math.random() * 120,
         vx: (Math.random() - 0.5) * 0.5,
         vy: 0.4 + Math.random() * 1.2,
         rot: Math.random() * Math.PI * 2,
         vr: (Math.random() - 0.5) * 0.01,
         w: 5 + Math.random() * 6,
         h: 8 + Math.random() * 6,
         color: colors[i % colors.length],
         life: 0, maxLife: 2600 + Math.random() * 1200,
         phase: Math.random() * Math.PI * 2
       });
     }
+    // 通关动画：大红字渐显
+    var titleEl = document.createElement('div');
+    titleEl.id = 'passTitle';
+    titleEl.textContent = '通关！上海交通大学';
+    titleEl.style.cssText = 'position:fixed;top:34%;left:0;width:100%;text-align:center;font:bold 30px "Microsoft YaHei",sans-serif;color:#D52B1E;text-shadow:0 0 20px rgba(255,215,0,0.8),0 0 40px rgba(255,215,0,0.6);opacity:0;transition:opacity 1s ease;pointer-events:none;z-index:1000';
+    document.body.appendChild(titleEl);
+    requestAnimationFrame(function(){ titleEl.style.opacity = '1'; });
+    setTimeout(function(){
+      titleEl.style.transition = 'opacity 1.5s ease';
+      titleEl.style.opacity = '0';
+      setTimeout(function(){ if(titleEl.parentNode) titleEl.parentNode.removeChild(titleEl); }, 1500);
+    }, 6000);
   }
*** End Patch ***
