<!-- SOLID CITY · part 2062 -->
  { x: -0.3 }
  },

  // Authored by Solid, in the Architect's style, for the milestone.
  // The three-point landing: right leg forward and bent, left leg
  // back, spine pitched in, right fist reaching for the ground.
  landing: {
    rootY: -0.35,
    rightHip:      { x: -0.85 },
    rightKnee:     { x: 1.30 },
    rightAnkle:    { x: -0.40 },
    leftHip:       { x: 0.55 },
    leftKnee:      { x: 0.90 },
    leftAnkle:     { x: -0.30 },
    spine:         { x: 0.35 },
    rightShoulder: { x: -1.90 },
    rightElbow:    { x: -0.25 },
    leftShoulder:  { x: 0.50 },
    leftElbow:     { x: -0.40 }
  },
  // The team fist bump: right arm extended forward, nearly straight;
  // the rest of the body stays easy. Upper body only — two walkers
  // can bump without breaking stride.
  fistBump: {
    rightShoulder: { x: -1.35 },
    rightElbow:    { x: -0.08 },
    leftShoulder:  { x: -0.10, z: 0.12 },
    leftElbow:     { x: -0.20 }
  },
  // THE BODY'S OWN VOCABULARY — Living Moments (the King's word:
  // body language first, speech second). Not heroics: what a body
  // says before words arrive, shared by every citizen.
  startle: {
    rightShoulder: { x: -0.22, z: -0.42 },
    leftShoulder:  { x: -0.22, z: 0.42 },
    rightElbow:    { x: -0.55 },
    leftElbow:     { x: -0.55 },
    spine:         { x: 0.07 },
    head:          { x: -0.05 }
  },
  laugh: {
    head:          { x: -0.20, z: 0.06 },
    spine:         { x: -0.07 },
    rightShoulder: { x: 0.12, z: -0.18 },
    leftShoulder:  { x: 0.12, z: 0.18 },
    rightElbow:    { x: -0.30 },
    leftElbow:     { x: -0.30 }
  },
  headShake: {
    head:  { z: 0.16, x: 0.08 },
    spine: { z: 0.03 }
  },
  wave: {
    rightShoulder: { x: -2.45, z: -0.30 },
    rightElbow:    { x: -0.55, z: -0.25 },
    head:          { x: -0.04 }
  }
};

// 'ready' is the milestone's power stance; both names stand.
HERO_POSES.powerStance = HERO_POSES.ready;

const GESTURES = {
  powerStance: { duration: 1.6, priority: 1 },
  ready:       { duration: 1.6, priority: 1 },
  powerCharge: { duration: 1.8, priority: 2 },
  shieldBlock: { duration: 1.2, priority: 2 },
  fistBump:    { duration: 1.4, priority: 2 },
  victory:     { duration: 1.8, priority: 2 },
  landing:     { duration: 1.1, priority: 3 },
  startle:     { duration: 0.7, priority: 3 },
  laugh:       { duration: 1.3, priority: 1 },
  headShake:   { duration: 1.1, priority: 1 },
  wave:        { duration: 1.5, priority: 1 }
};

const clamp01 = v => Math.min(1, Math.max(0, v));
const smooth = t => { t = clamp01(t); return t * t * (3 - 2 * t); };
// Frame-rate independent damping (the exponential form of lerp).
const damp = (a, b, lambda, dt) => a + (b - a) * (1 - Math.exp(-lambda * dt));

// The envelope: ease in over the first quarter, hold, ease out over
// the last third. At weight 0 the gesture owns nothing.
function envelope(t, duration) {
  const p = t / duration;
  if (p <= 0 || p >= 1) return 0;
  if (p < 0.25) return smooth(p / 0.25);
  if (p > 0.65) return smooth((1 - p) / 0.35);
  return 1;
}

/* createHeroMotion(parts, {lambda})
 * parts: the rig's named parts ({leftShoulder, rightElbow, ...}),
 * exactly as the Forge factory registers them.
 * update(dt, base): base is null (neutral), a pose map, or a
 * function(jointName) returning {x,y,z} or undefined — the base
 * locomotion layer's word for this frame. Returns {rootY}, the
 * active full-body gesture's suggested root offset (0 if none);
 * the caller composes it with its own bob and grounding. */
function createHeroMotion(parts, opts = {}) {
  const lambda = opts.lambda ?? 12;
  const onEvent = opts.onEvent || (() => {});
  // Additional gesture vocabularies (the descendants' signature
  // motions, another citizen's dialect) register through opts —
  // declarative {duration, priority, pose} records resolved by the
  // SAME mixer. One engine, many vocabularies; never a second
  // writer of joint rotations.
  const custom = opts.gestures || {};
  let active = null; // {name, pose, t, duration, priority}
  let cancelling = false;

  // Intent arrives here; execution is the mixer's alone. play()
  // decides admissibility (unknown gesture, or a stronger action
  // already owns the rig) and reports the gesture's life by event:
  // started, then completed or cancelled — the intent/execution
  // separation the Architect ordered, so any caller (a human, an
  // AI citizen, a game event) requests and listens the same way.
  function play(name, o = {}) {
    const g = custom[name];
    const pose = g ? g.pose : HERO_POSES[name];
    const meta = g || GESTURES[name];
    if (!pose || !meta) { onEvent('refused', name); return false; }
    const priority = o.priority ?? meta.priority;
    if (active && priority < active.priority) { onEvent('refused', name); return false; }
    active = { name, pose, t: 0, duration: o.duration ?? meta.duration, priority };
    cancelling = false;
    onEvent('started', name);
    retur