<!-- LIVE · part 14 -->
on.y = -0.3; g.add(sashEnd2);

  // Arms — flung wide, catching the air
  var armL = new THREE.Group(); armL.position.set(-0.28, 2.08, 0);
  armL.rotation.z = 1.35; armL.rotation.x = -0.15;  // Nearly horizontal, flung wide
  var upperL = M(new THREE.CylinderGeometry(0.08, 0.09, 0.45, 8), MAT.skinTone);
  upperL.position.y = -0.22; armL.add(upperL);
  var foreL = M(new THREE.CylinderGeometry(0.07, 0.08, 0.40, 8), MAT.skinTone);
  foreL.position.y = -0.62; armL.add(foreL);
  var handL = M(new THREE.SphereGeometry(0.08, 8, 6), MAT.skinTone);
  handL.position.y = -0.88; handL.scale.set(0.7, 1.3, 0.5); armL.add(handL);
  // Ribbons from wrists — long, trailing the spin
  var ribbonL = M(new THREE.BoxGeometry(0.08, 0.90, 0.01), MAT.goldCloth);
  ribbonL.position.set(0.15, -0.85, -0.25); ribbonL.rotation.z = 0.9; ribbonL.rotation.x = 0.5; armL.add(ribbonL);
  var ribbonL2 = M(new THREE.BoxGeometry(0.06, 0.70, 0.01), MAT.crimsonCloth);
  ribbonL2.position.set(-0.10, -0.80, -0.20); ribbonL2.rotation.z = -0.7; ribbonL2.rotation.x = 0.4; armL.add(ribbonL2);
  g.add(armL);

  var armR = new THREE.Group(); armR.position.set(0.28, 2.08, 0);
  armR.rotation.z = -1.35; armR.rotation.x = -0.15;
  var upperR = upperL.clone(); upperR.position.y = -0.20; armR.add(upperR);
  var foreR = foreL.clone(); foreR.position.y = -0.55; armR.add(foreR);
  var handR = handL.clone(); handR.position.y = -0.78; armR.add(handR);
  var ribbonR = ribbonL.clone(); ribbonR.position.set(-0.15, -0.85, -0.25);
  ribbonR.rotation.z = -0.9; ribbonR.rotation.x = 0.5; armR.add(ribbonR);
  var ribbonR2 = ribbonL2.clone(); ribbonR2.position.set(0.10, -0.80, -0.20);
  ribbonR2.rotation.z = 0.7; ribbonR2.rotation.x = 0.4; armR.add(ribbonR2);
  g.add(armR);

  // Head — tilted back, face to the sky (abandon)
  var neck = M(new THREE.CylinderGeometry(0.08, 0.09, 0.12, 8), MAT.skinTone);
  neck.position.set(0, 2.18, 0); g.add(neck);
  var head = M(new THREE.SphereGeometry(0.15, 12, 10), MAT.skinTone);
  head.position.set(0, 2.35, -0.05); head.rotation.x = -0.4; head.scale.set(0.95, 1.05, 0.95); g.add(head);
  // Hair — flying outward from the spin
  for(var h=0; h<6; h++){
    var strand = M(new THREE.BoxGeometry(0.05, 0.40, 0.02), MAT.brownCloth);
    var ha = (h/6)*Math.PI*2;
    strand.position.set(Math.cos(ha)*0.25, 2.40, Math.sin(ha)*0.25);
    strand.rotation.z = Math.cos(ha)*1.2; strand.rotation.x = Math.sin(ha)*1.2;
    g.add(strand);
  }

  g.userData.avatarId = 'spinner';
  g.userData.avatarName = 'THE SPINNER';
  g.userData.legL = legL; g.userData.legR = legR;
  g.userData.armL = armL; g.userData.armR = armR;
  return g;
}


/* ============================================================
   9. THE KEEPER — Kneeling vigil, hands cupped around light (MACRO)
   Stillness, devotion. Not guarding against threat — keeping watch
   over something precious.
   Height: ~1.2 units kneeling (low, grounded, humble)
   Who you become: Someone who stays when others leave
   ============================================================ */
function buildKeeper() {
  initMaterials();
  var g = new THREE.Group();

  // === MACRO: Kneeling, grounded, low ===

  // Knees on ground — the foundation of the pose
  var kneeL = M(new THREE.SphereGeometry(0.13, 10, 8), MAT.brownCloth);
  kneeL.position.set(-0.18, 0.13, 0.10); kneeL.scale.set(1, 0.7, 1.2); g.add(kneeL);
  var kneeR = kneeL.clone(); kneeR.position.x = 0.18; g.add(kneeR);

  // Lower legs folded back (kneeling)
  var shinL = M(new THREE.CylinderGeometry(0.10, 0.09, 0.50, 8), MAT.brownCloth);
  shinL.position.set(-0.18, 0.12, -0.25); shinL.rotation.x = 1.35; g.add(shinL);
  var shinR = shinL.clone(); shinR.position.x = 0.18; g.add(shinR);
  var footLK = M(new THREE.BoxGeometry(0.16, 0.08, 0.28), MAT.skinTone);
  footLK.position.set(-0.18, 0.06, -0.50); g.add(footLK);
  var footRK = footLK.clone(); footRK.position.x = 0.18; g.add(footRK);

  // Thighs vertical (kneeling upright)
  var thighL = M(new THREE.CylinderGeometry(0.13, 0.11, 0.45, 8), MAT.brownCloth);
  thighL.position.set(-0.18, 0.40, 0.05); thighL.rotation.x = -0.15; g.add(thighL);
  var thighR = thighL.clone(); thighR.position.x = 0.18; g.add(thighR);

  // Hips — robed, settled low (kneeling)
  var pelvis = M(new THREE.CylinderGeometry(0.26, 0.32, 0.40, 10), MAT.grayCloth);
  pelvis.position.set(0, 0.55, 0); g.add(pelvis);

  // Torso — upright but bowed slightly forward (devotion, not defeat)
  var torso = M(new THREE.CylinderGeometry(0.24, 0.28, 0.60, 10), MAT.grayCloth);
  torso.position.set(0, 1.00, 0.05); torso.rotation.x = 0.22; g.add(torso);

  // Shoulders — rounded, drawn inward (protective)
  var shoulderL = M(new THREE.SphereGeometry(0.11, 10, 8), MAT.grayCloth);
  shoulderL.position.set(-0.28, 1.28, 0.10); shoulderL.scale.set(1, 0.8, 1); g.add(shoulderL);
  var shoulderR = shoulderL.clone(); shoulderR.position.x = 0.28; g.add(shoulderR);

  // Arms — reaching forward and down, hands cupped together
  var armL = 