/* ============================================================
   PAGE — P&ID MASTER DIAGRAM
   Faithful reproduction of the Bierkowo plant P&ID layout:
   PPM percolate-spray valve banks, compressed-air room, two
   gas/heating domes, 7 fermentation tunnels + dehydration halls,
   biogas dome, digestate + percolate reservoirs, sand traps,
   pumps room, biofilter room, mixing/feeding hall, title block —
   tied together by a multi-colour pipe network. Live + clickable.
   ============================================================ */
const h = React.createElement;

/* media colours (KEY LINES) */
const MED = {
  biogas:   "#F2941F",
  percolate:"#C98A5A",
  air:      "#2A9DE0",
  heat_s:   "#d33a2c",
  heat_r:   "#6E97C4",
  water:    "#3D8BE0",
  digestate:"#5fb478",
};

/* poly path from [[x,y],...] */
function poly(pts) { return pts.map((p, i) => (i ? "L" : "M") + p[0] + " " + p[1]).join(" "); }
let _pk = 0;
/* a pipe: thin coloured line, optional animated flow overlay */
function pp(pts, color, flow, dash) {
  const d = poly(pts); const k = "pp" + (_pk++);
  const els = [h("path", { key: k + "a", d, fill: "none", stroke: color, strokeWidth: 2, strokeLinejoin: "round", strokeLinecap: "round", opacity: 0.92, strokeDasharray: dash || null })];
  if (flow) els.push(h("path", { key: k + "f", d, fill: "none", stroke: "#eaf4ff", strokeWidth: 2, className: "flow" + (color === MED.biogas ? " gas" : ""), strokeLinecap: "round", opacity: 0.7 }));
  return els;
}
/* room / building outline with label */
function room(x, y, w, hh, label, opts) {
  opts = opts || {};
  return h("g", { key: "rm" + x + "-" + y + "-" + label },
    h("rect", { x, y, width: w, height: hh, rx: 4, fill: opts.fill || "rgba(13,31,60,0.4)", stroke: opts.stroke || "rgba(122,160,209,0.32)", strokeWidth: 1.3, strokeDasharray: opts.dash ? "5 4" : null }),
    h("text", { x: x + 8, y: y + 14, fill: opts.lc || "#8fb4e6", style: { font: "700 9.5px var(--font-mono)", letterSpacing: "0.06em" } }, label)
  );
}
function lbl(x, y, s, size, col, anchor) {
  return h("text", { key: "lb" + x + y + s, x, y, fill: col || "#647a98", textAnchor: anchor || "start", style: { font: `600 ${size || 9}px var(--font-mono)` } }, s);
}

/* PPM percolate-spray valve bank (header + row of valve ticks) */
function ppmBank(x, y, w, label, n) {
  const els = [
    h("rect", { x, y, width: w, height: 50, rx: 3, fill: "rgba(20,12,30,0.5)", stroke: "rgba(196,108,196,0.4)", strokeWidth: 1.1 }),
    lbl(x + 6, y + 13, label, 8.5, "#c98ad6"),
    h("line", { x1: x + 8, y1: y + 22, x2: x + w - 8, y2: y + 22, stroke: "#9a5fb0", strokeWidth: 1.4 }),
  ];
  const span = w - 24, step = span / (n - 1);
  for (let i = 0; i < n; i++) {
    const vx = x + 12 + i * step;
    els.push(h("line", { key: "vl" + x + i, x1: vx, y1: y + 22, x2: vx, y2: y + 30, stroke: "#9a5fb0", strokeWidth: 1.1 }));
    els.push(h("path", { key: "vt" + x + i, d: `M ${vx - 3} ${y + 30} L ${vx + 3} ${y + 30} L ${vx} ${y + 35} Z`, fill: "#c46cc4", opacity: 0.85 }));
    els.push(h("line", { key: "vd" + x + i, x1: vx, y1: y + 35, x2: vx, y2: y + 44, stroke: "rgba(196,108,196,0.5)", strokeWidth: 0.9 }));
  }
  return h("g", { key: "ppm" + label }, ...els);
}

