<!-- RUBY-BACKUP · part 312 -->
d #8a6a1c;border-radius:8px;font-family:serif;font-size:14px;padding:12px;box-sizing:border-box;resize:vertical;line-height:1.6;"></textarea>'
        + '<div style="display:flex;gap:10px;">'
        + '<button id="epistleEngrave" style="flex:1;background:#ffd700;color:#111;border:none;border-radius:8px;padding:14px;font-size:16px;cursor:pointer;font-weight:bold;">⚒️ Engrave in Stone</button>'
        + '<button id="epistleClose" style="background:#333;color:#fff;border:none;border-radius:8px;padding:14px 20px;font-size:16px;cursor:pointer;">X</button>'
        + '</div>'
        + '</div>';
      document.body.appendChild(ee);
      document.getElementById('epistleEngrave').onclick = function(){ engraveEpistle(); };
      document.getElementById('epistleClose').onclick = function(){ toggleEpistleEditor(); };
      ee.onclick = function(e){ if(e.target===ee) toggleEpistleEditor(); };
    }else{
      ee.style.display = 'flex';
    }
  }else if(ee){
    ee.style.display = 'none';
  }
}
function engraveEpistle(){
  try{
    var title = document.getElementById('epistleTitle').value || 'Untitled';
    var body = document.getElementById('epistleBody').value || '';
    if(!body){ codeStatus('write something first'); return; }
    // create stone tablet
    var tablet = new THREE.Group();
    var stoneMat = new THREE.MeshStandardMaterial({color:0x3a3a3a, roughness:0.9});
    var slab = new THREE.Mesh(new THREE.BoxGeometry(4, 5, 0.4), stoneMat);
    slab.name = 'epistle-slab';
    tablet.add(slab);
    // gold frame
    var frameMat = new THREE.MeshStandardMaterial({color:0xffd700, metalness:0.8, roughness:0.2});
    var frame = new THREE.Mesh(new THREE.BoxGeometry(4.3, 5.3, 0.2), frameMat);
    frame.position.z = -0.15;
    frame.name = 'epistle-frame';
    tablet.add(frame);
    // render text on canvas
    var canvas = document.createElement('canvas');
    canvas.width = 512; canvas.height = 640;
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#2a2a2a';
    ctx.fillRect(0,0,512,640);
    ctx.fillStyle = '#ffd700';
    ctx.font = 'bold 36px serif';
    ctx.textAlign = 'center';
    ctx.fillText(title.substring(0,24), 256, 60);
    ctx.strokeStyle = '#ffd700';
    ctx.lineWidth = 2;
    ctx.beginPath(); ctx.moveTo(60,90); ctx.lineTo(452,90); ctx.stroke();
    ctx.fillStyle = '#e8e8e8';
    ctx.font = '24px serif';
    ctx.textAlign = 'left';
    var words = body.split(' ');
    var lines = [], line = '';
    for(var i=0; i<words.length && lines.length<16; i++){
      var test = line + words[i] + ' ';
      if(ctx.measureText(test).width > 440){ lines.push(line); line = words[i] + ' '; }
      else line = test;
    }
    lines.push(line);
    for(var l=0; l<lines.length; l++){
      ctx.fillText(lines[l], 36, 130 + l*32);
    }
    var tex = new THREE.CanvasTexture(canvas);
    var faceMat = new THREE.MeshStandardMaterial({map:tex, roughness:0.8});
    var face = new THREE.Mesh(new THREE.PlaneGeometry(3.8, 4.8), faceMat);
    face.position.z = 0.21;
    face.name = 'epistle-face';
    tablet.add(face);
    // place in world
    tablet.position.set(-15, 2.5, -15);
    tablet.userData.isPrimitive = true;
    tablet.userData.isEpistle = true;
    if(typeof scene!=='undefined') scene.add(tablet);
    window._epistleTablet = tablet;
    var sceneRef = (typeof scene!=='undefined') ? scene : null;
    pushCommand({
      name: 'engrave epistle "' + title.substring(0,20) + '"',
      execute: function(){ if(sceneRef) sceneRef.add(tablet); },
      undo: function(){ if(sceneRef) sceneRef.remove(tablet); }
    });
    toggleEpistleEditor();
    codeStatus('engraved "' + title.substring(0,20) + '"');
  }catch(e){ codeStatus('engrave failed'); }
}
/* BLOCK WRITER — write text on the selected block, for the ancestors */
function writeOnBlock(text){
  try{
    var target = window._highlighted || window._selectedBlock;
    if(!target){ codeStatus('tap a block first, then write'); return; }
    // create canvas with the text
    var canvas = document.createElement('canvas');
    canvas.width = 512; canvas.height = 128;
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#111111';
    ctx.fillRect(0,0,512,128);
    ctx.fillStyle = '#ffd700';
    ctx.font = 'bold 48px serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    // intaglio-style: draw text with engraved effect
    ctx.fillText(text.substring(0,20), 256, 64);
    var tex = new THREE.CanvasTexture(canvas);
    // apply to all meshes in the target
    target.traverse(function(m){
      if(m.isMesh){
        if(!m.userData._matCloned){ m.material = m.material.clone(); m.userData._matCloned = true; }
        m.material.map = tex;
        m.material.needsUpdate = true;
      }
    });
    // command for undo
    pushCommand({
      name: 'write "' + text.substring(0,20) + '"',
      execute: function(){
        target.traverse(function(m){ if(m.isMesh && m.material){ m.material.map = tex; m.material.needs