--- /** * The method as a closed loop of four stages, drawn as a spec-sheet diagram. * Main nodes sit on the corners of the loop with their labels inside; * each stage's instruments fan outwards. Wide and tall compositions of the same drawing. */ interface Stage { title: string; items: string[] } interface Props { title: string; desc: string; stages: Stage[] } const { title, desc, stages } = Astro.props; const stroke = 1.25; const ring = 36; /* Wide composition: 1400 x 560. Nodes on the corners of a loop. */ const W = { w: 1400, h: 560, x1: 420, x2: 980, y1: 140, y2: 420, sat: 175, dy: 62 }; const wideNodes = [ { x: W.x1, y: W.y1, side: -1, up: -1 }, // top-left: threat analysis { x: W.x2, y: W.y1, side: 1, up: -1 }, // top-right: engineering { x: W.x2, y: W.y2, side: 1, up: 1 }, // bottom-right: verification { x: W.x1, y: W.y2, side: -1, up: 1 }, // bottom-left: monitoring ]; /* Tall composition: 400 x 780. Nodes stacked on a spine, the loop closes on the left. The title sits right of the node, its instruments hang below the title. */ const T = { w: 400, h: 780, x: 60, loopX: 20, y0: 60, step: 200, ring: 28, labelX: 40, satX: 44, satY: 36, dy: 28 }; const tallNodes = stages.map((_, i) => ({ x: T.x, y: T.y0 + i * T.step })); /* Direction tick: a small chevron at the midpoint of an edge, pointing along it. */ const tick = (x: number, y: number, dx: number, dy: number, s = 7) => { const len = Math.hypot(dx, dy) || 1; const ux = dx / len, uy = dy / len; const px = -uy, py = ux; return `${x - ux * s + px * s},${y - uy * s + py * s} ${x},${y} ${x - ux * s - px * s},${y - uy * s - py * s}`; }; --- {title} {desc} {wideNodes.map((n, i) => ( {stages[i].items.map((_, k) => { const sx = n.x + n.side * W.sat; const sy = n.y + (k - 1) * W.dy; return ; })} ))} {wideNodes.map((n, i) => ( {stages[i].items.map((_, k) => )} ))} {wideNodes.map((n, i) => ( {stages[i].title} ))} {wideNodes.map((n, i) => stages[i].items.map((item, k) => ( {item} )))} {title} {desc} {tallNodes.slice(0, 3).map((n) => )} {tallNodes.map((n, i) => ( {stages[i].items.map((_, k) => )} ))} {tallNodes.map((n, i) => ( {stages[i].items.map((_, k) => )} ))} {tallNodes.map((n, i) => {stages[i].title})} {tallNodes.map((n, i) => stages[i].items.map((item, k) => ( {item} )))}