/* instrument bubble (static, drawn in svg) */
function bub(x, y, code, col) {
  return h("g", { key: "bub" + x + y + code },
    h("circle", { cx: x, cy: y, r: 9, fill: "rgba(6,15,31,0.85)", stroke: col || "#5b6b7d", strokeWidth: 1.2 }),
    h("text", { x, y: y + 3, fill: col || "#8fb4e6", textAnchor: "middle", style: { font: "600 7px var(--font-mono)" } }, code)
  );
}

function PIDPage() {
  const { t, lang } = useApp();
  const D = id => window.devById(id);
  const W = 2520, Ht = 1180;
  const pz = window.usePanZoom(W, Ht, 0.6);
  const zoom = pz.zoom;

  // tunnel geometry
  const TUN_X = 1015, TUN_W = 330, TUN_H = 96, TUN_GAP = 26;
  const TUN_Y0 = 168;
  const tunY = i => TUN_Y0 + i * (TUN_H + TUN_GAP);

  // ---- build static SVG content ----
  const svg = [];
  svg.push(h("rect", { key: "bgp", width: W, height: Ht, fill: "url(#pidgrid)" }));

  // top distribution bus (header running across the top)
  const busY = [44, 52, 60, 68, 76];
  const busC = [MED.biogas, MED.percolate, MED.air, MED.heat_s, MED.digestate];
  busY.forEach((yy, i) => svg.push(...pp([[70, yy], [2360, yy]], busC[i], false)));
  svg.push(lbl(1490, 150, "RACK", 10, "#647a98"));
  svg.push(h("rect", { key: "rack", x: 1470, y: 92, width: 60, height: 30, rx: 2, fill: "none", stroke: "rgba(122,160,209,0.4)", strokeDasharray: "3 3" }));

  // ===== PPM percolate-spray valve banks (top-left) =====
  const banksL = ["PPM00", "PPM02", "PPM03", "PPM20", "PPM22"];
  const banksR = ["PPM04", "PPM05", "PPM01", "PPM21", "PPM24"];
  banksL.forEach((b, i) => svg.push(ppmBank(80, 86 + i * 62, 250, b, 14)));
  banksR.forEach((b, i) => svg.push(ppmBank(348, 86 + i * 62, 250, b, 14)));
  // bank feed risers up to bus
  svg.push(...pp([[205, 86], [205, 76]], MED.percolate, false));
  svg.push(...pp([[473, 86], [473, 76]], MED.percolate, false));
  // banks -> down to a collector that runs toward the tunnels
  svg.push(...pp([[205, 396], [205, 430], [630, 430]], MED.percolate, true));
  svg.push(...pp([[473, 396], [473, 416], [630, 416]], MED.percolate, true));
  svg.push(...pp([[630, 416], [630, 760], [1015, 760]], MED.percolate, true));

  // ===== Compressed-air production & distribution room =====
  svg.push(room(70, 470, 540, 220, "", { fill: "rgba(13,31,60,0.45)" }));
  svg.push(lbl(86, 492, t("air_compressed").toUpperCase(), 9.5, "#8fb4e6"));
  // air receivers + compressors inside
  svg.push(h("rect", { key: "ar1", x: 120, y: 560, width: 36, height: 80, rx: 4, fill: "rgba(42,157,224,0.12)", stroke: "rgba(42,157,224,0.5)" }));
  svg.push(h("rect", { key: "ar2", x: 170, y: 560, width: 36, height: 80, rx: 4, fill: "rgba(42,157,224,0.12)", stroke: "rgba(42,157,224,0.5)" }));
  svg.push(lbl(120, 555, "AR-001/002", 7.5, "#5b9fd0"));
  svg.push(bub(280, 600, "PT", MED.air), bub(330, 600, "FT", MED.air), bub(380, 600, "TT", MED.air));
  svg.push(lbl(86, 678, t("technical_corridor").toUpperCase(), 8, "#647a98"));
  svg.push(h("rect", { key: "actc", x: 80, y: 660, width: 520, height: 22, fill: "rgba(122,160,209,0.05)", stroke: "rgba(122,160,209,0.18)" }));
  // air distribution up to bus and out to plant
  svg.push(...pp([[206, 560], [206, 540], [430, 540], [430, 76]], MED.air, true));
  svg.push(...pp([[540, 600], [700, 600], [700, 200], [1015, 200]], MED.air, true));

  // ===== lower-left gas / heating domes =====
  // dome 1 (heating water buffer) + dome 2 (small)
  const dome = (cx, baseY, r, label, col) => h("g", { key: "dm" + cx },
    h("path", { d: `M ${cx - r} ${baseY} A ${r} ${r} 0 0 1 ${cx + r} ${baseY} Z`, fill: "rgba(42,120,180,0.18)", stroke: "rgba(122,160,209,0.45)", strokeWidth: 1.4 }),
    h("path", { d: `M ${cx - r} ${baseY} A ${r} ${r} 0 0 1 ${cx + r} ${baseY}`, fill: "none", stroke: col, strokeWidth: 1.6, opacity: 0.5 }),
    h("line", { x1: cx - r, y1: baseY, x2: cx + r, y2: baseY, stroke: "rgba(122,160,209,0.4)" }),
    lbl(cx, baseY + 16, label, 8, "#8fb4e6", "middle")
  );
  svg.push(dome(300, 900, 108, "HEATING / COOLING BUFFER", MED.heat_s));
  svg.push(dome(490, 912, 56, "EXPANSION", MED.heat_r));
  svg.push(lbl(120, 990, t("technical_corridor").toUpperCase(), 8, "#647a98"));
  svg.push(h("rect", { key: "ltc", x: 110, y: 974, width: 470, height: 22, fill: "rgba(122,160,209,0.05)", stroke: "rgba(122,160,209,0.18)" }));
  // heating supply/return risers toward tunnels
  svg.push(...pp([[300, 792], [300, 740], [700, 740], [700, 230]], MED.heat_s, true));
  svg.push(...pp([[360, 792], [360, 720], [690, 720], [690, 250]], MED.heat_r, true));

  // ===== TECHNICAL CORRIDOR (left of tunnel stack) =====
  svg.push(h("rect", { key: "tcv", x: 720, y: 150, width: 280, height: 944, fill: "rgba(122,160,209,0.04)", stroke: "rgba(122,160,209,0.22)", strokeDasharray: "5 4" }));
  [1, 3, 5].forEach(i => svg.push(lbl(728, tunY(i) + TUN_H / 2, t("technical_corridor").toUpperCase(), 8.5, "#647a98")));

  // ===== fermentation tunnels + dehydration halls =====
  for (let i = 0; i < window.N_TUN; i++) {
    const y = tunY(i);
    const meta = window.devById("20TUN" + String(i + 1).padStart(2, "0"));
    const pc = meta.phase === "run" ? MED.digestate : meta.phase === "start" ? MED.heat_s : "#5b6b7d";
    // tunnel body (hatched mass)
    svg.push(h("rect", { key: "tn" + i, x: TUN_X, y, width: TUN_W, height: TUN_H, rx: 3, fill: "rgba(13,31,60,0.6)", stroke: "rgba(122,160,209,0.4)", strokeWidth: 1.4 }));
    svg.push(h("rect", { key: "tnh" + i, x: TUN_X + 3, y: y + 24, width: TUN_W - 6, height: TUN_H - 27, fill: "url(#mass)", opacity: 0.5 }));
    svg.push(lbl(TUN_X + 10, y + 16, t("fermentation_tunnel").toUpperCase() + " TF-0" + (i + 1), 9, "#9db2cc"));
    // door / gate left
    svg.push(h("rect", { key: "tg" + i, x: TUN_X - 8, y: y + 18, width: 8, height: TUN_H - 22, fill: "rgba(122,160,209,0.25)" }));
    // dehydration hall right
    svg.push(room(TUN_X + TUN_W + 14, y, 96, TUN_H, "", { fill: "rgba(13,31,60,0.5)" }));
    svg.push(lbl(TUN_X + TUN_W + 20, y + 14, "DEHYDR.", 7.5, "#8fb4e6"));
    svg.push(bub(TUN_X + TUN_W + 62, y + 60, "LT", MED.percolate));
    // percolate spray feed into tunnel (from left collector)
    svg.push(...pp([[1015, 760], [TUN_X - 30, 760], [TUN_X - 30, y + 8], [TUN_X, y + 8]], MED.percolate, false));
    // biogas extraction riser from tunnel top -> up to bus
    const gx = TUN_X + TUN_W - 40;
    svg.push(...pp([[gx, y], [gx, y - 12], [1380 + i * 14, y - 12], [1380 + i * 14, 76]], MED.biogas, true));
    // digestate out to right
    svg.push(...pp([[TUN_X + TUN_W + 110, y + 70], [1560, y + 70]], pc, false));
  }

  // collector header on right of tunnels (vertical biogas/digestate bus)
  svg.push(...pp([[1560, 240], [1560, 980]], MED.digestate, false));

  // ===== RIGHT SIDE: gas dome, reservoirs, sand traps =====
  // big biogas gas holder dome
  const gFill = D("40LT01").v;
  const gcx = 1880, gbase = 300, gr = 132;
  svg.push(h("clipPath", { key: "gcl", id: "gholderclip" }, h("path", { d: `M ${gcx - gr} ${gbase} A ${gr} ${gr} 0 0 1 ${gcx + gr} ${gbase} Z` })));
  svg.push(h("path", { key: "gdome", d: `M ${gcx - gr} ${gbase} A ${gr} ${gr} 0 0 1 ${gcx + gr} ${gbase} Z`, fill: "rgba(42,157,224,0.1)", stroke: "rgba(122,160,209,0.5)", strokeWidth: 1.6 }));
  svg.push(h("rect", { key: "gfill", x: gcx - gr, y: gbase - (gr) * gFill / 100, width: gr * 2, height: gr * gFill / 100, fill: "#2A9DE0", opacity: 0.28, clipPath: "url(#gholderclip)" }));
  svg.push(h("path", { key: "gdome2", d: `M ${gcx - gr} ${gbase} A ${gr} ${gr} 0 0 1 ${gcx + gr} ${gbase}`, fill: "none", stroke: MED.biogas, strokeWidth: 2, opacity: 0.55 }));
  svg.push(lbl(gcx, gbase - 40, "BIOGAS HOLDER", 11, "#bcdcff", "middle"));
  svg.push(lbl(gcx, gbase - 24, "40-GH-001 · 2 500 m³", 8.5, "#647a98", "middle"));
  // biogas from tunnels bus -> dome inlet (top bus down)
  svg.push(...pp([[1450, 76], [1450, 130], [gcx - gr - 10, 130], [gcx - gr - 10, 250], [gcx - gr, 250]], MED.biogas, true));
  // dome outlet -> down to CHP
  svg.push(...pp([[gcx + gr, 260], [gcx + gr + 30, 260], [gcx + gr + 30, 660], [2120, 660]], MED.biogas, true));

  // sand trap left + right
  svg.push(room(1590, 300, 56, 120, "", { fill: "rgba(13,31,60,0.5)" }));
  svg.push(lbl(1596, 318, "SAND", 7.5, "#8fb4e6")); svg.push(lbl(1596, 328, "TRAP 2", 7.5, "#8fb4e6"));
  svg.push(room(2320, 300, 56, 120, "", { fill: "rgba(13,31,60,0.5)" }));
  svg.push(lbl(2326, 318, "SAND", 7.5, "#8fb4e6")); svg.push(lbl(2326, 328, "TRAP 1", 7.5, "#8fb4e6"));

  // digestate storage + percolate reservoirs PR1/PR2 (tank row)
  const tankRow = [
    { x: 2030, label: "DIGESTATE STORAGE", lvl: 62, col: MED.digestate, tag: "DS-001" },
    { x: 2120, label: "PERCOLATE PR1", lvl: D("30LT01").v, col: MED.percolate, tag: "30-PR-001" },
    { x: 2210, label: "PERCOLATE PR2", lvl: D("30LT02").v, col: MED.percolate, tag: "30-PR-002" },
  ];
  tankRow.forEach((tk, i) => {
    svg.push(h("rect", { key: "tk" + i, x: tk.x, y: 300, width: 78, height: 120, rx: 4, fill: "rgba(13,31,60,0.6)", stroke: "rgba(122,160,209,0.4)", strokeWidth: 1.3 }));
    svg.push(h("rect", { key: "tkl" + i, x: tk.x + 2, y: 300 + 118 - 116 * tk.lvl / 100, width: 74, height: 116 * tk.lvl / 100, fill: tk.col, opacity: 0.3 }));
    svg.push(lbl(tk.x + 39, 294, tk.label, 7, "#8fb4e6", "middle"));
    svg.push(lbl(tk.x + 39, 434, tk.tag, 7, "#647a98", "middle"));
  });
  // sand trap -> reservoir piping
  svg.push(...pp([[1560, 360], [1590, 360]], MED.percolate, false));
  svg.push(...pp([[2376, 360], [2410, 360], [2410, 280], [2249, 280], [2249, 300]], MED.percolate, false));
  // reservoirs -> pumps room
  svg.push(...pp([[2159, 420], [2159, 470]], MED.percolate, true));

  // ===== PUMPS ROOM =====
  svg.push(room(1820, 470, 360, 180, t("pumps_room").toUpperCase()));
  svg.push(bub(1880, 560, "P1", MED.percolate), bub(1930, 560, "P2", MED.percolate), bub(1980, 560, "P3", MED.percolate));
  svg.push(bub(2070, 560, "FT", MED.percolate), bub(2120, 560, "PT", MED.percolate));
  // pumps -> back to PPM banks (percolate recirculation up to top-left)
  svg.push(...pp([[1820, 540], [760, 540], [760, 120], [598, 120], [598, 86]], MED.percolate, true));

  // ===== CHP / cogeneration =====
  svg.push(room(2050, 660, 230, 150, t("chp_room").toUpperCase(), { stroke: "rgba(242,148,31,0.4)" }));
  svg.push(h("rect", { key: "gen", x: 2080, y: 700, width: 120, height: 70, rx: 6, fill: "rgba(19,49,92,0.7)", stroke: "rgba(95,217,154,0.5)" }));
  svg.push(lbl(2090, 740, "50-GG-001 · 600 kWe", 8, "#8fb4e6"));
  svg.push(...pp([[2280, 700], [2360, 700], [2360, 76]], MED.heat_s, true)); // CHP heat to bus
  svg.push(lbl(2300, 690, "→ GRID", 8, "#5fd99a"));

  // ===== BIOFILTER ROOM =====
  svg.push(room(2300, 470, 180, 160, t("biofilter_room").toUpperCase(), { stroke: "rgba(95,180,120,0.4)" }));
  svg.push(h("path", { key: "bfm", d: "M 2315 580 q 14 -12 28 0 q 14 -12 28 0 q 14 -12 28 0 q 14 -12 28 0", stroke: "#5fb478", strokeWidth: 2, fill: "none", opacity: 0.5 }));
  svg.push(lbl(2315, 600, "BED 80-BF-001", 7.5, "#7fc99a"));
  svg.push(bub(2340, 540, "QT", "#5fb478"));
  svg.push(...pp([[2300, 520], [2200, 520], [2200, 76]], "#9aa6b2", false)); // foul air to stack

  // ===== FIRE WATER reserve =====
  svg.push(room(1600, 500, 150, 130, t("fire_storage").toUpperCase(), { stroke: "rgba(211,58,44,0.35)" }));
  svg.push(h("rect", { key: "fw", x: 1630, y: 540, width: 60, height: 70, rx: 4, fill: "rgba(211,58,44,0.1)", stroke: "rgba(211,58,44,0.4)" }));

  // ===== MIXING / FEEDING HALL (bottom centre) =====
  svg.push(room(1380, 1000, 380, 150, t("mixing_hall").toUpperCase()));
  // hoppers
  [1430, 1520, 1610].forEach((hx, i) => {
    svg.push(h("path", { key: "hop" + i, d: `M ${hx} 1040 H ${hx + 60} L ${hx + 45} 1110 H ${hx + 15} Z`, fill: "rgba(122,160,209,0.1)", stroke: "rgba(122,160,209,0.4)", strokeWidth: 1.2 }));
  });
  svg.push(lbl(1700, 1050, "AUGERS →", 8, "#647a98"));
  // feed from mixing hall to tunnels (digestate/substrate)
  svg.push(...pp([[1380, 1075], [1000, 1075], [1000, tunY(6) + 50], [1015, tunY(6) + 50]], MED.digestate, true));

  // ===== Title block (bottom-right) =====
  svg.push(h("rect", { key: "tb", x: 2050, y: 830, width: 430, height: 320, fill: "rgba(8,18,37,0.85)", stroke: "rgba(122,160,209,0.45)", strokeWidth: 1.3 }));
  svg.push(h("line", { key: "tbl1", x1: 2050, y1: 900, x2: 2480, y2: 900, stroke: "rgba(122,160,209,0.3)" }));
  svg.push(h("line", { key: "tbl2", x1: 2050, y1: 1010, x2: 2480, y2: 1010, stroke: "rgba(122,160,209,0.3)" }));
  svg.push(h("line", { key: "tbl3", x1: 2050, y1: 1080, x2: 2480, y2: 1080, stroke: "rgba(122,160,209,0.3)" }));
  svg.push(lbl(2066, 858, "MTM Ekotechnika sp. z o.o.", 12, "#fff"));
  svg.push(lbl(2066, 876, "ul. Koszycka 21, 33-100 Tarnów · Poland", 8.5, "#9db2cc"));
  svg.push(lbl(2066, 926, "Construction of a biodegradable waste digestion", 8.5, "#9db2cc"));
  svg.push(lbl(2066, 940, "plant in a community installation in Bierkowo", 8.5, "#9db2cc"));
  svg.push(lbl(2066, 962, "Bierkowo · SŁUPSK (Pl.)", 9, "#caa05a"));
  svg.push(lbl(2066, 985, "Service design", 8.5, "#647a98"));
  svg.push(lbl(2066, 1042, "P&ID", 18, "#F2941F"));
  svg.push(lbl(2230, 1042, "101-GEN-S-001U", 10, "#9db2cc"));
  svg.push(lbl(2066, 1104, "Rev. 0N", 9, "#647a98"));
  svg.push(lbl(2066, 1124, "DECO · castores", 9, "#647a98"));
  svg.push(lbl(2380, 1104, "Sheet 1 / 1", 9, "#647a98"));

  // ---- representative line numbers on the main runs (real P&ID convention) ----
  const PT = window.pipeTag;
  if (PT) {
    svg.push(PT(820, 748, { dn: 150, od: 214, fl: "P1", num: "L141c", mat: "SS304" }, { color: MED.percolate, mid: true }));
    svg.push(PT(2000, 648, { dn: 250, od: 320, fl: "P2", num: "L240a", mat: "SS304" }, { color: MED.biogas, mid: true }));
    svg.push(PT(860, 188, { dn: 100, fl: "AA", num: "L301a", mat: "SS304" }, { color: MED.air, mid: true }));
    svg.push(PT(560, 738, { dn: 150, od: 250, fl: "WM", num: "L654a", mat: "CS" }, { color: MED.heat_s, mid: true }));
    svg.push(PT(1452, 110, { dn: 300, od: 425, fl: "P2", num: "L210a", mat: "SS304" }, { color: MED.biogas, vert: true }));
  }

  // ---- overlaid live, clickable devices ----
  const overlays = [];
  // per-tunnel gas extraction valve (clickable EV)
  for (let i = 0; i < window.N_TUN; i++) {
    const y = tunY(i);
    overlays.push(<VSym key={"gv" + i} d={D("20GV" + String(i + 1).padStart(2, "0"))} x={TUN_X + TUN_W - 40} y={y - 6} lbl="GAS" />);
    overlays.push(<VSym key={"sv" + i} d={D("20SV" + String(i + 1).padStart(2, "0"))} x={TUN_X - 30} y={y + 8} lbl="H₂O" />);
    overlays.push(<ISym key={"tt" + i} d={D("20TT" + String(i + 1).padStart(2, "0"))} x={TUN_X + 60} y={y + 62} />);
  }
  // gas dome inlet/outlet + analysers + flare
  overlays.push(<VSym key="g1" d={D("40EV01")} x={gcx - gr} y={250} lbl="IN" />);
  overlays.push(<VSym key="g2" d={D("40EV02")} x={gcx + gr} y={260} lbl="OUT" />);
  overlays.push(<VSym key="g3" d={D("40EV03")} x={gcx} y={gbase - 150} lbl="FLR" />);
  overlays.push(<ISym key="gl" d={D("40LT01")} x={gcx} y={gbase + 24} />);
  overlays.push(<ISym key="gp" d={D("40PT01")} x={gcx + 60} y={gbase + 24} />);
  overlays.push(<ISym key="a1" d={D("40AT01")} x={gcx - 90} y={gbase + 24} />);
  overlays.push(<ISym key="a3" d={D("40AT03")} x={gcx - 30} y={gbase + 24} />);
  // reservoirs levels
  overlays.push(<ISym key="r1" d={D("30LT01")} x={2159} y={300} showVal={false} />);
  overlays.push(<ISym key="r2" d={D("30LT02")} x={2249} y={300} showVal={false} />);
  // pumps
  overlays.push(<MSym key="pp1" d={D("30MP01")} x={1880} y={560} />);
  overlays.push(<MSym key="pp2" d={D("30MP02")} x={1930} y={560} />);
  // CHP genset
  overlays.push(<MSym key="chp" d={D("50GG01")} x={2140} y={735} glyph="G" />);
  // biofilter fans
  overlays.push(<MSym key="bf1" d={D("80MF01")} x={2390} y={540} />);
  // compressors
  overlays.push(<MSym key="ac1" d={D("70MC01")} x={150} y={600} />);
  overlays.push(<MSym key="ac2" d={D("70MC02")} x={210} y={600} />);
  overlays.push(<ISym key="ap" d={D("70PT01")} x={300} y={560} />);

  const legendItems = [
    ["m_biogas", MED.biogas], ["m_percolate", MED.percolate], ["m_air", MED.air],
    ["m_heat_s", MED.heat_s], ["m_heat_r", MED.heat_r], ["m_water", MED.water], ["m_digestate", MED.digestate],
  ];

  return (
    <div className="page" style={{ padding: 0, display: "flex", flexDirection: "column", overflow: "hidden" }}>
      <div style={{ padding: "16px 22px 10px" }}>
        <PageHead titleKey="nav_pid_gen" sub={t("pid_sub")} tag="101-GEN-S-001U · Rev 0N" />
      </div>
      {/* toolbar: zoom + line legend */}
      <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "0 22px 12px", flexWrap: "wrap" }}>
        <div className="modetog">
          {[["50%", 0.5], ["75%", 0.75], ["100%", 1], [t("zoom_fit"), 0.6]].map(([l, z]) => (
            <button key={l} className={Math.abs(zoom - z) < 0.001 ? "on auto" : ""} onClick={() => pz.preset(z)}>{l}</button>
          ))}
        </div>
        <span className="mono" style={{ fontSize: 10, color: "var(--hud-text-3)", whiteSpace: "nowrap" }}>{t("cad_hint")}</span>
        <div style={{ width: 1, height: 22, background: "var(--hud-line)" }}></div>
        <span className="eyebrow">{t("key_lines")}</span>
        <div className="legend">
          {legendItems.map(([k, c]) => (
            <span className="lg" key={k}><span style={{ width: 18, height: 0, borderTop: "2.5px solid " + c, display: "inline-block" }}></span>{t(k)}</span>
          ))}
        </div>
      </div>
      {/* scrollable schematic */}
      <div {...pz.bind} style={{ ...pz.bind.style, flex: 1, position: "relative", overflow: "hidden", background: "#04101f", borderTop: "1px solid var(--hud-line)" }}>
        <div style={{ position: "absolute", left: 0, top: 0, width: W, height: Ht, transformOrigin: "0 0", transform: `translate(${pz.pan.x}px, ${pz.pan.y}px) scale(${zoom})` }}>
          <svg width={W} height={Ht} style={{ position: "absolute", inset: 0 }}>
            <defs>
              <pattern id="pidgrid" width="40" height="40" patternUnits="userSpaceOnUse"><path d="M40 0H0V40" fill="none" stroke="rgba(122,160,209,0.045)" strokeWidth="1" /></pattern>
              <pattern id="mass" width="7" height="7" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="7" stroke="rgba(160,140,110,0.45)" strokeWidth="1.4" /></pattern>
            </defs>
            {svg}
          </svg>
          {overlays}
        </div>
      </div>
    </div>
  );
}

window.PAGES.pid = PIDPage;
