/* ============================================================ qft-bc-composite.mjs — quick play: a QFT field plate UNDERNEATH a bubble-chamber plate. Both render to standalone SVG; we embed each as a self-contained data-URI in one outer SVG (no defs/id collisions), and put the bubble chamber on top with mix-blend-mode:multiply — the lightbox metaphor: the field glows underneath, the dark ink darkens it, the light paper drops out. Usage: node tools/qft-bc-composite.mjs [qftSeed] [bcSeed] [out.html] [size] ============================================================ */ import { writeFileSync } from 'node:fs'; // --- QFT side --- import { generateQFTScene } from '../src/qft/scene.js'; import { paramsFromSeed as qftParams } from '../src/qft/params.js'; import { renderQFTSVG } from '../src/qft/renderer.js'; // --- bubble chamber side --- import { generateScene } from '../src/scene/scene.js'; import { renderSVG } from '../src/render/svgVector.js'; import { paramsFromSeed as bcParams } from '../src/scene/params.js'; import { GROUPS, TOGGLES, FIXED } from '../src/ui/controls.js'; const argv = process.argv.slice(2); const qftSeed = argv[0] || 'VACUUM-5113'; const bcSeed = argv[1] || 'LAMBDA-2648'; const out = argv[2] || '/tmp/qft-bc.html'; const SIZE = +(argv[3] || 1600); // pale QFT substrate so it reads as a luminous ground under the ink const qp = qftParams(qftSeed); qp.substrate = 'cream'; // force a light ground so the multiply'd BC ink reads qp.glow = 0.6; // bubble chamber: default mono, light cream paper → multiply lets the field through const bp = { ...FIXED, ...bcParams(bcSeed) }; for (const g of GROUPS) for (const c of g.controls) if (!(c.id in bp)) bp[c.id] = c.value; for (const t of TOGGLES) if (!(t.id in bp)) bp[t.id] = t.value; const qftSvg = renderQFTSVG(generateQFTScene(qp), qp, SIZE); const bcSvg = renderSVG(generateScene(bp), bp, SIZE); const dataUri = (svg) => 'data:image/svg+xml;base64,' + Buffer.from(svg).toString('base64'); const composite = ` `; const html = ` ${composite}`; writeFileSync(out, html); writeFileSync(out.replace(/\.html$/, '.svg'), composite); console.log(`composite -> ${out} (qft=${qftSeed} ${qp.archetype}, bc=${bcSeed}, ${SIZE}px)`);