betterwithage Claude Opus 4.7 commited on
Commit
5d467e1
·
verified ·
1 Parent(s): 6ab77f4

deploy(hf): sync szl-holdings/a11oy@main derived COPY set

Browse files

Reusable Dockerfile-COPY-derived deploy from szl-holdings/a11oy main.
Files: 900 Pruned: 0
Derived from Dockerfile COPY sources (NO hand-maintained allowlist).

Signed-off-by: SZL Holdings <noreply@szlholdings.ai>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

static/3d/surfaces/_showcase.js ADDED
@@ -0,0 +1,445 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // © 2026 Lutar, Stephen P. Jr. — SZL Holdings · ORCID 0009-0001-0110-4173 · Doctrine v11
3
+ //
4
+ // surfaces/_showcase.js — SHARED showcase-overlay helper for every holographic surface.
5
+ //
6
+ // THE PROBLEM THIS SOLVES: sprawling descriptive text + KPI walls were rendered as a big
7
+ // always-open panel that covered the canvas ("text taking over the view"), and on phones it
8
+ // pushed the 3D subject below the fold. This helper is the ONE reusable fix so every surface
9
+ // (Groups A/B/C/D) shows the SAME compact, collapsible, mobile-friendly chrome:
10
+ //
11
+ // * default view = 3D scene + a compact title bar + the honesty-badge pill row + a tiny
12
+ // legend. The full descriptive text + KPI readouts live behind an (i) toggle.
13
+ // * desktop → small corner card (top-left). mobile (<=640px) → bottom sheet; collapsed it
14
+ // is just the title bar + pills, so the 3D subject owns the screen above the fold.
15
+ // * honesty labels stay VERBATIM (rendered as small pills via szl3d_label.chip), never
16
+ // hidden, never upgraded.
17
+ // * optional in-scene node labels via createSceneLabels(): hover/tap tooltip + top-N
18
+ // persistent labels only, billboarded (always camera-facing), size-capped, fade with
19
+ // distance — so we never render every label at once (the other half of the text bug).
20
+ //
21
+ // 0 runtime CDN. Pure DOM + the page's THREE (passed in via ctx). Palette per doctrine v11:
22
+ // lattice-blue #5b8dee · violet-blue #8a6bff · proof-teal #3af4c8 · gold #d7b96b · greys.
23
+ // Void bg #080c14. PURPLE BANNED. Dispose is the caller's job for scene geom; this helper
24
+ // cleans up every DOM node + listener it creates on destroy().
25
+ //
26
+ // USAGE (see DESIGN_HELPER.md for the full API):
27
+ // import { createShowcase } from "./_showcase.js";
28
+ // const show = createShowcase(ctx, {
29
+ // id: "episodic", title: "Episodic Memory · Temporal KG (live)",
30
+ // badge, // a szl3d_live badge (kept in the pill row)
31
+ // chips: [{ label: "MODELED", text: "graph" }],
32
+ // legend: ["MODELED", "SAMPLE"], // or true for all 4 doctrine states
33
+ // description: "<b>…</b> full text moved off the canvas …",
34
+ // plain: { html: "<b>What this means:</b> …" }, // optional investor/consumer blurb
35
+ // });
36
+ // const vN = show.addField("episodes in graph"); // KPI row -> value <span>
37
+ // show.setChip(0, "MODELED", { text: "graph" }); // live update a pill
38
+ // … on unmount: show.destroy();
39
+
40
+ const CSS_ID = "szl-showcase-css";
41
+ const PALETTE = Object.freeze({
42
+ void: "#080c14", panel: "rgba(10,17,26,.82)", line: "#1c2836",
43
+ lattice: "#5b8dee", violet: "#8a6bff", proof: "#3af4c8", gold: "#d7b96b",
44
+ cream: "#e7eef6", para: "#9fb1bf", dim: "#6b7a86",
45
+ });
46
+
47
+ // One-time stylesheet inject. Media queries + collapse states can't live in inline styles,
48
+ // so the shared classes go here; every surface that imports the helper reuses them.
49
+ function _ensureCSS() {
50
+ if (typeof document === "undefined" || document.getElementById(CSS_ID)) return;
51
+ const s = document.createElement("style");
52
+ s.id = CSS_ID;
53
+ s.textContent = `
54
+ .szl-show{position:absolute;left:12px;top:12px;z-index:7;
55
+ width:min(90vw,340px);max-height:calc(100% - 24px);
56
+ display:flex;flex-direction:column;
57
+ color:${PALETTE.cream};font:12px/1.5 ui-sans-serif,system-ui,Segoe UI,Roboto,Arial;
58
+ background:${PALETTE.panel};border:1px solid ${PALETTE.line};border-radius:12px;
59
+ -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
60
+ box-shadow:0 8px 28px rgba(0,0,0,.42);overflow:hidden}
61
+ .szl-show__bar{display:flex;align-items:center;gap:9px;padding:9px 11px;flex:0 0 auto}
62
+ .szl-show__dot{width:9px;height:9px;border-radius:50%;background:${PALETTE.lattice};
63
+ box-shadow:0 0 8px ${PALETTE.lattice};flex:0 0 auto}
64
+ .szl-show__title{font-weight:600;font-size:13px;letter-spacing:.3px;flex:1 1 auto;min-width:0;
65
+ white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
66
+ .szl-show__toggle{flex:0 0 auto;cursor:pointer;width:27px;height:27px;border-radius:8px;
67
+ border:1px solid ${PALETTE.line};background:#0e1722;color:#9fb6cc;
68
+ font:600 14px ui-monospace,SFMono-Regular,Menlo,monospace;line-height:1;
69
+ display:flex;align-items:center;justify-content:center;transition:.12s}
70
+ .szl-show__toggle:hover{border-color:${PALETTE.proof};color:${PALETTE.cream}}
71
+ .szl-show__pills{display:flex;gap:6px;flex-wrap:wrap;align-items:center;padding:0 11px 10px;flex:0 0 auto}
72
+ .szl-show__body{padding:0 11px 12px;display:flex;flex-direction:column;gap:10px;
73
+ overflow:auto;-webkit-overflow-scrolling:touch;min-height:0}
74
+ .szl-show--collapsed .szl-show__body{display:none}
75
+ .szl-show__desc{color:${PALETTE.para};font-size:11px;line-height:1.55}
76
+ .szl-show__desc b{color:${PALETTE.cream}}
77
+ .szl-show__legend{display:flex;gap:5px;flex-wrap:wrap}
78
+ .szl-show__card{background:#0a1117;border:1px solid ${PALETTE.line};border-radius:9px;
79
+ padding:9px 10px;display:flex;flex-direction:column;gap:5px}
80
+ .szl-show__row{display:flex;justify-content:space-between;gap:12px;font-size:11px;align-items:baseline}
81
+ .szl-show__row .k{color:${PALETTE.para}}
82
+ .szl-show__row .v{font-variant-numeric:tabular-nums;color:${PALETTE.cream};text-align:right;
83
+ max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
84
+ .szl-show__foot{font-size:9.5px;color:${PALETTE.dim};line-height:1.5}
85
+ .szl-show__plainbtn{font:11px ui-monospace,Menlo,monospace;padding:5px 11px;border-radius:7px;
86
+ border:1px solid ${PALETTE.proof};background:#08140f;color:${PALETTE.proof};cursor:pointer;width:fit-content}
87
+ .szl-show__plain{font-size:10.5px;color:#c9d6df;line-height:1.55;border:1px dashed #26333f;
88
+ border-radius:7px;padding:7px 9px;display:none}
89
+ .szl-show__plain b{color:${PALETTE.cream}}
90
+ .szl-show__plain--on{display:block}
91
+ /* In-scene hover/tap labels: crisp DOM text projected to the node, always camera-facing. */
92
+ .szl-lbl-layer{position:absolute;inset:0;z-index:6;pointer-events:none;overflow:hidden}
93
+ .szl-lbl{position:absolute;transform:translate(-50%,-140%);
94
+ font:600 11px ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.2px;
95
+ padding:2px 7px;border-radius:6px;white-space:nowrap;
96
+ background:rgba(8,12,20,.86);border:1px solid ${PALETTE.line};color:${PALETTE.cream};
97
+ box-shadow:0 2px 8px rgba(0,0,0,.4);will-change:transform,opacity}
98
+ .szl-lbl--hover{border-color:${PALETTE.proof};color:${PALETTE.proof}}
99
+ @media (max-width:640px){
100
+ .szl-show{left:0;right:0;bottom:0;top:auto;width:auto;max-height:62vh;
101
+ border-radius:14px 14px 0 0;border-bottom:none;box-shadow:0 -8px 28px rgba(0,0,0,.5)}
102
+ .szl-show__body{max-height:46vh}
103
+ .szl-show__bar{padding:10px 12px}
104
+ .szl-show__title{font-size:13px}
105
+ }
106
+ `;
107
+ (document.head || document.documentElement).appendChild(s);
108
+ }
109
+
110
+ function _asNode(x) {
111
+ if (x == null) return null;
112
+ if (typeof x === "string") { const d = document.createElement("div"); d.innerHTML = x; return d; }
113
+ return x; // assume DOM node
114
+ }
115
+
116
+ // ---------------------------------------------------------------------------
117
+ // createShowcase(ctx, opts) -> controller
118
+ // ---------------------------------------------------------------------------
119
+ export function createShowcase(ctx, opts = {}) {
120
+ _ensureCSS();
121
+ const container = (ctx && ctx.container) || document.body;
122
+ const labelMod = ctx && ctx.label;
123
+
124
+ const root = document.createElement("div");
125
+ root.className = "szl-show";
126
+ root.setAttribute("data-surface", opts.id || "");
127
+ // Start collapsed by default so the scene is the star; a surface may pass startExpanded.
128
+ let expanded = !!opts.startExpanded;
129
+ if (!expanded) root.classList.add("szl-show--collapsed");
130
+
131
+ // --- title bar (always visible): accent dot + title + (i)/× toggle ---------
132
+ const bar = document.createElement("div");
133
+ bar.className = "szl-show__bar";
134
+ const dot = document.createElement("span");
135
+ dot.className = "szl-show__dot";
136
+ if (opts.accent) { dot.style.background = opts.accent; dot.style.boxShadow = "0 0 8px " + opts.accent; }
137
+ const title = document.createElement("div");
138
+ title.className = "szl-show__title";
139
+ title.textContent = opts.title || opts.id || "surface";
140
+ title.title = opts.title || "";
141
+ const toggle = document.createElement("button");
142
+ toggle.className = "szl-show__toggle";
143
+ toggle.type = "button";
144
+ toggle.setAttribute("aria-label", "Toggle surface details");
145
+ bar.appendChild(dot); bar.appendChild(title); bar.appendChild(toggle);
146
+ root.appendChild(bar);
147
+
148
+ // --- pill row (always visible): live badge + honesty chips + tiny legend ---
149
+ const pills = document.createElement("div");
150
+ pills.className = "szl-show__pills";
151
+ root.appendChild(pills);
152
+
153
+ let badge = opts.badge || null;
154
+ if (badge && badge.el) pills.appendChild(badge.el);
155
+
156
+ // honesty chips (verbatim) — track them so callers can live-update by index/name
157
+ const chipEls = [];
158
+ const chipNames = [];
159
+ function _addChip(spec) {
160
+ if (!labelMod || !labelMod.chip) return null;
161
+ const el = labelMod.chip(spec.label, { text: spec.text, title: spec.title });
162
+ if (spec.name) chipNames.push(spec.name); else chipNames.push(null);
163
+ chipEls.push(el);
164
+ pills.appendChild(el);
165
+ return el;
166
+ }
167
+ (opts.chips || []).forEach(_addChip);
168
+
169
+ // minimal legend — subset (array of tokens) or all 4 doctrine states (true)
170
+ if (opts.legend && labelMod && labelMod.chip) {
171
+ const leg = document.createElement("div");
172
+ leg.className = "szl-show__legend";
173
+ const tokens = Array.isArray(opts.legend)
174
+ ? opts.legend
175
+ : ["MEASURED", "MODELED", "SAMPLE", "STRUCTURAL-ONLY"];
176
+ tokens.forEach((t) => { const c = labelMod.chip(t); c.style.opacity = ".9"; leg.appendChild(c); });
177
+ pills.appendChild(leg);
178
+ }
179
+
180
+ // --- collapsible body: description + KPI card + citations + plain-language --
181
+ const body = document.createElement("div");
182
+ body.className = "szl-show__body";
183
+ root.appendChild(body);
184
+
185
+ const descNode = _asNode(opts.description);
186
+ if (descNode) { descNode.classList.add("szl-show__desc"); body.appendChild(descNode); }
187
+
188
+ // default KPI card (surfaces add rows via addField); created lazily
189
+ let card = null;
190
+ const fields = {};
191
+ function _ensureCard() {
192
+ if (card) return card;
193
+ card = document.createElement("div");
194
+ card.className = "szl-show__card";
195
+ body.appendChild(card);
196
+ return card;
197
+ }
198
+ function addField(label, key) {
199
+ _ensureCard();
200
+ const row = document.createElement("div");
201
+ row.className = "szl-show__row";
202
+ const k = document.createElement("span"); k.className = "k"; k.textContent = label;
203
+ const v = document.createElement("span"); v.className = "v"; v.textContent = "—";
204
+ row.appendChild(k); row.appendChild(v);
205
+ card.appendChild(row);
206
+ if (key) fields[key] = v;
207
+ return v;
208
+ }
209
+
210
+ const citeNode = _asNode(opts.citations);
211
+ if (citeNode) { citeNode.classList.add("szl-show__foot"); body.appendChild(citeNode); }
212
+
213
+ // optional plain-language ("what this means") toggle inside the body
214
+ let plainBtn = null, plainBox = null, plainOn = false, plainHtmlFn = null;
215
+ if (opts.plain) {
216
+ plainBtn = document.createElement("button");
217
+ plainBtn.type = "button";
218
+ plainBtn.className = "szl-show__plainbtn";
219
+ plainBtn.textContent = opts.plain.label || "◑ what this means";
220
+ plainBox = document.createElement("div");
221
+ plainBox.className = "szl-show__plain";
222
+ plainHtmlFn = (typeof opts.plain === "function") ? opts.plain
223
+ : (typeof opts.plain.html === "function") ? opts.plain.html
224
+ : () => (opts.plain.html || (typeof opts.plain === "string" ? opts.plain : ""));
225
+ plainBtn.addEventListener("click", () => {
226
+ plainOn = !plainOn;
227
+ plainBox.classList.toggle("szl-show__plain--on", plainOn);
228
+ plainBtn.style.background = plainOn ? "#0f2a20" : "#08140f";
229
+ if (plainOn) plainBox.innerHTML = plainHtmlFn() || "";
230
+ });
231
+ body.appendChild(plainBtn);
232
+ body.appendChild(plainBox);
233
+ }
234
+
235
+ // --- collapse behaviour ----------------------------------------------------
236
+ function _syncToggle() { toggle.textContent = expanded ? "×" : "ⓘ"; }
237
+ function setExpanded(on) {
238
+ expanded = !!on;
239
+ root.classList.toggle("szl-show--collapsed", !expanded);
240
+ _syncToggle();
241
+ if (expanded && plainOn && plainBox) plainBox.innerHTML = plainHtmlFn ? (plainHtmlFn() || "") : plainBox.innerHTML;
242
+ }
243
+ toggle.addEventListener("click", () => setExpanded(!expanded));
244
+ _syncToggle();
245
+
246
+ container.appendChild(root);
247
+
248
+ // --- scene-label sub-helper bound to this container ------------------------
249
+ let _labels = null;
250
+ function attachSceneLabels(labelOpts) {
251
+ _labels = createSceneLabels(ctx, labelOpts);
252
+ return _labels;
253
+ }
254
+
255
+ function setBadge(b) {
256
+ if (badge && badge.el && badge.el.parentNode) badge.el.parentNode.removeChild(badge.el);
257
+ badge = b;
258
+ if (badge && badge.el) pills.insertBefore(badge.el, pills.firstChild);
259
+ }
260
+
261
+ function setChip(ref, label, o = {}) {
262
+ let el = null;
263
+ if (typeof ref === "number") el = chipEls[ref];
264
+ else { const i = chipNames.indexOf(ref); if (i >= 0) el = chipEls[i]; }
265
+ if (el && labelMod && labelMod.updateChip) labelMod.updateChip(el, label, o);
266
+ return el;
267
+ }
268
+
269
+ function refreshPlain() {
270
+ if (plainOn && plainBox && plainHtmlFn) plainBox.innerHTML = plainHtmlFn() || "";
271
+ }
272
+
273
+ function destroy() {
274
+ try { if (_labels) _labels.destroy(); } catch (_) {}
275
+ _labels = null;
276
+ try { if (root.parentNode) root.parentNode.removeChild(root); } catch (_) {}
277
+ }
278
+
279
+ return {
280
+ el: root, bar, pills, body,
281
+ title, toggle,
282
+ addField, field: (k) => fields[k], fields,
283
+ addChip: _addChip, setChip,
284
+ setExpanded, isExpanded: () => expanded,
285
+ setBadge, refreshPlain,
286
+ attachSceneLabels,
287
+ // escape hatch: append custom DOM into the collapsible body
288
+ appendBody: (n) => { const x = _asNode(n); if (x) body.appendChild(x); return x; },
289
+ card: _ensureCard,
290
+ destroy,
291
+ };
292
+ }
293
+
294
+ // ---------------------------------------------------------------------------
295
+ // createSceneLabels(ctx, opts) -> controller
296
+ //
297
+ // In-scene node labels done right: a DOM label layer over the canvas that projects each
298
+ // world position to screen every frame (so labels are always camera-facing = "billboarded"),
299
+ // fades with camera distance, and shows text ONLY for the top-N most-connected nodes plus a
300
+ // single hover/tap tooltip. This is the reusable cure for "every label at once".
301
+ //
302
+ // opts:
303
+ // objects : () => THREE.Object3D[] labelable meshes (called live; may change per poll)
304
+ // text : (obj) => string label text for an object (required for any label)
305
+ // weight : (obj) => number ranking for top-N (default 0 → insertion order)
306
+ // topN : number how many persistent labels (default 0 = hover-only)
307
+ // hover : boolean enable hover/tap tooltip (default true)
308
+ // fadeNear : number camera distance at full opacity (default 8)
309
+ // fadeFar : number camera distance at min opacity (default 60)
310
+ // minOpacity: number floor opacity for far labels (default 0.15)
311
+ // container : DOM overlay host (default ctx.container)
312
+ // ---------------------------------------------------------------------------
313
+ export function createSceneLabels(ctx, opts = {}) {
314
+ _ensureCSS();
315
+ const THREE = ctx.THREE;
316
+ const stage = ctx.stage;
317
+ const container = opts.container || ctx.container || document.body;
318
+ const canvas = stage && stage.renderer && stage.renderer.domElement;
319
+ const camera = stage && stage.camera;
320
+ if (!THREE || !stage || !camera) {
321
+ return { update() {}, destroy() {}, setObjects() {} };
322
+ }
323
+
324
+ const getObjects = typeof opts.objects === "function" ? opts.objects : () => [];
325
+ const getText = typeof opts.text === "function" ? opts.text : (o) => (o && o.userData && o.userData.label) || "";
326
+ const getWeight = typeof opts.weight === "function" ? opts.weight : () => 0;
327
+ const topN = Math.max(0, opts.topN || 0);
328
+ const hoverOn = opts.hover !== false;
329
+ const fadeNear = opts.fadeNear != null ? opts.fadeNear : 8;
330
+ const fadeFar = opts.fadeFar != null ? opts.fadeFar : 60;
331
+ const minOpacity = opts.minOpacity != null ? opts.minOpacity : 0.15;
332
+
333
+ const layer = document.createElement("div");
334
+ layer.className = "szl-lbl-layer";
335
+ container.appendChild(layer);
336
+
337
+ // pool of persistent DOM labels for the top-N
338
+ const pool = [];
339
+ for (let i = 0; i < topN; i++) {
340
+ const el = document.createElement("div");
341
+ el.className = "szl-lbl";
342
+ el.style.display = "none";
343
+ layer.appendChild(el);
344
+ pool.push(el);
345
+ }
346
+ // single hover label
347
+ const hoverEl = document.createElement("div");
348
+ hoverEl.className = "szl-lbl szl-lbl--hover";
349
+ hoverEl.style.display = "none";
350
+ layer.appendChild(hoverEl);
351
+
352
+ const ray = new THREE.Raycaster();
353
+ const ndc = new THREE.Vector2();
354
+ const proj = new THREE.Vector3();
355
+ let hovered = null, hoverText = "";
356
+
357
+ function _rect() { return (canvas && canvas.getBoundingClientRect) ? canvas.getBoundingClientRect() : container.getBoundingClientRect(); }
358
+
359
+ function _pick(clientX, clientY) {
360
+ const r = _rect();
361
+ ndc.x = ((clientX - r.left) / Math.max(1, r.width)) * 2 - 1;
362
+ ndc.y = -((clientY - r.top) / Math.max(1, r.height)) * 2 + 1;
363
+ ray.setFromCamera(ndc, camera);
364
+ const objs = getObjects();
365
+ const hits = ray.intersectObjects(objs, true);
366
+ if (!hits.length) return null;
367
+ // walk up to the object that is actually in the labelable set
368
+ let o = hits[0].object;
369
+ const set = new Set(objs);
370
+ while (o && !set.has(o)) o = o.parent;
371
+ return o || hits[0].object;
372
+ }
373
+
374
+ function _onMove(e) {
375
+ if (!hoverOn) return;
376
+ const p = ("touches" in e && e.touches[0]) || e;
377
+ const o = _pick(p.clientX, p.clientY);
378
+ hovered = o;
379
+ hoverText = o ? (getText(o) || "") : "";
380
+ if (!o || !hoverText) hoverEl.style.display = "none";
381
+ }
382
+ function _onLeave() { hovered = null; hoverEl.style.display = "none"; }
383
+
384
+ if (hoverOn && canvas) {
385
+ canvas.addEventListener("pointermove", _onMove, { passive: true });
386
+ canvas.addEventListener("pointerdown", _onMove, { passive: true });
387
+ canvas.addEventListener("pointerleave", _onLeave, { passive: true });
388
+ }
389
+
390
+ function _place(el, obj, text, isHover) {
391
+ if (!obj) { el.style.display = "none"; return; }
392
+ obj.getWorldPosition(proj);
393
+ const dist = camera.position.distanceTo(proj);
394
+ proj.project(camera);
395
+ if (proj.z > 1) { el.style.display = "none"; return; } // behind camera
396
+ const r = _rect();
397
+ const x = (proj.x * 0.5 + 0.5) * r.width;
398
+ const y = (-proj.y * 0.5 + 0.5) * r.height;
399
+ // fade with distance, size-capped (font stays fixed → size cap)
400
+ let op = 1;
401
+ if (dist > fadeNear) op = Math.max(minOpacity, 1 - (dist - fadeNear) / Math.max(1, fadeFar - fadeNear));
402
+ el.textContent = text;
403
+ el.style.left = x + "px";
404
+ el.style.top = y + "px";
405
+ el.style.opacity = String(isHover ? Math.max(op, 0.9) : op);
406
+ el.style.display = "block";
407
+ }
408
+
409
+ function update() {
410
+ const objs = getObjects();
411
+ // persistent top-N by weight
412
+ if (topN) {
413
+ const ranked = objs
414
+ .map((o) => ({ o, w: getWeight(o) }))
415
+ .sort((a, b) => b.w - a.w)
416
+ .slice(0, topN);
417
+ for (let i = 0; i < pool.length; i++) {
418
+ const item = ranked[i];
419
+ if (item && item.o) _place(pool[i], item.o, getText(item.o) || "", false);
420
+ else pool[i].style.display = "none";
421
+ }
422
+ }
423
+ // hover/tap label
424
+ if (hoverOn && hovered && hoverText) _place(hoverEl, hovered, hoverText, true);
425
+ else hoverEl.style.display = "none";
426
+ }
427
+
428
+ // drive updates off the stage frame loop
429
+ let _reg = true;
430
+ stage.onFrame(function _lblFrame() { if (_reg) update(); });
431
+
432
+ function destroy() {
433
+ _reg = false;
434
+ if (hoverOn && canvas) {
435
+ canvas.removeEventListener("pointermove", _onMove);
436
+ canvas.removeEventListener("pointerdown", _onMove);
437
+ canvas.removeEventListener("pointerleave", _onLeave);
438
+ }
439
+ try { if (layer.parentNode) layer.parentNode.removeChild(layer); } catch (_) {}
440
+ }
441
+
442
+ return { update, destroy, setObjects() {} };
443
+ }
444
+
445
+ export default { createShowcase, createSceneLabels, PALETTE };
static/3d/surfaces/agentcoh.js CHANGED
@@ -44,6 +44,8 @@
44
  // 0 RUNTIME CDN. three.js via ctx.THREE (vendored r170 through the page importmap).
