// Caption the long-term target without changing its native topology. // Text lives inside the SVG so standalone exports retain proposal/line semantics. export function targetCaption(html) { const roots = [...html.matchAll(/]*role="img"[^>]*>/g)]; if (roots.length !== 1) throw new Error('Target caption SVG contract drift'); const root = roots[0][0]; const match = /viewBox="([\d. -]+)"/.exec(root); if (!match) throw new Error('Target caption requires viewBox'); const [x,y,w,h] = match[1].trim().split(/\s+/).map(Number); const size = Math.min(26, w / 30); const lines = ['Long-term Target — not a six-month commitment', 'Solid: lifecycle · Dotted: execution / governance', 'Dashed: human-controlled contributions']; const extra = size * 5; const caption = `${lines.map((line,i) => `${line}`).join('')}`; return html.replace(root, root.replace(match[0], `viewBox="${x} ${y} ${w} ${h+extra}"`) + caption); }