<!-- SOLID CITY · part 2046 -->
t('benchsel', 'EDIT', 'Make it the current creation', 'fg-t', i) + '</div>'; }).join('') : '<span class="fg-dim">Your unpublished creations autosave here.</span>') + '</div>';
  h += '<div class="fg-sec"><div class="fg-ph">LIBRARY (' + lib.length + ')</div>' + (lib.length ? lib.map(function (e, i) { return '<div class="fg-li"><span>' + esc(e.name) + ' <i>' + (e.n || (e.pieces || []).length) + ' pc</i></span>' + bt('stamp', 'STAMP', 'Use as the ghost', 'fg-t fg-gold', i) + bt('libdel', '\u2715', 'Remove', 'fg-t', i) + '</div>'; }).join('') : '<span class="fg-dim">SAVE TO LIBRARY keeps copies you can stamp anywhere.</span>') +
    '<div class="fg-row">' + bt('import', 'IMPORT FROM THE CREATOR', 'Import THE CREATOR saves from this browser', 'fg-t') + '</div></div>';
  var mine = F.world.filter(function (c) { return c.mine; });
  if (me.loggedIn) h += '<div class="fg-sec"><div class="fg-ph">MY WORLD BUILDS (' + mine.length + ')</div>' + (mine.length ? mine.map(function (c) { var i = F.world.indexOf(c); return '<div class="fg-li"><span>' + esc(c.name) + ' <i>' + ({ public: 'live', pending: '\u23F3 awaiting approval', rejected: 'rejected' }[c.status] || c.status) + '</i></span>' + bt('wgo', 'GO', 'Walk there', 'fg-t', i) + bt('pickup', 'PICK UP', 'Back to the workbench', 'fg-t', i) + bt('wdel', '\u2715', 'Delete', 'fg-t', i) + '</div>'; }).join('') : '<span class="fg-dim">Nothing published yet.</span>') + '</div>';
  if (me.admin) { var pend = F.world.filter(function (c) { return c.status === 'pending'; }); h += '<div class="fg-sec"><div class="fg-ph">\uD83D\uDC51 AWAITING YOUR APPROVAL (' + pend.length + ')</div>' + (pend.length ? pend.map(function (c) { var i = F.world.indexOf(c); return '<div class="fg-li"><span>' + esc(c.name) + ' <i>by ' + esc(c.owner || '?') + ' \u00b7 ' + c.items.length + ' pc</i></span>' + bt('wgo', 'GO', 'Walk there', 'fg-t', i) + bt('approve', '\u2713', 'Approve', 'fg-t fg-gold', i) + bt('reject', '\u2715', 'Reject', 'fg-t', i) + '</div>'; }).join('') : '<span class="fg-dim">No builds waiting.</span>') + '</div>'; }
  h += '<div class="fg-foot fg-dim">Every piece is solid. No building on the pad and its flight lane, the monument, the gates or the towers; max ' + L.MAX_HEIGHT + ' m high, ' + L.MAX_PIECES + ' pieces per creation. Keys: Z/X rotate \u00b7 R/F raise/lower \u00b7 [ ] size \u00b7 Enter place \u00b7 Del delete \u00b7 Ctrl+Z undo \u00b7 B exit.</div>';
  sheet.innerHTML = h;
  var nm = $('fg-name'); if (nm && cr) nm.addEventListener('change', function () { cr.name = nm.value.trim().slice(0, L.NAME) || cr.name; saveBench(); render(); });
}
function openSheet() { pop.hidden = true; sheet.hidden = false; getMe().then(function () { renderSheet(); }); renderSheet(); }
ui.addEventListener('click', function (e) {
  var b = e.target.closest('[data-fg]'); if (!b) return;
  var a = b.getAttribute('data-fg'), g = b.getAttribute('data-arg'), w = g != null ? F.world[+g] : null;
  if (a !== 'pop' && a !== 'color' && a !== 'finish' && a !== 'clay') pop.hidden = true;
  switch (a) {
    case 'exit': close(); break;
    case 'shape': setShape(g); break;
    case 'place': place(); break;
    case 'rot': edit('Rotated ' + (+g > 0 ? '+' : '') + g + '\u00b0', rotY(+g)); break;
    case 'scale': edit(+g > 1 ? 'Bigger' : 'Smaller', scaleBy(+g)); break;
    case 'nudge': nudge(g); break;
    case 'pop': openPop(g); break;
    case 'color': setColor(+g); break;
    case 'finish': setFinish(g); break;
    case 'clay': edit(CLAY[g][0], CLAY[g][1]); break;
    case 'dup': duplicate(); break;
    case 'del': del(); break;
    case 'undo': undo(); break;
    case 'sheet': if (sheet.hidden) openSheet(); else closeSheet(); break;
    case 'closesheet': closeSheet(); break;
    case 'newcr': F.cur = null; select(null); renderSheet(); say('The next piece you PLACE starts a new creation.'); break;
    case 'scope': F.scope = F.scope === 'whole' ? 'piece' : 'whole'; updateSel(); render(); renderSheet(); say(F.scope === 'whole' ? 'WHOLE: edits move / rotate / copy the whole creation.' : 'PIECE: edits apply to one piece.'); break;
    case 'grid': F.grid = { 0.5: 1, 1: 2, 2: 0.25, 0.25: 0.5 }[F.grid] || 0.5; F.lastKey = ''; render(); renderSheet(); break;
    case 'libsave': libSave(); break;
    case 'publish': publish(); break;
    case 'stamp': libStamp(+g); break;
    case 'libdel': libRemove(+g); break;
    case 'import': importCreator(); break;
    case 'benchgo': var bc = F.bench.filter(function (c) { return c.items.length; })[+g]; if (bc) goTo(bc); break;
    case 'benchsel': var bs = F.bench.filter(function (c) { return c.items.length; })[+g]; if (bs) { F.cur = bs; select(null); renderSheet(); say('\u201c' + bs.name + '\u201d is the current creation — new pieces join it.'); } break;
    case 'wgo': if (w) goTo(w); break;
    case 'pickup': if (w) pickUp(w); break;
    case 'wdel': if (w) removeWorld(w); break;
    case 'approve': if (w) review(w, 'approve'); break;
    case 