<!-- SOLID CITY · part 2045 -->
"fg-msg" class="fg-msg"></div></div>' +
  '<div class="fg-col" id="fg-col">' +
    bt('rot', '\u27F2', 'Rotate left 15\u00b0', '', -15) + bt('rot', '\u27F3', 'Rotate right 15\u00b0', '', 15) +
    bt('scale', '\u2212', 'Smaller', '', 0.8) + bt('scale', '+', 'Bigger', '', 1.25) +
    bt('nudge', '\u2912', 'Raise', '', 'up') + bt('nudge', '\u2913', 'Lower', '', 'down') +
    bt('nudge', '\u2190', 'Move left', '', 'left') + bt('nudge', '\u2192', 'Move right', '', 'right') +
    bt('nudge', '\u2191', 'Move away', '', 'fwd') + bt('nudge', '\u2193', 'Move closer', '', 'back') +
    bt('pop', '\uD83C\uDFA8', 'Colour + finish', 'fg-cbtn', 'color') + bt('pop', '\uD83E\uDDF1', 'Clay tools', '', 'clay') +
    bt('dup', '\uD83D\uDCCB', 'Copy (duplicate)') + bt('del', '\uD83D\uDDD1', 'Delete', 'fg-red') +
    bt('undo', '\u21B6', 'Undo') + bt('sheet', '\u2630', 'Creations, library, publish') +
  '</div>' +
  '<div class="fg-tray"><div class="fg-shapes" id="fg-shapes">' + C.SHAPES.map(function (s) { return bt('shape', s[2], s[1], '', s[0]); }).join('') + '</div>' +
    '<button type="button" class="fg-place" id="fg-place" data-fg="place">PLACE</button></div>' +
  '<div class="fg-pop" id="fg-pop" hidden></div>' +
  '<div class="fg-sheet" id="fg-sheet" hidden></div>';
hud.appendChild(ui);
var pop = $('fg-pop'), sheet = $('fg-sheet');
function say(t, bad, quiet) { var m = $('fg-msg'); if (!m) return; m.textContent = t; m.classList.toggle('bad', !!bad); F.msgBad = !!bad; if (!quiet) { m.classList.remove('pulse'); void m.offsetWidth; m.classList.add('pulse'); } }
function render() {
  if (!F.on) return;
  var cr = F.sel ? F.sel.cr : F.cur, n = cr ? cr.items.length : 0;
  $('fg-info').textContent = (cr ? '\u201c' + cr.name + '\u201d \u00b7 ' + n + ' pc' : 'new creation') + ' \u00b7 ' + (F.scope === 'whole' ? 'WHOLE' : 'PIECE') + ' \u00b7 grid ' + F.grid + ' m';
  Array.prototype.forEach.call(document.querySelectorAll('#fg-shapes .fg-b'), function (b) { b.classList.toggle('on', !F.sel && b.getAttribute('data-arg') === F.shape && F.ghostName === C.shapeName(F.shape)); });
  var pb = $('fg-place'); pb.textContent = F.sel ? '\u2713 DONE' : 'PLACE'; pb.classList.toggle('sel', !!F.sel);
}
function openPop(kind) {
  if (!pop.hidden && pop.getAttribute('data-k') === kind) { pop.hidden = true; return; }
  pop.setAttribute('data-k', kind);
  if (kind === 'color') pop.innerHTML = '<div class="fg-ph">COLOUR</div><div class="fg-sw">' + SW.map(function (c) { var h = '#' + ('00000' + c.toString(16)).slice(-6); return '<button type="button" class="fg-s" data-fg="color" data-arg="' + c + '" style="background:' + h + '" aria-label="' + h + '"></button>'; }).join('') +
    '<label class="fg-s fg-pick" title="Any colour">\uD83C\uDF08<input type="color" id="fg-cin" value="#c99a3a"></label></div><div class="fg-ph">FINISH</div><div class="fg-row">' + bt('finish', 'MATTE', 'Matte', 'fg-t', 'matte') + bt('finish', 'GLOW', 'Glow', 'fg-t', 'glow') + bt('finish', 'GLASS', 'Glass', 'fg-t', 'glass') + '</div>';
  else pop.innerHTML = '<div class="fg-ph">CLAY (from THE CREATOR)</div><div class="fg-row fg-wrap">' + Object.keys(CLAY).map(function (k) { return bt('clay', CLAY[k][0], CLAY[k][0], 'fg-t', k); }).join('') + '</div>';
  pop.hidden = false;
  var ci = $('fg-cin'); if (ci) ci.addEventListener('input', function () { setColor(parseInt(ci.value.slice(1), 16)); });
}
function closeSheet() { sheet.hidden = true; }
function renderSheet() {
  if (sheet.hidden) return;
  var cr = F.sel && F.sel.cr.local ? F.sel.cr : F.cur, lib = readLib(), me = F.me || {};
  var h = '<div class="fg-sh-h"><b>THE FORGE</b><button type="button" class="fg-x" data-fg="closesheet" aria-label="Close">\u2715</button></div>';
  h += '<div class="fg-sec"><div class="fg-ph">THIS CREATION</div>' + (cr ? '<input id="fg-name" maxlength="' + L.NAME + '" value="' + esc(cr.name) + '" aria-label="Creation name"> <span class="fg-dim">' + cr.items.length + ' / ' + L.MAX_PIECES + ' pieces</span>' : '<span class="fg-dim">Nothing yet — PLACE a shape and it starts one.</span>') +
    '<div class="fg-row fg-wrap">' + bt('newcr', 'NEW CREATION', 'Start a new creation', 'fg-t') + bt('scope', F.scope === 'whole' ? 'SELECT: WHOLE' : 'SELECT: PIECE', 'Edit one piece or the whole creation', 'fg-t' + (F.scope === 'whole' ? ' on' : '')) +
    bt('grid', 'GRID ' + F.grid + ' m', 'Grid step', 'fg-t') + bt('libsave', 'SAVE TO LIBRARY', 'Save to your library', 'fg-t') + bt('publish', me.loggedIn ? (me.admin ? 'PUBLISH (live)' : 'PUBLISH (for approval)') : 'PUBLISH (log in)', 'Publish to the world', 'fg-t fg-gold') + '</div></div>';
  var bench = F.bench.filter(function (c) { return c.items.length; });
  h += '<div class="fg-sec"><div class="fg-ph">ON THIS DEVICE (' + bench.length + ')</div>' + (bench.length ? bench.map(function (c, i) { return '<div class="fg-li"><span>' + esc(c.name) + ' <i>' + c.items.length + ' pc</i></span>' + bt('benchgo', 'GO', 'Walk there', 'fg-t', i) + b