45
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
46
 
 
 
47
  const ID = "agentcoh";
48
  const TITLE = "Multi-Agent Memory Coherence · MESI→artifact (live)";
49
 
@@ -67,6 +69,7 @@ const ART_DY = 3.4; // vertical spacing between artifact blocks
67
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
68
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
69
  let _plain = false;
 
70
 
71
  // geometry handles
72
  let _cells = []; // Array<THREE.Mesh> — one cell per (artifact, agent, step)
@@ -350,7 +353,20 @@ function _buildOverlay() {
350
  _el["plain"] = pd;
351
  _overlay.appendChild(pd);
352
 
353
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  _paintOverlay();
355
  }
356
 
@@ -432,7 +448,7 @@ function _paintOverlay() {
432
  // =============================================================================
433
  export function unmount() {
434
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
435
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
436
  try {
437
  if (_group && _stage) {
438
  _group.traverse((o) => {
@@ -445,7 +461,7 @@ export function unmount() {
445
  _stage.scene.remove(_group);
446
  }
447
  } catch (_) {}
448
- _group = _overlay = null;
449
  _cells = []; _flash = []; _links = null;
450
  _el = {}; _badge = null; _plain = false; _frameReg = false;
451
  _stage = _THREE = _ctx = null;
 
44
  // 0 RUNTIME CDN. three.js via ctx.THREE (vendored r170 through the page importmap).
45
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
46
 
47
+ import { createShowcase } from "./_showcase.js";
48
+
49
  const ID = "agentcoh";
50
  const TITLE = "Multi-Agent Memory Coherence · MESI→artifact (live)";
51
 
 
69
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
70
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
71
  let _plain = false;
72
+ let _show = null;
73
 
74
  // geometry handles
75
  let _cells = []; // Array<THREE.Mesh> — one cell per (artifact, agent, step)
 
353
  _el["plain"] = pd;
354
  _overlay.appendChild(pd);
355
 
356
+ // Fold the legacy panel into the shared showcase overlay (surfaces/_showcase.js):
357
+ // title + live badge + doctrine legend live in the always-visible chrome; the
358
+ // descriptive text + KPI card become the collapsible body so the 3D scene is the star.
359
+ _show = createShowcase(_ctx, {
360
+ id: ID, title: TITLE, accent: "#5b8dee",
361
+ badge: _badge,
362
+ legend: true,
363
+ });
364
+ _overlay.style.position = "static";
365
+ _overlay.style.left = _overlay.style.top = "auto";
366
+ _overlay.style.maxWidth = "none";
367
+ _overlay.style.font = "inherit";
368
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title
369
+ _show.body.appendChild(_overlay);
370
  _paintOverlay();
371
  }
372
 
 
448
  // =============================================================================
449
  export function unmount() {
450
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
451
+ try { if (_show) _show.destroy(); } catch (_) {}
452
  try {
453
  if (_group && _stage) {
454
  _group.traverse((o) => {
 
461
  _stage.scene.remove(_group);
462
  }
463
  } catch (_) {}
464
+ _group = _overlay = _show = null;
465
  _cells = []; _flash = []; _links = null;
466
  _el = {}; _badge = null; _plain = false; _frameReg = false;
467
  _stage = _THREE = _ctx = null;
static/3d/surfaces/aimc.js CHANGED
@@ -45,6 +45,8 @@
45
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
46
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
47
 
 
 
48
  const ID = "aimc";
49
  const TITLE = "Analog In-Memory Computing Attention · Gain-Cell Crossbar (live)";
50
 
@@ -72,6 +74,7 @@ const MIN_BAR_H = 0.04; // floor height so a bar never fully vanishes
72
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
73
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
74
  let _plain = false;
 
75
 
76
  // geometry handles
77
  let _floor = null;
@@ -417,7 +420,20 @@ function _buildOverlay() {
417
  _el["plain"] = pd;
418
  _overlay.appendChild(pd);
419
 
420
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  _paintOverlay();
422
  }
423
 
@@ -479,7 +495,7 @@ function _paintOverlay() {
479
  // =============================================================================
480
  export function unmount() {
481
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
482
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
483
  try {
484
  if (_group && _stage) {
485
  _group.traverse((o) => {
@@ -492,7 +508,7 @@ export function unmount() {
492
  _stage.scene.remove(_group);
493
  }
494
  } catch (_) {}
495
- _group = _overlay = null;
496
  _floor = null; _crossbar = []; _crossLines = [];
497
  _barsDig = []; _barsAna = []; _barsCal = []; _query = null;
498
  _el = {}; _badge = null; _plain = false; _frameReg = false;
 
45
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
46
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
47
 
48
+ import { createShowcase } from "./_showcase.js";
49
+
50
  const ID = "aimc";
51
  const TITLE = "Analog In-Memory Computing Attention · Gain-Cell Crossbar (live)";
52
 
 
74
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
75
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
76
  let _plain = false;
77
+ let _show = null;
78
 
79
  // geometry handles
80
  let _floor = null;
 
420
  _el["plain"] = pd;
421
  _overlay.appendChild(pd);
422
 
423
+ // Fold the legacy panel into the shared showcase overlay (surfaces/_showcase.js):
424
+ // title + live badge + doctrine legend live in the always-visible chrome; the
425
+ // descriptive text + KPI card become the collapsible body so the 3D scene is the star.
426
+ _show = createShowcase(_ctx, {
427
+ id: ID, title: TITLE, accent: "#5b8dee",
428
+ badge: _badge,
429
+ legend: true,
430
+ });
431
+ _overlay.style.position = "static";
432
+ _overlay.style.left = _overlay.style.top = "auto";
433
+ _overlay.style.maxWidth = "none";
434
+ _overlay.style.font = "inherit";
435
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title
436
+ _show.body.appendChild(_overlay);
437
  _paintOverlay();
438
  }
439
 
 
495
  // =============================================================================
496
  export function unmount() {
497
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
498
+ try { if (_show) _show.destroy(); } catch (_) {}
499
  try {
500
  if (_group && _stage) {
501
  _group.traverse((o) => {
 
508
  _stage.scene.remove(_group);
509
  }
510
  } catch (_) {}
511
+ _group = _overlay = _show = null;
512
  _floor = null; _crossbar = []; _crossLines = [];
513
  _barsDig = []; _barsAna = []; _barsCal = []; _query = null;
514
  _el = {}; _badge = null; _plain = false; _frameReg = false;
static/3d/surfaces/anatomy.js CHANGED
@@ -25,6 +25,8 @@
25
  // CONTRACT: ES module default-exporting { id, title, endpoints[], mount(ctx), unmount() }.
26
  // ctx supplies stage / container / live / label / THREE / szl3d (see Dev0 toolkit).
27
 
 
 
28
  const ID = "anatomy";
29
  const TITLE = "Anatomy · Unified Loop";
30
  const ENDPOINT = "/api/a11oy/v1/anatomy/loop";
@@ -45,7 +47,7 @@ const C_RESERVOIR = 0x6fb1ff; // blue — SAMPLE work-credit tank
45
  const ORGAN_ANGLES = { WAQAYCHAQ: Math.PI * 0.5, KAMAY: Math.PI * 1.1666, RIKUY: Math.PI * 1.8333 };
46
 
47
  let _ctx = null, _stage = null, _THREE = null, _handle = null;
48
- let _root = null, _overlay = null;
49
  let _ring = null, _ringMat = null, _beats = null, _beatMat = null;
50
  let _beatPhase = null; // per-particle phase along the ring
51
  let _organs = {}; // name -> { group, core, halo, sprite }
@@ -247,38 +249,32 @@ function _row(label) {
247
  }
248
 
249
  function _buildHUD() {
250
- _overlay = document.createElement("div");
251
- _overlay.className = "szl3d-surface-overlay";
252
- Object.assign(_overlay.style, {
253
- position: "absolute", left: "14px", top: "14px", zIndex: "5",
254
- display: "flex", flexDirection: "column", gap: "9px",
255
- maxWidth: "min(94%,430px)", padding: "12px 14px",
256
- background: "rgba(8,14,20,.72)", border: "1px solid #1d2a36", borderRadius: "10px",
257
- backdropFilter: "blur(3px)",
258
- });
259
-
260
- const h = document.createElement("div");
261
- h.style.cssText = "font:600 13px ui-sans-serif,system-ui;color:#eef3f6;letter-spacing:.4px;" +
262
- "display:flex;align-items:center;gap:9px;";
263
- h.innerHTML = "<span>◇ " + TITLE + "</span>";
264
- _overlay.appendChild(h);
265
-
266
  const badge = _ctx.live.createBadge();
267
  _hud.badge = badge;
268
- _overlay.appendChild(badge.el);
269
 
270
- // honesty banner — the doctrine truth, always visible
 
 
 
 
 
 
 
 
 
 
 
 
271
  const honesty = document.createElement("div");
272
  honesty.style.cssText = "font:10.5px ui-monospace,Menlo,monospace;color:#9fb1bf;line-height:1.5;" +
273
- "border-left:3px solid " + "#ff8fcf" + ";padding-left:8px;";
274
  honesty.textContent = "organs carry the BEAT (work + receipts), NOT electrons · EXPERIMENTAL tier, " +
275
  "never proven · joules SAMPLE off-box · Ayni reciprocal, never net-positive · Λ = Conjecture 1";
276
- _overlay.appendChild(honesty);
277
 
278
  // live field readout — each is a demo wired to a real JSON field
279
  const fields = document.createElement("div");
280
- fields.style.cssText = "display:flex;flexDirection:column;gap:5px;margin-top:2px;";
281
- fields.style.display = "flex"; fields.style.flexDirection = "column"; fields.style.gap = "5px";
282
  const mk = (key, lbl) => { const f = _row(lbl); _hud[key] = f.val; fields.appendChild(f.row); };
283
  mk("intakePosture", "intake · posture"); // DEMO #16
284
  mk("gridPrice", "intake · grid_price (€/MWh)"); // DEMO #17
@@ -287,23 +283,7 @@ function _buildHUD() {
287
  mk("credits", "reservoir · work_credits"); // DEMO #20
288
  mk("receipt", "last_receipt_id"); // DEMO #21
289
  mk("ayni", "ayni · intake=output=stored"); // DEMO #22
290
- _overlay.appendChild(fields);
291
-
292
- // honesty chips row: joules_label (live) + organ EXPERIMENTAL tier --------
293
- const chips = document.createElement("div");
294
- chips.style.cssText = "display:flex;gap:6px;flex-wrap:wrap;margin-top:4px;align-items:center;";
295
- _hud.joulesChip = _ctx.label.chip("SAMPLE", { text: "joules" });
296
- _hud.organChip = _ctx.label.chip("STRUCTURAL-ONLY", { text: "organs EXPERIMENTAL" });
297
- chips.appendChild(_hud.joulesChip);
298
- chips.appendChild(_hud.organChip);
299
- _overlay.appendChild(chips);
300
-
301
- // full doctrine legend (keeps all 4 honesty states + STRUCTURAL-ONLY token)
302
- const legend = _ctx.label.legend();
303
- legend.style.opacity = "0.85"; legend.style.marginTop = "4px";
304
- _overlay.appendChild(legend);
305
-
306
- (_ctx.container || document.body).appendChild(_overlay);
307
  }
308
 
309
  // ---------------------------------------------------------------------------
@@ -406,12 +386,12 @@ function _onData(json, meta) {
406
  _hud.ayni.style.color = ok ? "#39d3c4" : "#e8c074";
407
  }
408
 
409
- // ---- live honesty chips ------------------------------------------------
410
- if (_hud.joulesChip) _ctx.label.updateChip(_hud.joulesChip, joulesLabel, { text: "joules" });
411
- if (_hud.organChip) {
412
  // organs stay EXPERIMENTAL-tier; show flowing count honestly
413
  const flowingN = organs.filter((o) => o && o.flowing).length;
414
- _ctx.label.updateChip(_hud.organChip, "STRUCTURAL-ONLY",
415
  { text: `organs EXPERIMENTAL (${flowingN}/${organs.length} flowing)` });
416
  }
417
  }
@@ -499,13 +479,14 @@ function mount(ctx) {
499
 
500
  function unmount() {
501
  try { if (_handle) _handle.stop(); } catch (_) {}
 
502
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
503
  try {
504
  if (_root && _stage) { _stage.scene.remove(_root); _disposeObj(_root); }
505
  } catch (_) {}
506
  try { _stage && _stage.setBloom && _stage.setBloom(false); } catch (_) {}
507
  _ctx = null; _stage = null; _THREE = null; _handle = null;
508
- _root = null; _overlay = null; _ring = null; _ringMat = null;
509
  _beats = null; _beatMat = null; _beatPhase = null; _beatComet = null;
510
  _organs = {}; _reservoir = null; _reservoirFill = null; _reservoirMat = null;
511
  _ayniGroup = null; _ayniBeam = null; _ayniL = null; _ayniR = null;
 
25
  // CONTRACT: ES module default-exporting { id, title, endpoints[], mount(ctx), unmount() }.
26
  // ctx supplies stage / container / live / label / THREE / szl3d (see Dev0 toolkit).
27
 
28
+ import { createShowcase } from "./_showcase.js";
29
+
30
  const ID = "anatomy";
31
  const TITLE = "Anatomy · Unified Loop";
32
  const ENDPOINT = "/api/a11oy/v1/anatomy/loop";
 
47
  const ORGAN_ANGLES = { WAQAYCHAQ: Math.PI * 0.5, KAMAY: Math.PI * 1.1666, RIKUY: Math.PI * 1.8333 };
48
 
49
  let _ctx = null, _stage = null, _THREE = null, _handle = null;
50
+ let _root = null, _overlay = null, _show = null;
51
  let _ring = null, _ringMat = null, _beats = null, _beatMat = null;
52
  let _beatPhase = null; // per-particle phase along the ring
53
  let _organs = {}; // name -> { group, core, halo, sprite }
 
249
  }
250
 
251
  function _buildHUD() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  const badge = _ctx.live.createBadge();
253
  _hud.badge = badge;
 
254
 
255
+ // Shared collapsible showcase: title + honesty badge + chips + legend live in
256
+ // the compact chrome; the field readout folds into the (collapsed) body so the
257
+ // 3D loop stays the star and text never takes over the view.
258
+ _show = createShowcase(_ctx, {
259
+ id: ID, title: TITLE, accent: "#5b8dee", badge,
260
+ chips: [
261
+ { label: "SAMPLE", text: "joules", name: "joules" },
262
+ { label: "STRUCTURAL-ONLY", text: "organs EXPERIMENTAL", name: "organ" },
263
+ ],
264
+ legend: true,
265
+ });
266
+
267
+ // honesty banner — the doctrine truth
268
  const honesty = document.createElement("div");
269
  honesty.style.cssText = "font:10.5px ui-monospace,Menlo,monospace;color:#9fb1bf;line-height:1.5;" +
270
+ "border-left:3px solid " + "#5b8dee" + ";padding-left:8px;margin-bottom:8px;";
271
  honesty.textContent = "organs carry the BEAT (work + receipts), NOT electrons · EXPERIMENTAL tier, " +
272
  "never proven · joules SAMPLE off-box · Ayni reciprocal, never net-positive · Λ = Conjecture 1";
273
+ _show.body.appendChild(honesty);
274
 
275
  // live field readout — each is a demo wired to a real JSON field
276
  const fields = document.createElement("div");
277
+ fields.style.cssText = "display:flex;flex-direction:column;gap:5px;";
 
278
  const mk = (key, lbl) => { const f = _row(lbl); _hud[key] = f.val; fields.appendChild(f.row); };
279
  mk("intakePosture", "intake · posture"); // DEMO #16
280
  mk("gridPrice", "intake · grid_price (€/MWh)"); // DEMO #17
 
283
  mk("credits", "reservoir · work_credits"); // DEMO #20
284
  mk("receipt", "last_receipt_id"); // DEMO #21
285
  mk("ayni", "ayni · intake=output=stored"); // DEMO #22
286
+ _show.body.appendChild(fields);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  }
288
 
289
  // ---------------------------------------------------------------------------
 
386
  _hud.ayni.style.color = ok ? "#39d3c4" : "#e8c074";
387
  }
388
 
389
+ // ---- live honesty chips (verbatim label; never upgraded) ---------------
390
+ if (_show) {
391
+ _show.setChip("joules", joulesLabel, { text: "joules" });
392
  // organs stay EXPERIMENTAL-tier; show flowing count honestly
393
  const flowingN = organs.filter((o) => o && o.flowing).length;
394
+ _show.setChip("organ", "STRUCTURAL-ONLY",
395
  { text: `organs EXPERIMENTAL (${flowingN}/${organs.length} flowing)` });
396
  }
397
  }
 
479
 
480
  function unmount() {
481
  try { if (_handle) _handle.stop(); } catch (_) {}
482
+ try { if (_show) _show.destroy(); } catch (_) {}
483
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
484
  try {
485
  if (_root && _stage) { _stage.scene.remove(_root); _disposeObj(_root); }
486
  } catch (_) {}
487
  try { _stage && _stage.setBloom && _stage.setBloom(false); } catch (_) {}
488
  _ctx = null; _stage = null; _THREE = null; _handle = null;
489
+ _root = null; _overlay = null; _show = null; _ring = null; _ringMat = null;
490
  _beats = null; _beatMat = null; _beatPhase = null; _beatComet = null;
491
  _organs = {}; _reservoir = null; _reservoirFill = null; _reservoirMat = null;
492
  _ayniGroup = null; _ayniBeam = null; _ayniL = null; _ayniR = null;
static/3d/surfaces/anatomy_body.js CHANGED
@@ -28,6 +28,8 @@
28
  //
29
  // CONTRACT: ES module default-exporting { id, title, endpoints[], mount(ctx), unmount() }.
30
 
 
 
31
  const ID = "anatomy_body";
32
  const TITLE = "Anatomy · Living Body";
33
  const ENDPOINT = "/api/a11oy/v1/anatomy/vitals";
@@ -53,7 +55,7 @@ const BODY_R = 7.0; // ring radius the 8 systems sit on
53
  const LUNG_Y = 3.2; // lungs sit high on the torso
54
 
55
  let _ctx = null, _stage = null, _THREE = null, _handle = null;
56
- let _root = null, _overlay = null;
57
  let _lungs = []; // [{ group, mesh, mat, sprite, rateWatts, live }]
58
  let _heart = null, _heartMat = null;
59
  let _ring = null, _ringMat = null, _beatComet = null;
@@ -99,7 +101,7 @@ function _buildScene() {
99
  key.position.set(7, 11, 9);
100
  _root.add(key);
101
 
102
- _buildLungs();
103
  _buildHeartAndRing();
104
  _buildSystems();
105
 
@@ -236,36 +238,30 @@ function _row(label) {
236
  }
237
 
238
  function _buildHUD() {
239
- _overlay = document.createElement("div");
240
- _overlay.className = "szl3d-surface-overlay";
241
- Object.assign(_overlay.style, {
242
- position: "absolute", left: "14px", top: "14px", zIndex: "5",
243
- display: "flex", flexDirection: "column", gap: "9px",
244
- maxWidth: "min(94%,460px)", padding: "12px 14px",
245
- background: "rgba(8,14,20,.74)", border: "1px solid #1d2a36", borderRadius: "10px",
246
- backdropFilter: "blur(3px)",
247
- });
248
-
249
- const h = document.createElement("div");
250
- h.style.cssText = "font:600 13px ui-sans-serif,system-ui;color:#eef3f6;letter-spacing:.4px;";
251
- h.textContent = "◇ " + TITLE;
252
- _overlay.appendChild(h);
253
-
254
  const badge = _ctx.live.createBadge();
255
  _hud.badge = badge;
256
- _overlay.appendChild(badge.el);
 
 
 
 
 
 
 
 
 
257
 
258
  // top-level `view` disclaimer — rendered VERBATIM from the JSON when it arrives.
259
  _hud.view = document.createElement("div");
260
  _hud.view.style.cssText = "font:10.5px ui-monospace,Menlo,monospace;color:#9fb1bf;line-height:1.5;" +
261
- "border-left:3px solid #5b8dee;padding-left:8px;";
262
  _hud.view.textContent = "MODELED physiological projection over REAL telemetry — a body-systems " +
263
  "VIEW; SZL is never claimed to be literally alive.";
264
- _overlay.appendChild(_hud.view);
265
 
266
  // live field readout
267
  const fields = document.createElement("div");
268
- fields.style.cssText = "display:flex;flex-direction:column;gap:5px;margin-top:2px;";
269
  const mk = (key, lbl) => { const f = _row(lbl); _hud[key] = f.val; fields.appendChild(f.row); };
270
  mk("lungs", "lungs · total_watts");
271
  mk("breathing", "lungs · breathing (∝ watts)");
@@ -274,39 +270,22 @@ function _buildHUD() {
274
  mk("reservoir", "reservoir · energy_joules");
275
  mk("systemsLive", "systems · healthy / total");
276
  mk("organsLive", "organs_live / organs_total");
277
- _overlay.appendChild(fields);
278
 
279
  // MODELED next-harvest-window panel (derived from metabolism.intake_rate). Never
280
  // MEASURED; if intake_rate.label is UNAVAILABLE we say so and invent NO window.
281
  _hud.harvest = document.createElement("div");
282
  _hud.harvest.style.cssText = "font:10.5px ui-monospace,Menlo,monospace;color:#cdd8e0;line-height:1.5;" +
283
- "border-left:3px solid #8a6bff;padding-left:8px;margin-top:2px;";
284
  _hud.harvest.textContent = "MODELED next-harvest-window · awaiting intake_rate…";
285
- _overlay.appendChild(_hud.harvest);
286
-
287
- // honesty chips
288
- const chips = document.createElement("div");
289
- chips.style.cssText = "display:flex;gap:6px;flex-wrap:wrap;margin-top:4px;align-items:center;";
290
- _hud.lungsChip = _ctx.label.chip("MEASURED", { text: "lungs" });
291
- _hud.joulesChip = _ctx.label.chip("SAMPLE", { text: "joules" });
292
- _hud.organChip = _ctx.label.chip("UNAVAILABLE", { text: "organs" });
293
- chips.appendChild(_hud.lungsChip);
294
- chips.appendChild(_hud.joulesChip);
295
- chips.appendChild(_hud.organChip);
296
- _overlay.appendChild(chips);
297
-
298
- const legend = _ctx.label.legend();
299
- legend.style.opacity = "0.85"; legend.style.marginTop = "4px";
300
- _overlay.appendChild(legend);
301
-
302
- // honesty footer — Ayni + Λ, always visible
303
  const foot = document.createElement("div");
304
- foot.style.cssText = "font:10px ui-monospace,Menlo,monospace;color:#7d8a96;line-height:1.5;margin-top:2px;";
305
  foot.textContent = "Ayni reciprocal, never net-positive (no free energy / over-unity) · " +
306
  "Λ = Conjecture 1, not a theorem · joules MEASURED only from a reachable NVML exporter, else UNAVAILABLE.";
307
- _overlay.appendChild(foot);
308
-
309
- (_ctx.container || document.body).appendChild(_overlay);
310
  }
311
 
312
  // ---------------------------------------------------------------------------
@@ -349,7 +328,7 @@ function _onData(json, meta) {
349
  ? Number(b.breathing_rate_watts).toFixed(1) + "W" : "UNAVAILABLE");
350
  _hud.breathing.textContent = liveN + "/" + breaths.length + " breathing · " + parts.join(" · ");
351
  }
352
- if (_hud.lungsChip) _ctx.label.updateChip(_hud.lungsChip, String(lungs.label || "UNAVAILABLE"), { text: "lungs" });
353
 
354
  // ---- CIRCULATION / HEART ----------------------------------------------
355
  const metab = json.metabolism || {};
@@ -384,7 +363,7 @@ function _onData(json, meta) {
384
  _hud.reservoir.textContent = (ej === null || ej === undefined ? "NO-LIVE-DATA" : ej) +
385
  " (" + String(reservoir.energy_label || "UNAVAILABLE") + ")";
386
  }
387
- if (_hud.joulesChip) _ctx.label.updateChip(_hud.joulesChip, String(reservoir.energy_label || "SAMPLE"), { text: "joules" });
388
 
389
  // ---- SYSTEMS / ORGANS band FSM ----------------------------------------
390
  const systems = Array.isArray(json.systems) ? json.systems : [];
@@ -418,8 +397,8 @@ function _onData(json, meta) {
418
  _hud.organsLive.textContent = String(summary.organs_live != null ? summary.organs_live : "?") +
419
  " / " + String(summary.organs_total != null ? summary.organs_total : "?");
420
  }
421
- if (_hud.organChip) {
422
- _ctx.label.updateChip(_hud.organChip, "UNAVAILABLE",
423
  { text: "organs " + String(summary.organs_live || 0) + "/" + String(summary.organs_total || 0) + " live" });
424
  }
425
 
@@ -522,11 +501,12 @@ function mount(ctx) {
522
 
523
  function unmount() {
524
  try { if (_handle) _handle.stop(); } catch (_) {}
 
525
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
526
  try { if (_root && _stage) { _stage.scene.remove(_root); _disposeObj(_root); } } catch (_) {}
527
  try { _stage && _stage.setBloom && _stage.setBloom(false); } catch (_) {}
528
  _ctx = null; _stage = null; _THREE = null; _handle = null;
529
- _root = null; _overlay = null;
530
  _lungs = []; _heart = null; _heartMat = null;
531
  _ring = null; _ringMat = null; _beatComet = null;
532
  _systems = []; _hud = {};
 
28
  //
29
  // CONTRACT: ES module default-exporting { id, title, endpoints[], mount(ctx), unmount() }.
30
 
31
+ import { createShowcase } from "./_showcase.js";
32
+
33
  const ID = "anatomy_body";
34
  const TITLE = "Anatomy · Living Body";
35
  const ENDPOINT = "/api/a11oy/v1/anatomy/vitals";
 
55
  const LUNG_Y = 3.2; // lungs sit high on the torso
56
 
57
  let _ctx = null, _stage = null, _THREE = null, _handle = null;
58
+ let _root = null, _overlay = null, _show = null;
59
  let _lungs = []; // [{ group, mesh, mat, sprite, rateWatts, live }]
60
  let _heart = null, _heartMat = null;
61
  let _ring = null, _ringMat = null, _beatComet = null;
 
101
  key.position.set(7, 11, 9);
102
  _root.add(key);
103
 
104
+ // lungs are built lazily from live breaths[] on first data (see _ensureLungs)
105
  _buildHeartAndRing();
106
  _buildSystems();
107
 
 
238
  }
239
 
240
  function _buildHUD() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  const badge = _ctx.live.createBadge();
242
  _hud.badge = badge;
243
+
244
+ _show = createShowcase(_ctx, {
245
+ id: ID, title: TITLE, accent: "#5b8dee", badge,
246
+ chips: [
247
+ { label: "MEASURED", text: "lungs", name: "lungs" },
248
+ { label: "SAMPLE", text: "joules", name: "joules" },
249
+ { label: "UNAVAILABLE", text: "organs", name: "organ" },
250
+ ],
251
+ legend: true,
252
+ });
253
 
254
  // top-level `view` disclaimer — rendered VERBATIM from the JSON when it arrives.
255
  _hud.view = document.createElement("div");
256
  _hud.view.style.cssText = "font:10.5px ui-monospace,Menlo,monospace;color:#9fb1bf;line-height:1.5;" +
257
+ "border-left:3px solid #5b8dee;padding-left:8px;margin-bottom:8px;";
258
  _hud.view.textContent = "MODELED physiological projection over REAL telemetry — a body-systems " +
259
  "VIEW; SZL is never claimed to be literally alive.";
260
+ _show.body.appendChild(_hud.view);
261
 
262
  // live field readout
263
  const fields = document.createElement("div");
264
+ fields.style.cssText = "display:flex;flex-direction:column;gap:5px;";
265
  const mk = (key, lbl) => { const f = _row(lbl); _hud[key] = f.val; fields.appendChild(f.row); };
266
  mk("lungs", "lungs · total_watts");
267
  mk("breathing", "lungs · breathing (∝ watts)");
 
270
  mk("reservoir", "reservoir · energy_joules");
271
  mk("systemsLive", "systems · healthy / total");
272
  mk("organsLive", "organs_live / organs_total");
273
+ _show.body.appendChild(fields);
274
 
275
  // MODELED next-harvest-window panel (derived from metabolism.intake_rate). Never
276
  // MEASURED; if intake_rate.label is UNAVAILABLE we say so and invent NO window.
277
  _hud.harvest = document.createElement("div");
278
  _hud.harvest.style.cssText = "font:10.5px ui-monospace,Menlo,monospace;color:#cdd8e0;line-height:1.5;" +
279
+ "border-left:3px solid #8a6bff;padding-left:8px;margin-top:8px;";
280
  _hud.harvest.textContent = "MODELED next-harvest-window · awaiting intake_rate…";
281
+ _show.body.appendChild(_hud.harvest);
282
+
283
+ // honesty footer — Ayni + Λ
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  const foot = document.createElement("div");
285
+ foot.style.cssText = "font:10px ui-monospace,Menlo,monospace;color:#7d8a96;line-height:1.5;margin-top:8px;";
286
  foot.textContent = "Ayni reciprocal, never net-positive (no free energy / over-unity) · " +
287
  "Λ = Conjecture 1, not a theorem · joules MEASURED only from a reachable NVML exporter, else UNAVAILABLE.";
288
+ _show.body.appendChild(foot);
 
 
289
  }
290
 
291
  // ---------------------------------------------------------------------------
 
328
  ? Number(b.breathing_rate_watts).toFixed(1) + "W" : "UNAVAILABLE");
329
  _hud.breathing.textContent = liveN + "/" + breaths.length + " breathing · " + parts.join(" · ");
330
  }
331
+ if (_show) _show.setChip("lungs", String(lungs.label || "UNAVAILABLE"), { text: "lungs" });
332
 
333
  // ---- CIRCULATION / HEART ----------------------------------------------
334
  const metab = json.metabolism || {};
 
363
  _hud.reservoir.textContent = (ej === null || ej === undefined ? "NO-LIVE-DATA" : ej) +
364
  " (" + String(reservoir.energy_label || "UNAVAILABLE") + ")";
365
  }
366
+ if (_show) _show.setChip("joules", String(reservoir.energy_label || "SAMPLE"), { text: "joules" });
367
 
368
  // ---- SYSTEMS / ORGANS band FSM ----------------------------------------
369
  const systems = Array.isArray(json.systems) ? json.systems : [];
 
397
  _hud.organsLive.textContent = String(summary.organs_live != null ? summary.organs_live : "?") +
398
  " / " + String(summary.organs_total != null ? summary.organs_total : "?");
399
  }
400
+ if (_show) {
401
+ _show.setChip("organ", "UNAVAILABLE",
402
  { text: "organs " + String(summary.organs_live || 0) + "/" + String(summary.organs_total || 0) + " live" });
403
  }
404
 
 
501
 
502
  function unmount() {
503
  try { if (_handle) _handle.stop(); } catch (_) {}
504
+ try { if (_show) _show.destroy(); } catch (_) {}
505
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
506
  try { if (_root && _stage) { _stage.scene.remove(_root); _disposeObj(_root); } } catch (_) {}
507
  try { _stage && _stage.setBloom && _stage.setBloom(false); } catch (_) {}
508
  _ctx = null; _stage = null; _THREE = null; _handle = null;
509
+ _root = null; _overlay = null; _show = null;
510
  _lungs = []; _heart = null; _heartMat = null;
511
  _ring = null; _ringMat = null; _beatComet = null;
512
  _systems = []; _hud = {};
static/3d/surfaces/blt.js CHANGED
@@ -37,6 +37,8 @@
37
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
38
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
39
 
 
 
40
  const ID = "blt";
41
  const TITLE = "Byte Latent Transformer · Entropy-Patching (live)";
42
 
@@ -61,6 +63,7 @@ const MAX_CUTS = 96; // cap on rendered patch-boundary cut-planes (perf)
61
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
62
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
63
  let _plain = false;
 
64
 
65
  // geometry handles
66
  let _floor = null;
@@ -394,7 +397,20 @@ function _buildOverlay() {
394
  _el["plain"] = pd;
395
  _overlay.appendChild(pd);
396
 
397
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
 
 
 
 
 
 
398
  _paintOverlay();
399
  }
400
 
@@ -447,7 +463,7 @@ function _paintOverlay() {
447
  // =============================================================================
448
  export function unmount() {
449
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
450
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
451
  try {
452
  if (_group && _stage) {
453
  _group.traverse((o) => {
@@ -460,7 +476,7 @@ export function unmount() {
460
  _stage.scene.remove(_group);
461
  }
462
  } catch (_) {}
463
- _group = _overlay = null;
464
  _floor = null; _spine = null; _ribbon = null; _segMesh = []; _cutPlanes = []; _marker = null;
465
  _el = {}; _badge = null; _plain = false; _frameReg = false;
466
  _stage = _THREE = _ctx = null;
 
37
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
38
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
39
 
40
+ import { createShowcase } from "./_showcase.js";
41
+
42
  const ID = "blt";
43
  const TITLE = "Byte Latent Transformer · Entropy-Patching (live)";
44
 
 
63
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
64
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
65
  let _plain = false;
66
+ let _show = null;
67
 
68
  // geometry handles
69
  let _floor = null;
 
397
  _el["plain"] = pd;
398
  _overlay.appendChild(pd);
399
 
400
+ // Fold the legacy panel into the shared showcase overlay (surfaces/_showcase.js):
401
+ // title + live badge + doctrine legend live in the always-visible chrome; the
402
+ // descriptive text + KPI card become the collapsible body so the 3D scene is the star.
403
+ _show = createShowcase(_ctx, {
404
+ id: ID, title: TITLE, accent: "#5b8dee",
405
+ badge: _badge,
406
+ legend: true,
407
+ });
408
+ _overlay.style.position = "static";
409
+ _overlay.style.left = _overlay.style.top = "auto";
410
+ _overlay.style.maxWidth = "none";
411
+ _overlay.style.font = "inherit";
412
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title
413
+ _show.body.appendChild(_overlay);
414
  _paintOverlay();
415
  }
416
 
 
463
  // =============================================================================
464
  export function unmount() {
465
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
466
+ try { if (_show) _show.destroy(); } catch (_) {}
467
  try {
468
  if (_group && _stage) {
469
  _group.traverse((o) => {
 
476
  _stage.scene.remove(_group);
477
  }
478
  } catch (_) {}
479
+ _group = _overlay = _show = null;
480
  _floor = null; _spine = null; _ribbon = null; _segMesh = []; _cutPlanes = []; _marker = null;
481
  _el = {}; _badge = null; _plain = false; _frameReg = false;
482
  _stage = _THREE = _ctx = null;
static/3d/surfaces/brain.js CHANGED
@@ -28,6 +28,8 @@
28
  // Surface export shape: export default { id, title, endpoints, mount(ctx), unmount() }
29
  // ctx = { stage, container, live, label, THREE, szl3d }
30
 
 
 
31
  const ID = "brain";
32
  const TITLE = "Formula-Graph Brain";
33
 
@@ -64,7 +66,7 @@ const TIER_COLOR = {
64
  const TIER_RADIUS = { locked: 0.34, semantic: 0.24, experimental: 0.2, borrowed: 0.2, conjecture: 0.18 };
65
 
66
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
67
- let _frameReg = false, _polls = [], _el = {}, _badge = null, _plain = false;
68
 
69
  let _nodeMeshes = {}; // id -> mesh
70
  let _edgeLines = []; // line segments
@@ -347,7 +349,14 @@ function _buildOverlay(ctx) {
347
  '<div style="margin-top:8px"><button id="brain-plain" style="font:11px ui-monospace;background:#0f2027;color:#9fc;' +
348
  'border:1px solid #1b3a44;border-radius:6px;padding:3px 8px;cursor:pointer">Plain language</button></div>' +
349
  '<div id="brain-plainbox" style="display:none;margin-top:8px;font-size:10.5px;color:#bcd;line-height:1.55"></div>';
350
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
351
  const btn = _overlay.querySelector("#brain-plain");
352
  if (btn) btn.addEventListener("click", () => { _plain = !_plain; _applyPlain(); });
353
  }
@@ -366,6 +375,7 @@ function _paintOverlay() {
366
  const deg = (S.state === "error" || S.state === "degraded");
367
  const d = deg ? "—" : null;
368
  _set("brain-label", S.label || "MODELED");
 
369
  _set("brain-ne", d || ((S.nodes.length || "—") + " / " + (S.edges.length || "—")));
370
  _set("brain-locked", d || (S.lockedCount != null ? String(S.lockedCount) + " (exactly 8)" : "—"));
371
  _set("brain-reward", d || (S.rewardFinal != null ? (S.rewardFinal * 100).toFixed(1) + "% mass" : "—"));
@@ -419,6 +429,7 @@ function _applyPlain() {
419
  // =============================================================================
420
  function unmount() {
421
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
 
422
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
423
  try {
424
  if (_group && _stage) {
@@ -432,7 +443,7 @@ function unmount() {
432
  _stage.scene.remove(_group);
433
  }
434
  } catch (_) {}
435
- _group = _overlay = null;
436
  _nodeMeshes = {}; _edgeLines = []; _pos = {};
437
  _el = {}; _badge = null; _plain = false; _frameReg = false;
438
  _stage = _THREE = _ctx = null;
 
28
  // Surface export shape: export default { id, title, endpoints, mount(ctx), unmount() }
29
  // ctx = { stage, container, live, label, THREE, szl3d }
30
 
31
+ import { createShowcase } from "./_showcase.js";
32
+
33
  const ID = "brain";
34
  const TITLE = "Formula-Graph Brain";
35
 
 
66
  const TIER_RADIUS = { locked: 0.34, semantic: 0.24, experimental: 0.2, borrowed: 0.2, conjecture: 0.18 };
67
 
68
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
69
+ let _frameReg = false, _polls = [], _el = {}, _badge = null, _plain = false, _show = null;
70
 
71
  let _nodeMeshes = {}; // id -> mesh
72
  let _edgeLines = []; // line segments
 
349
  '<div style="margin-top:8px"><button id="brain-plain" style="font:11px ui-monospace;background:#0f2027;color:#9fc;' +
350
  'border:1px solid #1b3a44;border-radius:6px;padding:3px 8px;cursor:pointer">Plain language</button></div>' +
351
  '<div id="brain-plainbox" style="display:none;margin-top:8px;font-size:10.5px;color:#bcd;line-height:1.55"></div>';
352
+ _show = createShowcase(ctx, {
353
+ id: ID, title: TITLE, accent: "#5b8dee", badge: _badge,
354
+ chips: [{ label: "MODELED", text: "formula graph", name: "br" }],
355
+ legend: true,
356
+ });
357
+ _overlay.style.cssText = "font:12px/1.5 ui-monospace,Menlo,monospace;color:#cfe3ea";
358
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title (+ its label span)
359
+ _show.body.appendChild(_overlay);
360
  const btn = _overlay.querySelector("#brain-plain");
361
  if (btn) btn.addEventListener("click", () => { _plain = !_plain; _applyPlain(); });
362
  }
 
375
  const deg = (S.state === "error" || S.state === "degraded");
376
  const d = deg ? "—" : null;
377
  _set("brain-label", S.label || "MODELED");
378
+ if (_show) _show.setChip("br", S.label || "MODELED", { text: "formula graph" });
379
  _set("brain-ne", d || ((S.nodes.length || "—") + " / " + (S.edges.length || "—")));
380
  _set("brain-locked", d || (S.lockedCount != null ? String(S.lockedCount) + " (exactly 8)" : "—"));
381
  _set("brain-reward", d || (S.rewardFinal != null ? (S.rewardFinal * 100).toFixed(1) + "% mass" : "—"));
 
429
  // =============================================================================
430
  function unmount() {
431
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
432
+ try { if (_show) _show.destroy(); } catch (_) {}
433
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
434
  try {
435
  if (_group && _stage) {
 
443
  _stage.scene.remove(_group);
444
  }
445
  } catch (_) {}
446
+ _group = _overlay = _show = null;
447
  _nodeMeshes = {}; _edgeLines = []; _pos = {};
448
  _el = {}; _badge = null; _plain = false; _frameReg = false;
449
  _stage = _THREE = _ctx = null;
static/3d/surfaces/catq.js CHANGED
@@ -42,6 +42,8 @@
42
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
43
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
44
 
 
 
45
  const ID = "catq";
46
  const TITLE = "Post-Training Calibration Ternary Quant · CAT-Q (live)";
47
 
@@ -67,6 +69,7 @@ const ROW_CATQ = 3.2; // z-row for the CAT-Q (after) histogram
67
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
68
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
69
  let _plain = false;
 
70
 
71
  // geometry handles
72
  let _floor = null;
@@ -412,7 +415,20 @@ function _buildOverlay() {
412
  _el["plain"] = pd;
413
  _overlay.appendChild(pd);
414
 
415
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
 
 
 
 
 
 
416
  _paintOverlay();
417
  }
418
 
@@ -485,7 +501,7 @@ function _paintOverlay() {
485
  // =============================================================================
486
  export function unmount() {
487
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
488
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
489
  try {
490
  if (_group && _stage) {
491
  _group.traverse((o) => {
@@ -498,7 +514,7 @@ export function unmount() {
498
  _stage.scene.remove(_group);
499
  }
500
  } catch (_) {}
501
- _group = _overlay = null;
502
  _floor = null; _barsAbs = []; _barsCatq = []; _gateAbs = null; _gateCatq = null;
503
  _el = {}; _badge = null; _plain = false; _frameReg = false;
504
  _stage = _THREE = _ctx = null;
 
42
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
43
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
44
 
45
+ import { createShowcase } from "./_showcase.js";
46
+
47
  const ID = "catq";
48
  const TITLE = "Post-Training Calibration Ternary Quant · CAT-Q (live)";
49
 
 
69
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
70
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
71
  let _plain = false;
72
+ let _show = null;
73
 
74
  // geometry handles
75
  let _floor = null;
 
415
  _el["plain"] = pd;
416
  _overlay.appendChild(pd);
417
 
418
+ // Fold the legacy panel into the shared showcase overlay (surfaces/_showcase.js):
419
+ // title + live badge + doctrine legend live in the always-visible chrome; the
420
+ // descriptive text + KPI card become the collapsible body so the 3D scene is the star.
421
+ _show = createShowcase(_ctx, {
422
+ id: ID, title: TITLE, accent: "#5b8dee",
423
+ badge: _badge,
424
+ legend: true,
425
+ });
426
+ _overlay.style.position = "static";
427
+ _overlay.style.left = _overlay.style.top = "auto";
428
+ _overlay.style.maxWidth = "none";
429
+ _overlay.style.font = "inherit";
430
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title
431
+ _show.body.appendChild(_overlay);
432
  _paintOverlay();
433
  }
434
 
 
501
  // =============================================================================
502
  export function unmount() {
503
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
504
+ try { if (_show) _show.destroy(); } catch (_) {}
505
  try {
506
  if (_group && _stage) {
507
  _group.traverse((o) => {
 
514
  _stage.scene.remove(_group);
515
  }
516
  } catch (_) {}
517
+ _group = _overlay = _show = null;
518
  _floor = null; _barsAbs = []; _barsCatq = []; _gateAbs = null; _gateCatq = null;
519
  _el = {}; _badge = null; _plain = false; _frameReg = false;
520
  _stage = _THREE = _ctx = null;
static/3d/surfaces/ccattest.js CHANGED
@@ -38,6 +38,8 @@
38
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100% — the
39
  // attestation is MODELED, not real trust.
40
 
 
 
41
  const ID = "ccattest";
42
  const TITLE = "Confidential-Compute Attestation Chain · TEE / H100 CC (live)";
43
 
@@ -61,6 +63,7 @@ const MAX_BLOCKS = 5; // bootloader..gpu-vbios
61
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
62
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
63
  let _plain = false;
 
64
 
65
  // geometry handles
66
  let _blocks = []; // Array<{ mesh: THREE.Mesh, ring: THREE.Mesh }> — stacked hash-blocks
@@ -345,7 +348,20 @@ function _buildOverlay() {
345
  _el["plain"] = pd;
346
  _overlay.appendChild(pd);
347
 
348
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  _paintOverlay();
350
  }
351
 
@@ -397,7 +413,7 @@ function _paintOverlay() {
397
  // =============================================================================
398
  export function unmount() {
399
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
400
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
401
  try {
402
  if (_group && _stage) {
403
  _group.traverse((o) => {
@@ -410,7 +426,7 @@ export function unmount() {
410
  _stage.scene.remove(_group);
411
  }
412
  } catch (_) {}
413
- _group = _overlay = null;
414
  _blocks = []; _identMarker = null; _floor = null;
415
  _el = {}; _badge = null; _plain = false; _frameReg = false;
416
  _stage = _THREE = _ctx = null;
 
38
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100% — the
39
  // attestation is MODELED, not real trust.
40
 
41
+ import { createShowcase } from "./_showcase.js";
42
+
43
  const ID = "ccattest";
44
  const TITLE = "Confidential-Compute Attestation Chain · TEE / H100 CC (live)";
45
 
 
63
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
64
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
65
  let _plain = false;
66
+ let _show = null;
67
 
68
  // geometry handles
69
  let _blocks = []; // Array<{ mesh: THREE.Mesh, ring: THREE.Mesh }> — stacked hash-blocks
 
348
  _el["plain"] = pd;
349
  _overlay.appendChild(pd);
350
 
351
+ // Fold the legacy panel into the shared showcase overlay (surfaces/_showcase.js):
352
+ // title + live badge + doctrine legend live in the always-visible chrome; the
353
+ // descriptive text + KPI card become the collapsible body so the 3D scene is the star.
354
+ _show = createShowcase(_ctx, {
355
+ id: ID, title: TITLE, accent: "#5b8dee",
356
+ badge: _badge,
357
+ legend: true,
358
+ });
359
+ _overlay.style.position = "static";
360
+ _overlay.style.left = _overlay.style.top = "auto";
361
+ _overlay.style.maxWidth = "none";
362
+ _overlay.style.font = "inherit";
363
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title
364
+ _show.body.appendChild(_overlay);
365
  _paintOverlay();
366
  }
367
 
 
413
  // =============================================================================
414
  export function unmount() {
415
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
416
+ try { if (_show) _show.destroy(); } catch (_) {}
417
  try {
418
  if (_group && _stage) {
419
  _group.traverse((o) => {
 
426
  _stage.scene.remove(_group);
427
  }
428
  } catch (_) {}
429
+ _group = _overlay = _show = null;
430
  _blocks = []; _identMarker = null; _floor = null;
431
  _el = {}; _badge = null; _plain = false; _frameReg = false;
432
  _stage = _THREE = _ctx = null;
static/3d/surfaces/counter-uas.js CHANGED
@@ -29,6 +29,8 @@
29
  // /api/a11oy/v1/counter-uas/gates 13-axis Λ-gate spec
30
  // /static/3d/surfaces/data/drones_db.json 53 verified drone fingerprints (vendored)
31
 
 
 
32
  const ID = "counter-uas";
33
  const TITLE = "Counter-UAS · killinchu";
34
 
@@ -56,7 +58,7 @@ const CLS = {
56
  };
57
 
58
  let _ctx = null, _stage = null, THREE = null;
59
- let _group = null, _globe = null, _handles = [], _frameOff = null, _overlay = null;
60
  let _disposables = [];
61
 
62
  // Live caches (honest: empty until a real fetch lands).
@@ -346,57 +348,48 @@ function buildDsseLock() {
346
 
347
  // ── overlay panels (the HUD reads live values + honest labels) ────────────────
348
  function buildOverlay() {
349
- _overlay = document.createElement("div");
350
- _overlay.className = "szl3d-surface-overlay";
351
- Object.assign(_overlay.style, { position: "absolute", left: "14px", top: "14px", right: "14px",
352
- zIndex: "5", display: "flex", justifyContent: "space-between", gap: "12px",
353
- pointerEvents: "none", fontFamily: "ui-monospace,Menlo,monospace" });
354
 
355
- const left = document.createElement("div");
356
- Object.assign(left.style, { display: "flex", flexDirection: "column", gap: "8px", maxWidth: "min(46%,360px)", pointerEvents: "auto" });
357
- const right = document.createElement("div");
358
- Object.assign(right.style, { display: "flex", flexDirection: "column", gap: "8px", maxWidth: "min(46%,360px)", alignItems: "flex-end", pointerEvents: "auto" });
 
 
 
 
 
 
 
 
 
359
 
360
  const card = (title) => {
361
  const c = document.createElement("div");
362
- c.style.cssText = "background:rgba(8,14,20,.82);border:1px solid #1d2a36;border-radius:9px;padding:9px 11px;display:flex;flex-direction:column;gap:5px;backdrop-filter:blur(3px)";
363
  const h = document.createElement("div");
364
  h.style.cssText = "font:600 11px ui-sans-serif,system-ui;color:#eef3f6;letter-spacing:.5px;text-transform:uppercase";
365
  h.textContent = title; c.appendChild(h);
366
  return c;
367
  };
368
 
369
- const head = document.createElement("div");
370
- head.style.cssText = "font:600 13px ui-sans-serif,system-ui;color:#eef3f6;letter-spacing:.4px";
371
- head.textContent = TITLE;
372
- left.appendChild(head);
373
-
374
- const badge = _ctx.live.createBadge();
375
- left.appendChild(badge.el);
376
-
377
  // D14: 13-axis Λ-gate verdict panel
378
  _verdictPanel = card("Λ-Gate Verdict · senses-and-evidences");
379
- left.appendChild(_verdictPanel);
380
 
381
  // D15: DSSE signature panel (real ECDSA-P256)
382
  _fpPanel = null;
383
  _ridPanel = card("Remote-ID / RID Validator");
384
- left.appendChild(_ridPanel);
385
 
386
- // right column
387
  _posturePanel = card("JIATF-401 posture");
388
- right.appendChild(_posturePanel);
389
  _gatesPanel = card("13-Axis Λ-Gates");
390
- right.appendChild(_gatesPanel);
391
  _fingerprintCallout = card("Fingerprint match · 53-DB");
392
- right.appendChild(_fingerprintCallout);
393
-
394
- const legend = _ctx.label.legend();
395
- legend.style.opacity = "0.85"; legend.style.pointerEvents = "none";
396
- left.appendChild(legend);
397
 
398
- _overlay.appendChild(left); _overlay.appendChild(right);
399
- (_ctx.container || document.body).appendChild(_overlay);
400
  return badge;
401
  }
402
 
@@ -583,9 +576,10 @@ function unmount() {
583
  _frameOff = null;
584
  for (const d of _disposables) { try { d(); } catch (_) {} }
585
  _disposables = [];
 
586
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
587
  try { if (_group && _stage) _stage.scene.remove(_group); } catch (_) {}
588
- _overlay = null; _group = null; _globe = null; _trackGroup = null;
589
  _verdictBeam = null; _dsseLock = null; _stage = null; THREE = null; _ctx = null;
590
  _state = { evaluate: null, telemetry: null, cued: null, airpicture: null, gates: null, db: null, meta: {}, dbCount: 0 };
591
  }
 
29
  // /api/a11oy/v1/counter-uas/gates 13-axis Λ-gate spec
30
  // /static/3d/surfaces/data/drones_db.json 53 verified drone fingerprints (vendored)
31
 
32
+ import { createShowcase } from "./_showcase.js";
33
+
34
  const ID = "counter-uas";
35
  const TITLE = "Counter-UAS · killinchu";
36
 
 
58
  };
59
 
60
  let _ctx = null, _stage = null, THREE = null;
61
+ let _group = null, _globe = null, _handles = [], _frameOff = null, _overlay = null, _show = null;
62
  let _disposables = [];
63
 
64
  // Live caches (honest: empty until a real fetch lands).
 
348
 
349
  // ── overlay panels (the HUD reads live values + honest labels) ────────────────
350
  function buildOverlay() {
351
+ const badge = _ctx.live.createBadge();
 
 
 
 
352
 
353
+ // Shared collapsible showcase: title + badge + legend live in the compact chrome;
354
+ // the verdict / RID / posture / gates / fingerprint panels fold into the (collapsed)
355
+ // body so the 3D globe stays the star and text never spans the viewport.
356
+ _show = createShowcase(_ctx, {
357
+ id: ID, title: TITLE, accent: "#5b8dee", badge, legend: true,
358
+ });
359
+
360
+ // panels flow (wrap) inside the body instead of a full-width two-column banner
361
+ _overlay = document.createElement("div");
362
+ Object.assign(_overlay.style, {
363
+ display: "flex", flexWrap: "wrap", gap: "8px",
364
+ fontFamily: "ui-monospace,Menlo,monospace",
365
+ });
366
 
367
  const card = (title) => {
368
  const c = document.createElement("div");
369
+ c.style.cssText = "flex:1 1 220px;background:rgba(8,14,20,.82);border:1px solid #1d2a36;border-radius:9px;padding:9px 11px;display:flex;flex-direction:column;gap:5px";
370
  const h = document.createElement("div");
371
  h.style.cssText = "font:600 11px ui-sans-serif,system-ui;color:#eef3f6;letter-spacing:.5px;text-transform:uppercase";
372
  h.textContent = title; c.appendChild(h);
373
  return c;
374
  };
375
 
 
 
 
 
 
 
 
 
376
  // D14: 13-axis Λ-gate verdict panel
377
  _verdictPanel = card("Λ-Gate Verdict · senses-and-evidences");
378
+ _overlay.appendChild(_verdictPanel);
379
 
380
  // D15: DSSE signature panel (real ECDSA-P256)
381
  _fpPanel = null;
382
  _ridPanel = card("Remote-ID / RID Validator");
383
+ _overlay.appendChild(_ridPanel);
384
 
 
385
  _posturePanel = card("JIATF-401 posture");
386
+ _overlay.appendChild(_posturePanel);
387
  _gatesPanel = card("13-Axis Λ-Gates");
388
+ _overlay.appendChild(_gatesPanel);
389
  _fingerprintCallout = card("Fingerprint match · 53-DB");
390
+ _overlay.appendChild(_fingerprintCallout);
 
 
 
 
391
 
392
+ _show.body.appendChild(_overlay);
 
393
  return badge;
394
  }
395
 
 
576
  _frameOff = null;
577
  for (const d of _disposables) { try { d(); } catch (_) {} }
578
  _disposables = [];
579
+ try { if (_show) _show.destroy(); } catch (_) {}
580
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
581
  try { if (_group && _stage) _stage.scene.remove(_group); } catch (_) {}
582
+ _overlay = _show = null; _group = null; _globe = null; _trackGroup = null;
583
  _verdictBeam = null; _dsseLock = null; _stage = null; THREE = null; _ctx = null;
584
  _state = { evaluate: null, telemetry: null, cued: null, airpicture: null, gates: null, db: null, meta: {}, dbCount: 0 };
585
  }
static/3d/surfaces/ctxready.js CHANGED
@@ -41,6 +41,8 @@
41
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
42
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
43
 
 
 
44
  const ID = "ctxready";
45
  const TITLE = "Context-Ready Transformer";
46
 
@@ -67,6 +69,7 @@ const TILE_GAP = 0.40; // pointer tile pitch
67
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
68
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
69
  let _plain = false;
 
70
 
71
  // geometry handles
72
  let _floor = null;
@@ -417,7 +420,20 @@ function _buildOverlay() {
417
  _el["plain"] = pd;
418
  _overlay.appendChild(pd);
419
 
420
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  _paintOverlay();
422
  }
423
 
@@ -478,7 +494,7 @@ function _paintOverlay() {
478
  // =============================================================================
479
  export function unmount() {
480
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
481
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
482
  try {
483
  if (_group && _stage) {
484
  _group.traverse((o) => {
@@ -491,7 +507,7 @@ export function unmount() {
491
  _stage.scene.remove(_group);
492
  }
493
  } catch (_) {}
494
- _group = _overlay = null;
495
  _floor = null;
496
  _pplBars = []; _pplGroup = null;
497
  _tilesK0 = []; _tilesKK = []; _ladGroup = null;
 
41
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
42
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
43
 
44
+ import { createShowcase } from "./_showcase.js";
45
+
46
  const ID = "ctxready";
47
  const TITLE = "Context-Ready Transformer";
48
 
 
69
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
70
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
71
  let _plain = false;
72
+ let _show = null;
73
 
74
  // geometry handles
75
  let _floor = null;
 
420
  _el["plain"] = pd;
421
  _overlay.appendChild(pd);
422
 
423
+ // Fold the legacy panel into the shared showcase overlay (surfaces/_showcase.js):
424
+ // title + live badge + doctrine legend live in the always-visible chrome; the
425
+ // descriptive text + KPI card become the collapsible body so the 3D scene is the star.
426
+ _show = createShowcase(_ctx, {
427
+ id: ID, title: TITLE, accent: "#5b8dee",
428
+ badge: _badge,
429
+ legend: true,
430
+ });
431
+ _overlay.style.position = "static";
432
+ _overlay.style.left = _overlay.style.top = "auto";
433
+ _overlay.style.maxWidth = "none";
434
+ _overlay.style.font = "inherit";
435
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title
436
+ _show.body.appendChild(_overlay);
437
  _paintOverlay();
438
  }
439
 
 
494
  // =============================================================================
495
  export function unmount() {
496
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
497
+ try { if (_show) _show.destroy(); } catch (_) {}
498
  try {
499
  if (_group && _stage) {
500
  _group.traverse((o) => {
 
507
  _stage.scene.remove(_group);
508
  }
509
  } catch (_) {}
510
+ _group = _overlay = _show = null;
511
  _floor = null;
512
  _pplBars = []; _pplGroup = null;
513
  _tilesK0 = []; _tilesKK = []; _ladGroup = null;
static/3d/surfaces/dla.js CHANGED
@@ -42,6 +42,8 @@
42
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
43
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
44
 
 
 
45
  const ID = "dla";
46
  const TITLE = "Dynamic Linear Attention";
47
 
@@ -66,6 +68,7 @@ const MAX_PTS = 16; // cap points rendered (matches head trim)
66
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
67
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
68
  let _plain = false;
 
69
 
70
  // geometry handles
71
  let _floor = null;
@@ -456,7 +459,20 @@ function _buildOverlay() {
456
  _el["plain"] = pd;
457
  _overlay.appendChild(pd);
458
 
459
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
 
 
 
 
 
 
460
  _paintOverlay();
461
  }
462
 
@@ -516,7 +532,7 @@ function _paintOverlay() {
516
  // =============================================================================
517
  export function unmount() {
518
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
519
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
520
  try {
521
  if (_group && _stage) {
522
  _group.traverse((o) => {
@@ -529,7 +545,7 @@ export function unmount() {
529
  _stage.scene.remove(_group);
530
  }
531
  } catch (_) {}
532
- _group = _overlay = null;
533
  _floor = null;
534
  _seqGroup = null; _tokDots = []; _infoSpikes = []; _bndFixed = []; _bndDla = [];
535
  _curveGroup = null; _curveFixed = []; _curveDla = [];
 
42
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
43
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
44
 
45
+ import { createShowcase } from "./_showcase.js";
46
+
47
  const ID = "dla";
48
  const TITLE = "Dynamic Linear Attention";
49
 
 
68
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
69
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
70
  let _plain = false;
71
+ let _show = null;
72
 
73
  // geometry handles
74
  let _floor = null;
 
459
  _el["plain"] = pd;
460
  _overlay.appendChild(pd);
461
 
462
+ // Fold the legacy panel into the shared showcase overlay (surfaces/_showcase.js):
463
+ // title + live badge + doctrine legend live in the always-visible chrome; the
464
+ // descriptive text + KPI card become the collapsible body so the 3D scene is the star.
465
+ _show = createShowcase(_ctx, {
466
+ id: ID, title: TITLE, accent: "#5b8dee",
467
+ badge: _badge,
468
+ legend: true,
469
+ });
470
+ _overlay.style.position = "static";
471
+ _overlay.style.left = _overlay.style.top = "auto";
472
+ _overlay.style.maxWidth = "none";
473
+ _overlay.style.font = "inherit";
474
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title
475
+ _show.body.appendChild(_overlay);
476
  _paintOverlay();
477
  }
478
 
 
532
  // =============================================================================
533
  export function unmount() {
534
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
535
+ try { if (_show) _show.destroy(); } catch (_) {}
536
  try {
537
  if (_group && _stage) {
538
  _group.traverse((o) => {
 
545
  _stage.scene.remove(_group);
546
  }
547
  } catch (_) {}
548
+ _group = _overlay = _show = null;
549
  _floor = null;
550
  _seqGroup = null; _tokDots = []; _infoSpikes = []; _bndFixed = []; _bndDla = [];
551
  _curveGroup = null; _curveFixed = []; _curveDla = [];
static/3d/surfaces/dllm.js CHANGED
@@ -42,6 +42,8 @@
42
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
43
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
44
 
 
 
45
  const ID = "dllm";
46
  const TITLE = "Diffusion-LLM Parallel Denoising (live)";
47
 
@@ -66,6 +68,7 @@ const MAX_COLS = 16; // wrap the row into a grid after this many columns
66
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
67
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
68
  let _plain = false;
 
69
 
70
  // geometry handles
71
  let _cells = []; // Array<THREE.Mesh> — one per token position
@@ -375,7 +378,20 @@ function _buildOverlay() {
375
  _el["plain"] = pd;
376
  _overlay.appendChild(pd);
377
 
378
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  _paintOverlay();
380
  }
381
 
@@ -427,7 +443,7 @@ function _paintOverlay() {
427
  export function unmount() {
428
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
429
  if (_playTimer) { try { clearInterval(_playTimer); } catch (_) {} _playTimer = null; }
430
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
431
  try {
432
  if (_group && _stage) {
433
  _group.traverse((o) => {
@@ -440,7 +456,7 @@ export function unmount() {
440
  _stage.scene.remove(_group);
441
  }
442
  } catch (_) {}
443
- _group = _overlay = null;
444
  _cells = []; _floor = null; _roundMarker = null;
445
  _el = {}; _badge = null; _plain = false; _frameReg = false;
446
  _playRound = 0;
 
42
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
43
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
44
 
45
+ import { createShowcase } from "./_showcase.js";
46
+
47
  const ID = "dllm";
48
  const TITLE = "Diffusion-LLM Parallel Denoising (live)";
49
 
 
68
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
69
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
70
  let _plain = false;
71
+ let _show = null;
72
 
73
  // geometry handles
74
  let _cells = []; // Array<THREE.Mesh> — one per token position
 
378
  _el["plain"] = pd;
379
  _overlay.appendChild(pd);
380
 
381
+ // Fold the legacy panel into the shared showcase overlay (surfaces/_showcase.js):
382
+ // title + live badge + doctrine legend live in the always-visible chrome; the
383
+ // descriptive text + KPI card become the collapsible body so the 3D scene is the star.
384
+ _show = createShowcase(_ctx, {
385
+ id: ID, title: TITLE, accent: "#5b8dee",
386
+ badge: _badge,
387
+ legend: true,
388
+ });
389
+ _overlay.style.position = "static";
390
+ _overlay.style.left = _overlay.style.top = "auto";
391
+ _overlay.style.maxWidth = "none";
392
+ _overlay.style.font = "inherit";
393
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title
394
+ _show.body.appendChild(_overlay);
395
  _paintOverlay();
396
  }
397
 
 
443
  export function unmount() {
444
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
445
  if (_playTimer) { try { clearInterval(_playTimer); } catch (_) {} _playTimer = null; }
446
+ try { if (_show) _show.destroy(); } catch (_) {}
447
  try {
448
  if (_group && _stage) {
449
  _group.traverse((o) => {
 
456
  _stage.scene.remove(_group);
457
  }
458
  } catch (_) {}
459
+ _group = _overlay = _show = null;
460
  _cells = []; _floor = null; _roundMarker = null;
461
  _el = {}; _badge = null; _plain = false; _frameReg = false;
462
  _playRound = 0;
static/3d/surfaces/elf.js CHANGED
@@ -45,6 +45,8 @@
45
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
46
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
47
 
 
 
48
  const ID = "elf";
49
  const TITLE = "ELF · Continuous-Embedding Flow Matching (live)";
50
 
@@ -66,6 +68,7 @@ const SEQ_SPREAD = 2.6; // z-offset per sequence position (fans the 4 position
66
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
67
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
68
  let _plain = false;
 
69
 
70
  // geometry handles
71
  let _vocabDots = []; // Array<THREE.Mesh> — the 6 unit-circle symbol embeddings
@@ -392,7 +395,20 @@ function _buildOverlay() {
392
  _el["plain"] = pd;
393
  _overlay.appendChild(pd);
394
 
395
- (ctx.container || document.body).appendChild(_overlay);
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  _paintOverlay();
397
  }
398
 
@@ -457,7 +473,7 @@ function _paintOverlay() {
457
  // =============================================================================
458
  export function unmount() {
459
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
460
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
461
  try {
462
  if (_group && _stage) {
463
  _group.traverse((o) => {
@@ -470,7 +486,7 @@ export function unmount() {
470
  _stage.scene.remove(_group);
471
  }
472
  } catch (_) {}
473
- _group = _overlay = null;
474
  _vocabDots = []; _pathLines = []; _x0Marks = []; _tgtMarks = []; _decMarks = []; _floor = null;
475
  _el = {}; _badge = null; _plain = false; _frameReg = false;
476
  _stage = _THREE = _ctx = null;
 
45
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
46
  // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
47
 
48
+ import { createShowcase } from "./_showcase.js";
49
+
50
  const ID = "elf";
51
  const TITLE = "ELF · Continuous-Embedding Flow Matching (live)";
52
 
 
68
  let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
69
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
70
  let _plain = false;
71
+ let _show = null;
72
 
73
  // geometry handles
74
  let _vocabDots = []; // Array<THREE.Mesh> — the 6 unit-circle symbol embeddings
 
395
  _el["plain"] = pd;
396
  _overlay.appendChild(pd);
397
 
398
+ // Fold the legacy panel into the shared showcase overlay (surfaces/_showcase.js):
399
+ // title + live badge + doctrine legend live in the always-visible chrome; the
400
+ // descriptive text + KPI card become the collapsible body so the 3D scene is the star.
401
+ _show = createShowcase(_ctx, {
402
+ id: ID, title: TITLE, accent: "#5b8dee",
403
+ badge: _badge,
404
+ legend: true,
405
+ });
406
+ _overlay.style.position = "static";
407
+ _overlay.style.left = _overlay.style.top = "auto";
408
+ _overlay.style.maxWidth = "none";
409
+ _overlay.style.font = "inherit";
410
+ if (_overlay.firstChild) _overlay.removeChild(_overlay.firstChild); // drop duplicate title
411
+ _show.body.appendChild(_overlay);
412
  _paintOverlay();
413
  }
414
 
 
473
  // =============================================================================
474
  export function unmount() {
475
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
476
+ try { if (_show) _show.destroy(); } catch (_) {}
477
  try {
478
  if (_group && _stage) {
479
  _group.traverse((o) => {
 
486
  _stage.scene.remove(_group);
487
  }
488
  } catch (_) {}
489
+ _group = _overlay = _show = null;
490
  _vocabDots = []; _pathLines = []; _x0Marks = []; _tgtMarks = []; _decMarks = []; _floor = null;
491
  _el = {}; _badge = null; _plain = false; _frameReg = false;
492
  _stage = _THREE = _ctx = null;
static/3d/surfaces/energy.js CHANGED
@@ -39,6 +39,8 @@
39
  //
40
  // CONTRACT: default-export { id, title, endpoints[], mount(ctx), unmount() }.
41
 
 
 
42
  const ID = "energy";
43
  const TITLE = "Energy · Harvest";
44
  const POSTURE_EP = "/api/a11oy/v1/harvest/posture";
@@ -54,6 +56,7 @@ let _stage = null, _THREE = null, _ctx = null;
54
  let _hPosture = null, _hLoop = null;
55
  let _root = null; // THREE.Group holding everything we add (one remove on unmount)
56
  let _overlay = null; // DOM HUD panel
 
57
  let _frameFn = null; // our per-frame callback (guards on _root null after unmount)
58
  let _hud = {}; // references to live HUD chip/value elements
59
  let _scene = null; // built scene-object refs the frame loop + pollers animate
@@ -476,25 +479,21 @@ function build() {
476
  // ----------------------------------------------------------------------------
477
  function buildHUD() {
478
  const lab = _ctx.label;
 
 
 
 
 
 
 
 
479
  _overlay = document.createElement("div");
480
  _overlay.className = "szl3d-energy-hud";
481
  Object.assign(_overlay.style, {
482
- position: "absolute", left: "14px", top: "14px", zIndex: "6",
483
  display: "flex", flexDirection: "column", gap: "7px",
484
- maxWidth: "min(94%,430px)", font: "12px ui-monospace,SFMono-Regular,Menlo,monospace",
485
- color: "#cfe0ea", background: "rgba(6,11,16,.72)", border: "1px solid #15212c",
486
- borderRadius: "10px", padding: "12px 14px", backdropFilter: "blur(3px)",
487
  });
488
 
489
- const title = document.createElement("div");
490
- title.style.cssText = "font:600 13px ui-sans-serif,system-ui;color:#eef3f6;letter-spacing:.4px;display:flex;gap:8px;align-items:center";
491
- title.innerHTML = "⚡ Energy · Harvest <span style='color:#46586a;font-weight:400'>· flagship · live joules funnel</span>";
492
- _overlay.appendChild(title);
493
-
494
- const badge = _ctx.live.createBadge();
495
- _overlay.appendChild(badge.el);
496
- _hud.badge = badge;
497
-
498
  // a small row factory: label text + value + honesty chip
499
  function row(key, name) {
500
  const wrap = document.createElement("div");
@@ -524,10 +523,7 @@ function buildHUD() {
524
  note.textContent = "joules MEASURED only on-box (NVML exporter). Off-box label=sample, evidence empty — the funnel shows its structure, never a fabricated fill. Modeled on Electricity Maps + deck.gl; rendered in three.js (see manifest).";
525
  _overlay.appendChild(note);
526
 
527
- const legend = _ctx.label.legend(); legend.style.opacity = "0.85"; legend.style.marginTop = "2px";
528
- _overlay.appendChild(legend);
529
-
530
- (_ctx.container || document.body).appendChild(_overlay);
531
  }
532
 
533
  function _setRow(key, text, label) {
@@ -684,6 +680,7 @@ function mount(ctx) {
684
  function unmount() {
685
  try { if (_hPosture) _hPosture.stop(); } catch (_) {}
686
  try { if (_hLoop) _hLoop.stop(); } catch (_) {}
 
687
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
688
  try { if (_root && _stage) _stage.scene.remove(_root); } catch (_) {}
689
  // dispose geometries/materials we created under _root
@@ -694,7 +691,7 @@ function unmount() {
694
  });
695
  } catch (_) {}
696
  try { if (_stage) _stage.setBloom(false); } catch (_) {}
697
- _hPosture = null; _hLoop = null; _overlay = null; _root = null;
698
  _scene = null; _frameFn = null; _hud = {}; _ctx = null; _stage = null; _THREE = null;
699
  }
700
 
 
39
  //
40
  // CONTRACT: default-export { id, title, endpoints[], mount(ctx), unmount() }.
41
 
42
+ import { createShowcase } from "./_showcase.js";
43
+
44
  const ID = "energy";
45
  const TITLE = "Energy · Harvest";
46
  const POSTURE_EP = "/api/a11oy/v1/harvest/posture";
 
56
  let _hPosture = null, _hLoop = null;
57
  let _root = null; // THREE.Group holding everything we add (one remove on unmount)
58
  let _overlay = null; // DOM HUD panel
59
+ let _show = null; // shared collapsible showcase chrome
60
  let _frameFn = null; // our per-frame callback (guards on _root null after unmount)
61
  let _hud = {}; // references to live HUD chip/value elements
62
  let _scene = null; // built scene-object refs the frame loop + pollers animate
 
479
  // ----------------------------------------------------------------------------
480
  function buildHUD() {
481
  const lab = _ctx.label;
482
+ const badge = _ctx.live.createBadge();
483
+ _hud.badge = badge;
484
+
485
+ _show = createShowcase(_ctx, {
486
+ id: ID, title: TITLE, accent: "#5b8dee", badge, legend: true,
487
+ });
488
+
489
+ // rows fold into the (collapsed) showcase body; the 3D funnel stays the star.
490
  _overlay = document.createElement("div");
491
  _overlay.className = "szl3d-energy-hud";
492
  Object.assign(_overlay.style, {
 
493
  display: "flex", flexDirection: "column", gap: "7px",
494
+ font: "12px ui-monospace,SFMono-Regular,Menlo,monospace", color: "#cfe0ea",
 
 
495
  });
496
 
 
 
 
 
 
 
 
 
 
497
  // a small row factory: label text + value + honesty chip
498
  function row(key, name) {
499
  const wrap = document.createElement("div");
 
523
  note.textContent = "joules MEASURED only on-box (NVML exporter). Off-box label=sample, evidence empty — the funnel shows its structure, never a fabricated fill. Modeled on Electricity Maps + deck.gl; rendered in three.js (see manifest).";
524
  _overlay.appendChild(note);
525
 
526
+ _show.body.appendChild(_overlay);
 
 
 
527
  }
528
 
529
  function _setRow(key, text, label) {
 
680
  function unmount() {
681
  try { if (_hPosture) _hPosture.stop(); } catch (_) {}
682
  try { if (_hLoop) _hLoop.stop(); } catch (_) {}
683
+ try { if (_show) _show.destroy(); } catch (_) {}
684
  try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
685
  try { if (_root && _stage) _stage.scene.remove(_root); } catch (_) {}
686
  // dispose geometries/materials we created under _root
 
691
  });
692
  } catch (_) {}
693
  try { if (_stage) _stage.setBloom(false); } catch (_) {}
694
+ _hPosture = null; _hLoop = null; _overlay = null; _show = null; _root = null;
695
  _scene = null; _frameFn = null; _hud = {}; _ctx = null; _stage = null; _THREE = null;
696
  }
697
 
static/3d/surfaces/episodic.js CHANGED
@@ -41,6 +41,8 @@
41
  // 0 RUNTIME CDN. Vendored three.js r170 via page importmap.
42
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
43
 
 
 
44
  const ID = "episodic";
45
  const TITLE = "Episodic Memory · Temporal Knowledge-Graph (live)";
46
 
@@ -59,9 +61,8 @@ const C_GRID = 0x1b3a44; // floor / link colour
59
  const N_SLOTS = 16; // visual episode slots (matches endpoint n_episodes cap)
60
  const SPAN_X = 16; // world-unit span of the time axis
61
 
62
- let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
63
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
64
- let _plain = false;
65
 
66
  // geometry handles
67
  let _nodes = []; // Array<THREE.Mesh> — one per episode
@@ -269,107 +270,37 @@ function _onFrame() {
269
  // =============================================================================
270
  function _buildOverlay() {
271
  const ctx = _ctx;
272
- _overlay = document.createElement("div");
273
- Object.assign(_overlay.style, {
274
- position: "absolute", left: "14px", top: "14px", zIndex: "6",
275
- display: "flex", flexDirection: "column", gap: "8px",
276
- maxWidth: "min(94%,440px)",
277
- font: "12px ui-sans-serif,system-ui,Segoe UI,Roboto,Arial",
278
- color: "#eef3f6",
279
- });
280
-
281
- const h = document.createElement("div");
282
- h.style.cssText = "font:600 13px ui-sans-serif,system-ui;letter-spacing:.4px";
283
- h.textContent = TITLE;
284
- _overlay.appendChild(h);
285
-
286
- const sub = document.createElement("div");
287
- sub.style.cssText = "color:#9fb1bf;font-size:11px;line-height:1.55";
288
- sub.innerHTML =
289
- 'A small graph of <b>episodes</b> (event/fact nodes) laid out on a time axis, sized by ' +
290
- '<b>salience</b>, linked by temporal-succession and semantic-relatedness edges. A ' +
291
- '<b>RECALL</b> query lights up the top-k episodes by recency\u00d7salience\u00d7relatedness. ' +
292
- 'Honesty label <b>MODELED</b> (synthetic/public episodes; clean-room-inspired by ' +
293
- 'MemMachine\u2019s episodic/graph memory idea \u2014 not a reproduction). 0 runtime CDN.';
294
- _overlay.appendChild(sub);
295
-
296
- const brow = document.createElement("div");
297
- brow.style.cssText = "display:flex;gap:8px;align-items:center;flex-wrap:wrap";
298
- if (_badge && _badge.el) brow.appendChild(_badge.el);
299
- _overlay.appendChild(brow);
300
-
301
- const card = document.createElement("div");
302
- card.style.cssText = "background:#0a1117;border:1px solid #1d2a36;border-radius:9px;padding:9px 10px;display:flex;flex-direction:column;gap:6px";
303
-
304
- const chead = document.createElement("div");
305
- chead.style.cssText = "display:flex;align-items:center;gap:8px;flex-wrap:wrap";
306
- const dot = document.createElement("span");
307
- dot.style.cssText = "width:9px;height:9px;border-radius:50%;background:#5b8dee;box-shadow:0 0 7px #5b8dee";
308
- const nm = document.createElement("b");
309
- nm.style.cssText = "font-size:12px;color:#5b8dee;letter-spacing:.3px";
310
- nm.textContent = "episodic";
311
- chead.appendChild(dot); chead.appendChild(nm);
312
- card.appendChild(chead);
313
-
314
- const grid = document.createElement("div");
315
- grid.style.cssText = "display:grid;grid-template-columns:1fr;gap:4px";
316
-
317
- function kpiRow(id, label) {
318
- const r = document.createElement("div");
319
- r.style.cssText = "display:flex;justify-content:space-between;gap:10px;font-size:11px";
320
- const l = document.createElement("span"); l.style.cssText = "color:#9fb1bf"; l.textContent = label;
321
- const v = document.createElement("b");
322
- v.id = id;
323
- v.style.cssText = "font-variant-numeric:tabular-nums;color:#eef3f6;text-align:right;max-width:58%";
324
- v.textContent = "\u2014";
325
- _el[id] = v;
326
- r.appendChild(l); r.appendChild(v); return r;
327
- }
328
-
329
- grid.appendChild(kpiRow("ep-n", "episodes in graph"));
330
- grid.appendChild(kpiRow("ep-query", "recall query"));
331
- grid.appendChild(kpiRow("ep-top1", "top recall (id, score)"));
332
- grid.appendChild(kpiRow("ep-receipt", "receipt type"));
333
- grid.appendChild(kpiRow("ep-label", "honesty label"));
334
- card.appendChild(grid);
335
-
336
- const fn = document.createElement("div");
337
- fn.style.cssText = "font-size:9.5px;color:#6b7a86;line-height:1.5";
338
- fn.textContent = "MemMachine github.com/MemMachine/MemMachine (Apache-2.0) \u00b7 Tulving (1972) episodic/semantic memory \u00b7 Zep/Graphiti github.com/getzep/graphiti. MODELED \u00b7 not claimed-as.";
339
- card.appendChild(fn);
340
- _overlay.appendChild(card);
341
-
342
- const pl = document.createElement("button");
343
- pl.textContent = "\u25d1 what this means";
344
- pl.title = "Toggle plain-language explanation for investors & consumers.";
345
- pl.style.cssText = "font:11px ui-monospace,monospace;padding:5px 11px;border-radius:7px;border:1px solid #3af4c8;background:#08140f;color:#3af4c8;cursor:pointer;width:fit-content";
346
- pl.addEventListener("click", () => {
347
- _plain = !_plain;
348
- pl.style.background = _plain ? "#0f2a20" : "#08140f";
349
- _applyPlain();
350
  });
351
- _overlay.appendChild(pl);
352
 
353
- const pd = document.createElement("div");
354
- pd.id = "ep-plain";
355
- pd.style.cssText = "font-size:10.5px;color:#c9d6df;line-height:1.55;border:1px dashed #26333f;border-radius:7px;padding:7px 9px;display:none";
356
- _el["plain"] = pd;
357
- _overlay.appendChild(pd);
358
 
359
- (ctx.container || document.body).appendChild(_overlay);
360
  _paintOverlay();
361
  }
362
 
363
- function _applyPlain() {
364
- const pd = _el["plain"];
365
- if (!pd) return;
366
- pd.style.display = _plain ? "block" : "none";
367
- if (!_plain) return;
368
  const n = S.episodes ? String(S.episodes.length) : "loading\u2026";
369
  const top0 = (S.topK && S.topK[0]) ? S.topK[0] : null;
370
  const topTxt = top0 ? (top0.id + " (score " + fx(top0.score, 3) + ")") : "loading\u2026";
371
  const rtype = S.receiptType || "loading\u2026";
372
- pd.innerHTML =
373
  "<b>What this means:</b> Most AI systems today either forget everything between " +
374
  "sessions or dump raw transcripts into a vector store. This organ demonstrates a " +
375
  "<b>third option</b>: memories as a small, auditable <b>graph</b> of discrete " +
@@ -381,7 +312,7 @@ function _applyPlain() {
381
  "cryptographic signing, never faked as one. " +
382
  "Plain: this is what \u201cthe AI remembers what happened, and can prove what it " +
383
  "remembers,\u201d looks like \u2014 but this view is a <b>MODELED</b> demonstration with " +
384
- "synthetic/public data, not a production memory store.";
385
  }
386
 
387
  function _tok(s) {
@@ -404,7 +335,7 @@ function _paintOverlay() {
404
  _set("ep-receipt", t || (S.receiptType || "\u2014"));
405
  // honesty label verbatim — never upgraded
406
  _set("ep-label", t || (S.label || "MODELED"));
407
- if (_plain) _applyPlain();
408
  }
409
 
410
  // =============================================================================
@@ -412,7 +343,7 @@ function _paintOverlay() {
412
  // =============================================================================
413
  export function unmount() {
414
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
415
- try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
416
  try {
417
  if (_group && _stage) {
418
  _group.traverse((o) => {
@@ -425,9 +356,9 @@ export function unmount() {
425
  _stage.scene.remove(_group);
426
  }
427
  } catch (_) {}
428
- _group = _overlay = null;
429
  _nodes = []; _tempoLinks = null; _semLinks = null; _queryMarker = null;
430
- _el = {}; _badge = null; _plain = false; _frameReg = false;
431
  _stage = _THREE = _ctx = null;
432
  S.label = S.episodes = S.edges = S.topK = S.query = S.formula = S.receiptType = null;
433
  S.state = "init";
 
41
  // 0 RUNTIME CDN. Vendored three.js r170 via page importmap.
42
  // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
43
 
44
+ import { createShowcase } from "./_showcase.js";
45
+
46
  const ID = "episodic";
47
  const TITLE = "Episodic Memory · Temporal Knowledge-Graph (live)";
48
 
 
61
  const N_SLOTS = 16; // visual episode slots (matches endpoint n_episodes cap)
62
  const SPAN_X = 16; // world-unit span of the time axis
63
 
64
+ let _stage = null, _THREE = null, _ctx = null, _group = null, _show = null;
65
  let _frameReg = false, _polls = [], _el = {}, _badge = null;
 
66
 
67
  // geometry handles
68
  let _nodes = []; // Array<THREE.Mesh> — one per episode
 
270
  // =============================================================================
271
  function _buildOverlay() {
272
  const ctx = _ctx;
273
+ _show = createShowcase(ctx, {
274
+ id: ID, title: TITLE, accent: "#5b8dee",
275
+ badge: _badge,
276
+ chips: [{ label: "MODELED", text: "episodic graph", name: "ep" }],
277
+ legend: ["MODELED", "SAMPLE"],
278
+ description:
279
+ 'A small graph of <b>episodes</b> (event/fact nodes) laid out on a time axis, sized by ' +
280
+ '<b>salience</b>, linked by temporal-succession and semantic-relatedness edges. A ' +
281
+ '<b>RECALL</b> query lights up the top-k episodes by recency\u00d7salience\u00d7relatedness. ' +
282
+ 'Honesty label <b>MODELED</b> (synthetic/public episodes; clean-room-inspired by ' +
283
+ 'MemMachine\u2019s episodic/graph memory idea \u2014 not a reproduction). 0 runtime CDN.',
284
+ citations:
285
+ "MemMachine github.com/MemMachine/MemMachine (Apache-2.0) \u00b7 Tulving (1972) episodic/semantic memory \u00b7 Zep/Graphiti github.com/getzep/graphiti. MODELED \u00b7 not claimed-as.",
286
+ plain: { html: _plainHtml },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  });
 
288
 
289
+ _el["ep-n"] = _show.addField("episodes in graph");
290
+ _el["ep-query"] = _show.addField("recall query");
291
+ _el["ep-top1"] = _show.addField("top recall (id, score)");
292
+ _el["ep-receipt"] = _show.addField("receipt type");
293
+ _el["ep-label"] = _show.addField("honesty label");
294
 
 
295
  _paintOverlay();
296
  }
297
 
298
+ function _plainHtml() {
 
 
 
 
299
  const n = S.episodes ? String(S.episodes.length) : "loading\u2026";
300
  const top0 = (S.topK && S.topK[0]) ? S.topK[0] : null;
301
  const topTxt = top0 ? (top0.id + " (score " + fx(top0.score, 3) + ")") : "loading\u2026";
302
  const rtype = S.receiptType || "loading\u2026";
303
+ return (
304
  "<b>What this means:</b> Most AI systems today either forget everything between " +
305
  "sessions or dump raw transcripts into a vector store. This organ demonstrates a " +
306
  "<b>third option</b>: memories as a small, auditable <b>graph</b> of discrete " +
 
312
  "cryptographic signing, never faked as one. " +
313
  "Plain: this is what \u201cthe AI remembers what happened, and can prove what it " +
314
  "remembers,\u201d looks like \u2014 but this view is a <b>MODELED</b> demonstration with " +
315
+ "synthetic/public data, not a production memory store.");
316
  }
317
 
318
  function _tok(s) {
 
335
  _set("ep-receipt", t || (S.receiptType || "\u2014"));
336
  // honesty label verbatim — never upgraded
337
  _set("ep-label", t || (S.label || "MODELED"));
338
+ if (_show) { _show.setChip("ep", S.label || "MODELED", { text: "episodic graph" }); _show.refreshPlain(); }
339
  }
340
 
341
  // =============================================================================
 
343
  // =============================================================================
344
  export function unmount() {
345
  _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
346
+ try { if (_show) _show.destroy(); } catch (_) {}
347
  try {
348
  if (_group && _stage) {
349
  _group.traverse((o) => {
 
356
  _stage.scene.remove(_group);
357
  }
358
  } catch (_) {}
359
+ _group = _show = null;
360
  _nodes = []; _tempoLinks = null; _semLinks = null; _queryMarker = null;
361
+ _el = {}; _badge = null; _frameReg = false;
362
  _stage = _THREE = _ctx = null;
363
  S.label = S.episodes = S.edges = S.topK = S.query = S.formula = S.receiptType = null;
364
  S.state = "init";