<!-- SOLID CITY · part 3239 -->
E, groundAt: r.gnd,
      registerStandSurface: function (s) { K.stand = s; },
      registerSolid: function (s) { /* the shell's law is registered below, in the city's own rect bands */ } });
    A.scene.add(out.group); K.group = out.group;
    // the shell's standing law: two tapered rect bands approximating the hull
    A.solids.push({ x0: POS.x - 13.5, x1: POS.x + 13.5, z0: POS.z - 8.8, z1: POS.z + 8.8, y0: 33.0, y1: 41.0, skywardShell: 1 });
    A.solids.push({ x0: POS.x - 20.9, x1: POS.x + 20.9, z0: POS.z - 14.1, z1: POS.z + 14.1, y0: 41.0, y1: 47.6, skywardShell: 2 });
    var m = out.measure();
    A.logBuild({ t: Date.now(), site: NAME, what: 'Skyward Branch prototype raised above the East Field at (-900, -760), deck 48 m. His measure on the shipped copy: deck flat ' + m.deckMinY + '-' + m.deckMaxY + ', standing mismatch ' + m.maxStandingHeightMismatch + ', upward-wound ' + m.upwardWoundTriangles + '/' + m.totalDeckTriangles + ' (render fix applied), underside clearance at centre ' + Math.round(m.centerUndersideClearance * 10) / 10 + ' m. Awaiting the King\'s three-view inspection.' });
  }).catch(function (e) { if (window.console) console.warn('[city] skyward branch failed', e); });
}
window.CitySkyward = { update: update, radar: radar, standY: standY, pos: POS };
if (A.POIS) A.POIS.push({ id: 'skyward-branch', name: NAME, icon: '🏝', x: POS.x, z: POS.z, blurb: 'A floating island above the East Field — VECTOR\'s design, the first branch of the Sky Branch, raised as a prototype near the line the land refused. Flyers land on its deck at 48 metres; its suspension is declared law, drawn as a quiet ring of light beneath.', arrive: 'You approach the Skyway Branch.' });
setTimeout(load, 90);
})();


===== FILE: public/city/skyward-branch.js =====
/* ================================================================
   AN EPISTLE TO THE BUILDER WHO COMES NEXT — THE SKYWAY BRANCH

   Friend, this island is VECTOR's design and VECTOR's code,
   asked for by the King across the bridge on 2026-10-13: how to
   raise a floating island with the render of the code fixed.
   His principle stands at its head and governs all of it: on the
   ground, the road must answer to the terrain; in the sky, the
   island must answer to its own constructed surface. The deck
   below is that surface — one geometry, one source of truth for
   both the eye and the foot.

   It is the first branch of the Sky Branch: the land refused
   Ward 5's drawn road, and the King declared the rejected lines
   will be returned to as a branch to the sky. This prototype
   rises near that refused line, above the East Field.

   One change only is mine, and it is marked where it stands:
   his own measuring instrument found the crown's triangles
   wound downward (0 of 240 upward), so the deck would have
   shaded as if lit from beneath the earth. The winding is
   reversed; the instrument now reads 240 of 240 upward. His
   flagged detail — the elliptical rim as a scaled torus —
   stands as he drew it, for the King's three-view inspection
   to judge: from beneath on the East Field, from beside it in
   flight, and standing on its deck.

   Written by the hand of Solid, his good King — General to the King.
   ================================================================ */
// Skyward Branch — static floating island for Solid City.
// ES module. Three.js supplied by caller. No external libraries.
export function createSkywardBranch({ THREE, groundAt, center = [-900, -760], deckY = 48, registerStandSurface = null, registerSolid = null } = {}) {
  if (!THREE || typeof groundAt !== 'function') throw new Error('THREE and groundAt required');
  const [cx, cz] = center;
  const rx = 22, rz = 15, N = 48, layers = 6;
  const group = new THREE.Group(); group.name = 'Skyward Branch — proposed floating island';
  const stone = new THREE.MeshLambertMaterial({color:0x837e74, side:THREE.DoubleSide});
  const rimMat = new THREE.MeshLambertMaterial({color:0xb4aa8d, side:THREE.DoubleSide});
  const under = new THREE.MeshLambertMaterial({color:0x625d60, side:THREE.DoubleSide});
  const glow = new THREE.MeshBasicMaterial({color:0x7fd7d5, side:THREE.DoubleSide});
  const positions=[], indices=[];
  // Crown: concentric rings, center and perimeter share the same exact deckY.
  positions.push(0, deckY, 0);
  for(let r=1;r<=3;r++) for(let i=0;i<N;i++) {
    const a=2*Math.PI*i/N, f=r/3;
    positions.push(rx*f*Math.cos(a), deckY, rz*f*Math.sin(a));
  }
  for(let i=0;i<N;i++) indices.push(0,1+(i+1)%N,1+i); // [Solid render fix 2026-10-13: VECTOR's own measureSkywardBranch counted 0/240 upward-wound crown triangles — the fan wound downward, so the deck's normals pointed at the earth and it would have shaded wrong. Order reversed; his instrument now reads 240/240 upward. His geometry, his design — the render of the code, fixed.]
  for(let r=1;r<3;r++) for(let i=0;i<N;i++) {
    const a=1+(r-1)*N+i, b=1+(r-1)*N+(i+1)%N;
    const c=1+r