<!-- SOLID CITY · part 1994 -->
;
      }
      return { mode: M.mode, events: events };
    }

    if (M.mode === 'FLARE') {
      /* the last metres are the machine's: the adapter's floor holds
       * core flight 2.2 m above the fabric, so the flare is flown
       * kinematically — sink capped, speed bleeding, ground rushing
       * up at a pace a hull can forgive */
      M.phaseT += dt;
      c.vel.y += (-1.2 - c.vel.y) * Math.min(1, 2.5 * dt); // the sink eases to a forgiving -1.2 m/s
      if (c.vel.y < -3) c.vel.y = -3;
      c.pos.x += c.vel.x * dt; c.pos.z += c.vel.z * dt; c.pos.y += c.vel.y * dt;
      c.pitch *= (1 - 1.8 * dt); c.bank *= (1 - 1.8 * dt);
      var sF = surfBelow(c);
      if (sF !== null && c.pos.y - sF <= 0.02) {
        c.pos.y = sF;
        M.mode = 'LANDING'; M.phaseT = 0;
        M.rollV = Math.hypot(c.vel.x, c.vel.z); events.push('touchdown');
      } else if (M.phaseT > 6) emergency(events, 'hot');
      return { mode: M.mode, events: events };
    }

    if (M.mode === 'LANDING') {
      /* the roll-out: 1.6 s of decaying run on the surface she chose */
      M.phaseT += dt;
      var kk = Math.min(1, M.phaseT / 1.6), f2 = fwd(c);
      var vv = M.rollV * (1 - kk) * (1 - kk);
      c.pos.x += f2.x * vv * dt; c.pos.z += f2.z * vv * dt;
      var sL = surfBelow(c); if (sL !== null) c.pos.y = sL;
      c.vel = { x: f2.x * vv, y: 0, z: f2.z * vv };
      c.pitch *= (1 - kk * 0.3); c.bank *= (1 - kk * 0.3);
      if (kk >= 1) {
        c.vel = { x: 0, y: 0, z: 0 }; c.pitch = 0; c.bank = 0; c.throttle = 0; M.thrTarget = 0;
        M.mode = 'PARKED'; events.push('parked');
      }
      return { mode: M.mode, events: events };
    }

    if (M.mode === 'EMERGENCY') {
      M.phaseT += dt;
      if (M.emerg >= 3) {
        /* the settle: the sky refused her thrice — she sets herself down */
        var sS = surfBelow(c);
        if (sS !== null && c.pos.y - sS <= 0.05) {
          c.pos.y = sS; c.vel = { x: 0, y: 0, z: 0 }; c.pitch = 0; c.bank = 0; c.throttle = 0; M.thrTarget = 0;
          M.mode = 'PARKED'; M.emerg = 0; events.push('settled');
        } else {
          c.pos.y -= 2.0 * dt; c.vel = { x: 0, y: -2, z: 0 };
          c.pitch *= 0.9; c.bank *= 0.9;
        }
        return { mode: M.mode, events: events };
      }
      /* the go-around: 2.2 s of shaped flight — level the wings,
       * nose to +12 degrees, throttle 0.85, the pilot's hands stayed */
      var gi = { x: Math.max(-1, Math.min(1, -c.bank * 1.6)), y: Math.max(-1, Math.min(1, (12 * Math.PI / 180 - c.pitch) * 2.2)), throttle: 0.85 };
      if (!flyTick(dt, gi, events)) { /* still refused: hold position, keep trying */ }
      if (M.phaseT >= 2.2) { M.mode = 'FREE'; M.thrTarget = 0.7; events.push('recovered'); }
      return { mode: M.mode, events: events };
    }

    /* FREE / ASSIST / APPROACH — core flight, shaped by mode */
    var inp = { x: x, y: y, throttle: M.thrTarget };
    var g = gear(c);
    if (c.pos.y > 415) { /* atmosphere honesty: the world's ceiling is the envelope */
      if (inp.y > -0.4) inp.y = -0.4; // not merely no climb — the nose is brought down
      if (M.thrTarget > 0.55) M.thrTarget = 0.55;
      if (M.t - M.saidCeiling > 8) { M.saidCeiling = M.t; events.push('ceiling'); }
    }
    /* stall recovery (FREE and ASSIST): the core's wing has no nose-
     * drop of its own — a held stall mushes downward forever. When the
     * shudder persists and speed is low, the machine does what a
     * pilot's hands are trained to do: nose down, power in, until
     * the wing bites again. It outranks the pull-up: in a stall,
     * pulling up is the trap. */
    /* the mush is the flag's blind spot: at full power this wing can
     * hang nose-high at 20 m/s with alpha at the line — not flagged,
     * but not flying either. Pitch and speed together are the truth.
     * And the catch must be EARLY: past alpha 21 the core gives no
     * pitch authority at all, and at a 52-degree nose the velocity
     * path can never rise enough to hand it back — a falling-leaf
     * trap, escapable only by altitude. Caught at 17 degrees with
     * the path still rising, the yoke is alive and the nose obeys. */
    var mush = (M.mode === 'FREE' || M.mode === 'ASSIST') && speed(c) < 30 && c.pitch > 0.30;
    M.mushTime = mush ? M.mushTime + dt : Math.max(0, M.mushTime - 2 * dt);
    if (!M.recActive && (M.stallTime > 0.25 || M.mushTime > 0.25) && speed(c) < 30 && (M.mode === 'FREE' || M.mode === 'ASSIST')) { M.recActive = true; events.push('stall-recovery'); }
    if (M.recActive && speed(c) > 32 && Math.abs(c.pitch) < 0.35) { M.recActive = false; M.mode = 'ASSIST'; events.push('stall-recovered'); }
    var pullUp = !M.recActive && (M.mode === 'FREE' || M.mode === 'ASSIST') && c.vel.y < -2.5 && g < Math.max(14, -c.vel.y * 3.5);
    if (M.recActive) {
      /* the deep-stall law, learned by measurement: past alpha 21 the
       * core gives NO pitch authority, and thrust along a high nose
      