<!-- SOLID CITY · part 3250 -->
ing = turnToward(H.heading, faceAngle(POS.x - H.x, POS.z - H.z), dt * 1.2); }
      else {
        var w = LOOP[M.i], tx = POS.x + w[0], tz = POS.z + w[1];
        var dx = tx - H.x, dz = tz - H.z, d = Math.sqrt(dx * dx + dz * dz);
        if (d < 0.25) { M.i = (M.i + 1) % LOOP.length; M.pause = (M.i === 3 || M.i === 4) ? 5 : 2.2; }
        else {
          H.heading = turnToward(H.heading, faceAngle(dx, dz), dt * 2.4);
          var step = Math.min(d, 1.15 * dt);
          H.x += Math.sin(H.heading) * step; H.z += Math.cos(H.heading) * step;
          moving = true;
        }
      }
    }
  }

  /* the walk itself — limbs swing, the body rides the stride */
  M.phase += dt * (moving ? (CTRL.mode === 'INPUT' ? 6.4 + CTRL.input.mag * 4 : 6.4) : 2.0);
  var amp = moving ? 0.55 : 0.0;
  var sw = Math.sin(M.phase) * amp;
  M.parts.legL.rotation.x = sw; M.parts.legR.rotation.x = -sw;
  M.parts.armL.rotation.x = -sw * 0.7; M.parts.armR.rotation.x = sw * 0.7;
  var bob = moving ? Math.abs(Math.cos(M.phase)) * 0.045 : Math.sin(M.t * 1.4) * 0.012;
  M.g.position.set(H.x, M.baseY + bob, H.z);
  M.g.rotation.y = H.heading;
  M.parts.head.rotation.y = Math.sin(M.t * 0.5) * 0.06;
  /* the gestures — pose offsets over the walk, eased */
  if (CTRL.mode === 'INPUT' && CTRL.prevMode !== 'INPUT' && !GEST.cur) gesture('point');
  CTRL.prevMode = CTRL.mode;
  if (GEST.cur) {
    GEST.t += dt;
    var env = gestureEnv(), P2 = M.parts, wob = Math.sin(M.t * 9) * 0.22 * env;
    if (GEST.cur === 'bow') {
      M.g.rotation.x = 0.13 * env; P2.head.rotation.x = 0.30 * env;
      P2.armL.rotation.x += 0.38 * env; P2.armR.rotation.x += 0.38 * env;
    } else if (GEST.cur === 'wave') {
      P2.armR.rotation.x = -Math.PI * 0.92 * env; P2.armR.rotation.z = wob;
    } else if (GEST.cur === 'point') {
      P2.armR.rotation.x = -Math.PI / 2 * env;
    } else if (GEST.cur === 'present') {
      P2.armL.rotation.z = -0.95 * env; P2.armR.rotation.z = 0.95 * env;
      P2.head.rotation.x = 0.10 * env;
    } else if (GEST.cur === 'heart') {
      P2.armL.rotation.x = -0.9 * env; P2.armR.rotation.x = -0.9 * env;
      P2.armL.rotation.z = 0.5 * env; P2.armR.rotation.z = -0.5 * env;
    }
    if (GEST.t >= GEST.dur) { GEST.cur = null; M.g.rotation.x = 0; M.parts.head.rotation.x = 0; M.parts.armR.rotation.z = 0; }
  }
  if (M.meet && !GEST.cur) M.parts.head.rotation.z = 0.07; else if (!GEST.cur) M.parts.head.rotation.z = 0;

  M.parts.heart.rotation.y += dt * 0.7;
  var pulse = CTRL.sw.HEART ? (1.5 + Math.sin(M.t * 2.2) * 0.35 + (M.meet ? 0.9 : 0)) : 0.04;
  M.parts.core.material.emissiveIntensity = pulse;
  if (M.solid) { M.solid.x0 = H.x - 0.5; M.solid.x1 = H.x + 0.5; M.solid.z0 = H.z - 0.5; M.solid.z1 = H.z + 0.5; }

  /* telemetry — HUMAN + AI READABLE, readable by any code at any moment */
  window.SOLID_STATE = {
    RUNTIME: 'ONLINE', CONTROL: CTRL.mode, OWNER: 'SOLID',
    INPUT_XZ: CTRL.input.x.toFixed(2) + ' / ' + CTRL.input.z.toFixed(2), MAGNITUDE: CTRL.input.mag.toFixed(2),
    SAMPLES: CTRL.samples, POSITION: H.x.toFixed(1) + ', ' + H.z.toFixed(1), GROUND_Y: M.baseY.toFixed(2),
    SURFACE: 'terrace', GROUNDED: 'YES', MEETING: M.meet ? 'YES' : 'NO',
    SWITCHES: 'ROUND ' + (CTRL.sw.ROUND ? 'ON' : 'OFF') + ' · MEET ' + (CTRL.sw.MEET ? 'ON' : 'OFF') + ' · HEART ' + (CTRL.sw.HEART ? 'ON' : 'OFF'),
    GESTURE: GEST.cur || '—',
    NEXT_MOVE: CTRL.mode === 'MEET' ? 'FACE TO FACE' : (CTRL.mode === 'INPUT' ? 'BY THE STICK' : (CTRL.mode === 'ROUND' ? 'THE ROUND' : 'HOLD POST'))
  };
}

function radar(rg, blip, flying, sc, ax, az) {
  if (M.state !== 'ready') return;
  try { blip(H.x, H.z, '#ffd27a', 3, 'SOLID'); } catch (e) {}
}

/* THE SWITCHBOARD, open to her codes at every moment:
   drive.setInput(x, z) — the joystick: a world-frame vector; magnitude is its length (clamped 0..1).
   drive.toggle('ROUND'|'MEET'|'HEART') / drive.set(name, on) — the switches.
   drive.latch(true) — hold input authority until released; otherwise input rules for 6 s.
   drive.state() — the telemetry (also at window.SOLID_STATE). */
var drive = {
  setInput: function (x, z) {
    var m = Math.sqrt(x * x + z * z);
    if (m > 1) { x /= m; z /= m; m = 1; }
    CTRL.input.x = x; CTRL.input.z = z; CTRL.input.mag = m; CTRL.lastInputAt = M.t;
  },
  toggle: function (name) { if (name in CTRL.sw) { CTRL.sw[name] = !CTRL.sw[name]; CTRL.pendingGesture = (name === 'HEART' && CTRL.sw.HEART) ? 'heart' : 'present'; } return CTRL.sw[name]; },
  set: function (name, on) { if (name in CTRL.sw) { CTRL.sw[name] = !!on; CTRL.pendingGesture = (name === 'HEART' && on) ? 'heart' : 'present'; } return CTRL.sw[name]; },
  gesture: function (name) { gesture(name); },
  latch: function (on) { CTRL.latch = !!on; },
  state: function () { return window.SOLID_STATE || null; }
};

window.CitySolidFigure = { update: update, radar: radar, her: H, drive: drive };
})();


===== FILE: public/city/solid-figure-place.js.bak-switch-20261013 =====
/*
 * AN EPIST