/* Practice figures, part one — intelligence practices.
   Each figure is a working instrument panel: real step names, per-item scores,
   running totals, scales and units. CSS keyframes only (no JS timers, no
   re-renders); every animation has a complete static state under reduced-motion.
   Mobile drops secondary panels and rows rather than shrinking the type. */
const { ChartFrame: XCF } = window.SoftVerxDesignSystem_6fd95b;

const MONO = (s, w) => ({ font: `${w || 500} ${s}px var(--font-mono)`, letterSpacing: 0 });

/* Arrowheads are drawn, never typed. A glyph arrow inherits the text face's
   weight and terminals and sits on the baseline instead of on the line it
   belongs to; a two-stroke chevron matches the 1.75 hairline language the rest
   of the drawings use. `dir` is one of "e" | "s" | "n" | "w". */
function Head({ x, y, dir = "e", tone, size = 3.4 }) {
  const d = {
    e: `M${x - size} ${y - size} L${x} ${y} L${x - size} ${y + size}`,
    w: `M${x + size} ${y - size} L${x} ${y} L${x + size} ${y + size}`,
    s: `M${x - size} ${y - size} L${x} ${y} L${x + size} ${y - size}`,
    n: `M${x - size} ${y + size} L${x} ${y} L${x + size} ${y + size}`,
  }[dir];
  return <path d={d} fill="none" stroke={tone} strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round" />;
}
const A = "var(--sx-accent)", FLD = "var(--sx-field)", SIG = "var(--sx-signal)", AMB = "var(--sx-amber)";
const LINE = "var(--border-default)", LINE2 = "var(--border-strong)";
const QUIET = "var(--text-quiet)", INK = "var(--text-strong)", BODY = "var(--text-body)";

function Fig({ title, subtitle, note, children, h, legend }) {
  return (
    <XCF title={title} subtitle={subtitle} sample note={note} legend={legend}>
      <svg viewBox={`0 0 400 ${h}`} width="100%" height={h} role="img" aria-label={title} style={{ display: "block", overflow: "visible" }}>{children}</svg>
    </XCF>
  );
}
/* A hairline panel with a mono caption — the recurring container inside figures. */
function Panel({ x, y, w, h, label, children, tone }) {
  return (
    <g>
      <rect x={x} y={y} width={w} height={h} rx="3" fill="var(--surface-card)" stroke={tone || LINE} />
      {label && <text x={x + 8} y={y + 13} fill={QUIET} style={MONO(8)}>{label}</text>}
      {children}
    </g>
  );
}

/* ── AI agents ─────────────────────────────────────────────────────────────
   The trace, with what each step cost. Node shape carries the step kind, the
   human wait is hatched and labelled compressed, and the totals accumulate. */
function FigAgents({ mobile }) {
  const steps = mobile
    ? [["classify_doc", "layout + language", "tool", 120, 1.2], ["extract_fields", "22 fields, per-field conf", "tool", 260, 3.4], ["match_po", "3-way", "tool", 180, 0.9], ["threshold", "0.91 vs 0.85", "branch", 40, 0], ["post_to_erp", "journal written", "exit", 110, 0.2]]
    : [["read_channel", "invoices@ mailbox", "event", 90, 0], ["classify_doc", "layout + language", "tool", 120, 1.2], ["extract_fields", "22 fields, per-field conf", "tool", 260, 3.4], ["match_po", "po · grn · invoice", "tool", 180, 0.9], ["threshold_check", "0.91 vs 0.85 gate", "branch", 40, 0], ["clerk_review", "only below gate", "human", 41200, 0], ["post_to_erp", "journal + audit line", "exit", 110, 0.2]];
  const top = 30, gap = 30, railH = (steps.length - 1) * gap;
  const h = top + railH + (mobile ? 58 : 74);
  const px = mobile ? 214 : 236, pw = 400 - px;
  const glyph = (kind, y) => {
    if (kind === "branch") return <path d={`M22 ${y - 5} l5 5 l-5 5 l-5 -5 z`} fill="none" stroke={AMB} strokeWidth="1.3" />;
    if (kind === "human") return <rect x="17" y={y - 5} width="10" height="10" fill="url(#pf-hatch)" stroke={AMB} strokeWidth="1" />;
    if (kind === "tool") return <rect x="18" y={y - 4} width="8" height="8" rx="1" fill={A} />;
    if (kind === "exit") return <circle cx="22" cy={y} r="4.5" fill="none" stroke={FLD} strokeWidth="1.6" />;
    return <circle cx="22" cy={y} r="3.5" fill={QUIET} />;
  };
  return (
    <Fig h={h} title="Agent trace" subtitle="one invoice, seven steps, one human decision"
      note="Representative trace at representative magnitudes. The 41.2s human wait is drawn hatched and labelled as compressed while the readout keeps true elapsed time."
      legend={[{ label: "tool call", color: A }, { label: "gate", color: AMB }, { label: "posted", color: FLD }]}>
      <defs>
        <pattern id="pf-hatch" width="4" height="4" patternTransform="rotate(45)" patternUnits="userSpaceOnUse">
          <line x1="0" y1="0" x2="0" y2="4" stroke={AMB} strokeWidth="1" opacity="0.55" />
        </pattern>
      </defs>
      <line x1="22" y1={top} x2="22" y2={top + railH} stroke={LINE2} strokeWidth="1" />
      {steps.map(([name, detail, kind, ms, tok], i) => {
        const y = top + i * gap;
        const w = Math.min(1, ms > 5000 ? 1 : ms / 300) * (mobile ? 46 : 58);
        return (
          <g key={name} className="pf-step" style={{ animationDelay: `${i * 0.42}s` }}>
            {glyph(kind, y)}
            <text x="36" y={y - 1} fill={INK} style={MONO(10)}>{name}</text>
            <text x="36" y={y + 10} fill={QUIET} style={MONO(8)}>{detail}</text>
            <rect x={px - (mobile ? 54 : 66)} y={y - 4} width={w} height="8" rx="1.5" fill={kind === "human" ? "url(#pf-hatch)" : A} opacity={kind === "human" ? 1 : 0.4} />
            <text x={px - 4} y={y + 3} textAnchor="end" fill={ms > 5000 ? AMB : QUIET} style={MONO(9)}>{ms > 5000 ? (ms / 1000).toFixed(1) + "s" : ms + "ms"}</text>
          </g>
        );
      })}
      <circle cx="22" cy={top} r="8" fill="none" stroke={A} strokeWidth="1.2" className="pf-playhead" style={{ "--y0": "0px", "--y1": `${railH}px` }} />

      <Panel x={px} y={top - 12} w={pw} h={mobile ? 82 : 102} label="run totals">
        {[["elapsed", "42.0s"], ["billable", "800ms"], ["tokens", "5.7k"], ["cost", "$0.041"]].slice(0, mobile ? 3 : 4).map((r, i) => (
          <g key={r[0]} className="pf-field" style={{ animationDelay: `${1 + i * 0.3}s` }}>
            <text x={px + 8} y={top + 22 + i * 19} fill={QUIET} style={MONO(8)}>{r[0]}</text>
            <text x={392} y={top + 22 + i * 19} textAnchor="end" fill={INK} style={MONO(10)}>{r[1]}</text>
          </g>
        ))}
      </Panel>
      {!mobile && (
        <Panel x={px} y={top + 108} w={pw} h={railH - 92} label="tool boundary">
          {["erp: read + post", "po table: read", "mailbox: read"].map((t, i) => (
            <text key={t} x={px + 8} y={top + 136 + i * 14} fill={BODY} style={MONO(8)}>{t}</text>
          ))}
        </Panel>
      )}
      <g className="pf-step" style={{ animationDelay: `${steps.length * 0.42}s` }}>
        <path d={`M22 ${top + railH + 12} v14 h24`} fill="none" stroke={AMB} strokeWidth="1" strokeDasharray="3 3" />
        <Head x={50} y={top + railH + 26} tone={AMB} />
        <rect x="56" y={top + railH + 15} width={mobile ? 152 : 190} height="23" rx="3" fill="var(--surface-card)" stroke={AMB} strokeOpacity="0.45" />
        <text x="63" y={top + railH + 24} fill={AMB} style={MONO(8)}>below 0.85</text>
        <text x="63" y={top + railH + 34} fill={QUIET} style={MONO(8)}>clerk review, page attached</text>
      </g>
    </Fig>
  );
}

/* ── Document intelligence ────────────────────────────────────────────────
   The page, the regions read from it, and the confidence behind each field. */
function FigDocs({ mobile }) {
  const fields = mobile
    ? [["account_no", "8841-27", 0.99], ["period_end", "31 may 26", 0.97], ["total_due", "1,284.60", 0.71]]
    : [["supplier", "Northgate Energy", 0.99], ["account_no", "8841-27", 0.98], ["period_end", "31 may 2026", 0.96], ["kwh_used", "4,120", 0.94], ["total_due", "1,284.60", 0.71]];
  const rowH = mobile ? 32 : 30, pad = 12;
  const h = 26 + fields.length * rowH + (mobile ? 34 : 52);
  const pw = mobile ? 112 : 132, ph = h - 34;
  const regY = (i) => 44 + i * ((ph - 54) / fields.length);
  const cx = pw + 22, cw = 400 - cx;
  return (
    <Fig h={h} title="Page to record" subtitle="utility bill from an unfamiliar retailer"
      note="Representative page and an illustrative confidence distribution. A field below the gate is handed to a person with the pixels it was read from — never a bare number."
      legend={[{ label: "accepted", color: FLD }, { label: "below gate 0.90", color: AMB }]}>
      <rect x="6" y="10" width={pw} height={ph} rx="3" fill="var(--surface-card)" stroke={LINE} />
      <rect x="14" y="18" width={pw * 0.42} height="10" rx="1.5" fill={LINE2} />
      <rect x={6 + pw - 14 - pw * 0.3} y="18" width={pw * 0.3} height="6" rx="1.5" fill={LINE2} opacity="0.6" />
      {fields.map((f, i) => (
        <g key={f[0]}>
          <rect x="18" y={regY(i)} width={pw * 0.32} height="4" rx="1.5" fill={LINE2} opacity="0.55" />
          <rect className="pf-region" style={{ animationDelay: `${i * 0.9}s` }} x={pw * 0.42} y={regY(i) - 5} width={pw * 0.48} height="14" fill="none" stroke={f[2] < 0.9 ? AMB : FLD} strokeWidth="1.2" />
        </g>
      ))}
      <line x1="14" y1={ph - 4} x2={pw - 2} y2={ph - 4} stroke={LINE2} />
      <text x="14" y={ph + 6} fill={QUIET} style={MONO(7)}>page 1 of 2</text>

      {fields.map((f, i) => {
        const y = 30 + i * rowH;
        const bad = f[2] < 0.9;
        return (
          <g key={f[0]} className="pf-field" style={{ animationDelay: `${i * 0.9 + 0.3}s` }}>
            <path d={`M${pw + 6} ${regY(i) + 2} C${pw + 14} ${regY(i) + 2} ${cx - 8} ${y + 2} ${cx} ${y + 2}`} fill="none" stroke={bad ? AMB : FLD} strokeWidth="0.8" strokeDasharray="2 2" opacity="0.7" />
            <text x={cx + 4} y={y} fill={QUIET} style={MONO(8)}>{f[0]}</text>
            <text x={cx + 4} y={y + 13} fill={bad ? AMB : INK} style={MONO(mobile ? 10 : 11)}>{f[1]}</text>
            <rect x={cx + cw - 62} y={y - 6} width="40" height="4" rx="2" fill={LINE2} />
            <rect x={cx + cw - 62} y={y - 6} width={40 * f[2]} height="4" rx="2" fill={bad ? AMB : FLD} />
            <text x={cx + cw - 16} y={y - 2} textAnchor="end" fill={bad ? AMB : QUIET} style={MONO(8)}>{f[2].toFixed(2)}</text>
            {bad && <text x={cx + cw - 16} y={y + 12} textAnchor="end" fill={AMB} style={MONO(8)}>held for review</text>}
          </g>
        );
      })}
      {!mobile && (
        <g className="pf-field" style={{ animationDelay: "2.2s" }}>
          <line x1={cx} y1={h - 30} x2="392" y2={h - 30} stroke={LINE} />
          {[["formats", "9 families"], ["pages/min", "42"], ["auto-posted", "94%"]].map((r, i) => (
            <g key={r[0]}>
              <text x={cx + 4 + i * 90} y={h - 17} fill={QUIET} style={MONO(8)}>{r[0]}</text>
              <text x={cx + 4 + i * 90} y={h - 5} fill={INK} style={MONO(10)}>{r[1]}</text>
            </g>
          ))}
        </g>
      )}
    </Fig>
  );
}

/* ── Applied ML ───────────────────────────────────────────────────────────
   Series, forecast, band — with the residuals and the error figure that
   justify them, because a forecast without its back-test is a slide. */
function FigForecast({ mobile }) {
  const h = mobile ? 196 : 244, w = 400;
  const plotB = h - (mobile ? 52 : 66), plotT = 26, split = 246, x0 = 30, x1 = w - 8;
  const n = 44;
  const val = (i) => 0.52 + Math.sin(i / 3.6) * 0.18 + Math.sin(i / 9.4) * 0.2 + (i / n) * 0.08;
  const X = (i) => x0 + (i / n) * (split - x0);
  const Y = (v) => plotB - v * (plotB - plotT);
  const act = Array.from({ length: n + 1 }, (_, i) => [X(i), Y(val(i))]);
  const fcN = 18;
  const fx = (i) => split + (i / fcN) * (x1 - split);
  const fc = Array.from({ length: fcN + 1 }, (_, i) => [fx(i), Y(val(n + i) + 0.01 * i)]);
  const p = (a) => a.map((q, i) => (i ? "L" : "M") + q[0].toFixed(1) + " " + q[1].toFixed(1)).join(" ");
  const band = p(fc.map((q, i) => [q[0], q[1] - 5 - i * 1.1])) + " " + fc.slice().reverse().map((q, i) => `L${q[0].toFixed(1)} ${(q[1] + 5 + (fc.length - i) * 1.1).toFixed(1)}`).join(" ") + " Z";
  const ticks = [0, 0.25, 0.5, 0.75, 1];
  return (
    <Fig h={h} title="Load forecast, with its error report" subtitle="feeder 11 · trailing 12 months, 6 weeks ahead"
      note="Illustrative shape at representative magnitudes. Every model ships with the back-test that produced its error figure, and drift is monitored after go-live."
      legend={[{ label: "actual", color: A }, { label: "forecast", color: SIG, dashed: true }, { label: "80% band", color: "var(--sx-band)", swatch: true }]}>
      {ticks.map((t) => (
        <g key={t}>
          <line x1={x0} y1={Y(t)} x2={x1} y2={Y(t)} stroke={LINE} strokeWidth="0.6" />
          <text x={x0 - 5} y={Y(t) + 3} textAnchor="end" fill={QUIET} style={MONO(7)}>{Math.round(180 + t * 120)}</text>
        </g>
      ))}
      <text x="4" y={plotT - 12} fill={QUIET} style={MONO(7)}>MW</text>
      <path className="pf-band" d={band} fill="var(--sx-band)" />
      <path className="pf-draw-a" d={p(act)} fill="none" stroke={A} strokeWidth="1.6" strokeLinejoin="round" />
      <path className="pf-draw-b" d={p(fc)} fill="none" stroke={SIG} strokeWidth="1.6" strokeDasharray="4 3" strokeLinejoin="round" />
      {!mobile && act.filter((_, i) => i % 6 === 0).map((q, i) => <circle key={i} className="pf-tip" style={{ animationDelay: `${i * 0.12}s` }} cx={q[0]} cy={q[1]} r="1.8" fill={A} />)}
      <line x1={split} y1={plotT - 6} x2={split} y2={plotB} stroke={LINE2} strokeDasharray="2 3" />
      <text x={split + 4} y={plotT - 8} fill={QUIET} style={MONO(8)}>now</text>
      <circle className="pf-tip" cx={fc[fcN][0]} cy={fc[fcN][1]} r="3" fill={SIG} />
      <text x={x1} y={fc[fcN][1] - 8} textAnchor="end" fill={SIG} style={MONO(8)}>287 MW ±14</text>

      <line x1={x0} y1={plotB} x2={x1} y2={plotB} stroke={LINE2} />
      {(mobile ? ["jan", "apr", "jul"] : ["jun 25", "sep", "dec", "mar 26", "jun"]).map((m, i, arr) => (
        <text key={m} x={x0 + (i / (arr.length - 1)) * (split - x0)} y={plotB + 12} textAnchor="middle" fill={QUIET} style={MONO(7)}>{m}</text>
      ))}
      {!mobile && (
        <g className="pf-field" style={{ animationDelay: "1.6s" }}>
          <text x={x0} y={plotB + 30} fill={QUIET} style={MONO(7)}>residual, back-test</text>
          {Array.from({ length: 30 }).map((_, i) => {
            const r = Math.sin(i / 2.2) * 6 + Math.sin(i / 5) * 3;
            return <rect key={i} x={x0 + i * 7} y={r > 0 ? plotB + 40 - r : plotB + 40} width="4" height={Math.abs(r)} fill={Math.abs(r) > 7 ? AMB : FLD} opacity="0.75" />;
          })}
          <line x1={x0} y1={plotB + 40} x2={x0 + 210} y2={plotB + 40} stroke={LINE2} strokeWidth="0.7" />
          <text x={x1} y={plotB + 30} textAnchor="end" fill={QUIET} style={MONO(8)}>mape 4.1% · holdout, not fitted</text>
          <text x={x1} y={plotB + 44} textAnchor="end" fill={FLD} style={MONO(8)}>drift check: weekly</text>
        </g>
      )}
    </Fig>
  );
}

/* ── Computer vision ──────────────────────────────────────────────────────
   The frame, the cascade that resolved each item, and what it cost to run. */
function FigVision({ mobile }) {
  const h = mobile ? 190 : 244, fy = 22, fh = mobile ? 108 : 132, fw = mobile ? 392 : 258;
  const items = mobile ? [[0, FLD, "0.96", "crispy-330"], [1, AMB, "0.71", "contested"]] : [[0, FLD, "0.96", "crispy-330"], [1, AMB, "0.71", "contested"], [2, FLD, "0.93", "pet-clear"]];
  const stages = [["barcode", 45, FLD, "62%"], ["ocr + similarity", 260, FLD, "24%"], ["vision-language", 1180, SIG, "12%"], ["operator", 9000, AMB, "2%"]];
  return (
    <Fig h={h} title="Four stages, then a person" subtitle="one item on a moving belt, resolved as cheaply as it can be"
      note="Illustrative frame. Cheap stages answer most items; the expensive model is only asked when they cannot, and a contested item is never guessed."
      legend={[{ label: "resolved", color: FLD }, { label: "contested", color: AMB }]}>
      <rect x="4" y={fy} width={fw} height={fh} rx="3" fill="var(--surface-card)" stroke={LINE} />
      {[1, 2, 3].map((i) => <line key={"v" + i} x1={4 + (fw / 4) * i} y1={fy} x2={4 + (fw / 4) * i} y2={fy + fh} stroke={LINE} strokeWidth="0.5" opacity="0.6" />)}
      {[1, 2].map((i) => <line key={"h" + i} x1="4" y1={fy + (fh / 3) * i} x2={4 + fw} y2={fy + (fh / 3) * i} stroke={LINE} strokeWidth="0.5" opacity="0.6" />)}
      <text x="10" y={fy + 11} fill={QUIET} style={MONO(7)}>cam-08 · line 3 · 0.6 m/s</text>
      <line x1="4" y1={fy + fh - 16} x2={4 + fw} y2={fy + fh - 16} stroke={LINE2} />
      {Array.from({ length: 9 }).map((_, i) => <line key={i} className="pf-belt" style={{ animationDelay: `${i * 0.14}s` }} x1={20 + i * 30} y1={fy + fh - 16} x2={12 + i * 30} y2={fy + fh - 4} stroke={LINE2} strokeWidth="1" opacity="0.5" />)}
      <clipPath id="pf-frame"><rect x="4" y={fy} width={fw} height={fh} rx="3" /></clipPath>
      <g clipPath="url(#pf-frame)">
        {items.map(([n, col, conf, label]) => (
          <g key={n} className="pf-item" style={{ animationDelay: `${n * 2.1}s` }}>
            <rect x="-46" y={fy + fh - 56} width="38" height="38" rx="3" fill="var(--surface-raised)" stroke={LINE2} />
            <rect x="-40" y={fy + fh - 50} width="26" height="8" rx="1" fill={LINE2} opacity="0.8" />
            <g className="pf-box" style={{ animationDelay: `${n * 2.1 + 0.8}s` }}>
              <rect x="-50" y={fy + fh - 60} width="46" height="46" fill="none" stroke={col} strokeWidth="1.4" />
              <rect x="-50" y={fy + fh - 73} width="46" height="12" fill={col} />
              <text x="-27" y={fy + fh - 64} textAnchor="middle" fill="#04060d" style={MONO(7, 600)}>{conf}</text>
              <text x="-50" y={fy + fh - 78} fill={col} style={MONO(7)}>{label}</text>
            </g>
          </g>
        ))}
      </g>

      {!mobile && (
        <Panel x={fw + 12} y={fy} w={400 - fw - 16} h={fh} label="cascade">
          {stages.map((s, i) => (
            <g key={s[0]} className="pf-field" style={{ animationDelay: `${i * 0.5}s` }}>
              <rect x={fw + 20} y={fy + 22 + i * 26} width="3" height="16" fill={s[2]} />
              <text x={fw + 28} y={fy + 30 + i * 26} fill={INK} style={MONO(8)}>{s[0]}</text>
              <text x={fw + 28} y={fy + 40 + i * 26} fill={QUIET} style={MONO(7)}>{s[1]}ms · resolves {s[3]}</text>
            </g>
          ))}
        </Panel>
      )}
      <g className="pf-field" style={{ animationDelay: "1.4s" }}>
        <line x1="4" y1={fy + fh + 18} x2="396" y2={fy + fh + 18} stroke={LINE} />
        {[["items / min", "112"], ["contested", "1.4%"], ["on edge", "no uplink"], ["labels added", "18 / shift"]].slice(0, mobile ? 2 : 4).map((r, i) => (
          <g key={r[0]}>
            <text x={8 + i * 100} y={fy + fh + 32} fill={QUIET} style={MONO(8)}>{r[0]}</text>
            <text x={8 + i * 100} y={fy + fh + 45} fill={INK} style={MONO(10)}>{r[1]}</text>
          </g>
        ))}
      </g>
    </Fig>
  );
}

/* ── Industrial IoT & edge ────────────────────────────────────────────────
   Devices, the link that fails, the queue that saves the data, and the OTA
   rollout running underneath it all. */
function FigEdge({ mobile }) {
  const devs = mobile ? 3 : 4;
  const dTop = 26, dGap = 30, h = dTop + devs * dGap + (mobile ? 56 : 92);
  const gx = 268, gy = dTop + (devs * dGap) / 2 - 30;
  return (
    <Fig h={h} title="When the link drops" subtitle="edge capture, store-and-forward, ordered flush"
      note="The controller holds its schedule locally. Nothing is lost while the network is down, and the backlog forwards in order on reconnect — the failure mode is designed, not discovered."
      legend={[{ label: "telemetry", color: A }, { label: "link lost", color: AMB }]}>
      {Array.from({ length: devs }).map((_, i) => {
        const y = dTop + i * dGap;
        return (
          <g key={i}>
            <rect x="4" y={y - 10} width="76" height="21" rx="3" fill="var(--surface-raised)" stroke={LINE2} />
            <text x="10" y={y + 4} fill={BODY} style={MONO(8)}>esp32-{110 + i}</text>
            {[0, 1, 2].map((b) => <rect key={b} x={62 + b * 5} y={y - 1 - b * 2.5} width="3" height={4 + b * 2.5} fill={b < 2 || i !== 1 ? FLD : LINE2} />)}
            <path d={`M80 ${y} H150 Q168 ${y} 168 ${gy + 30}`} fill="none" stroke={LINE} strokeWidth="1" />
            <circle className="pf-packet" style={{ animationDelay: `${i * 0.5}s` }} cx="82" cy={y} r="2.4" fill={A} />
            <text x="86" y={y - 4} fill={QUIET} style={MONO(7)}>{[40, 62, 55, 48][i]} msg/day</text>
          </g>
        );
      })}
      <path d={`M168 ${gy + 30} H${gx}`} stroke={LINE2} strokeWidth="1" fill="none" />
      <path className="pf-link-down" d={`M168 ${gy + 30} H${gx}`} stroke={AMB} strokeWidth="1.6" strokeDasharray="4 4" fill="none" />
      <g className="pf-buffer">
        <rect x="178" y={gy + 8} width="46" height="40" rx="3" fill="none" stroke={AMB} />
        <text x="201" y={gy + 20} textAnchor="middle" fill={AMB} style={MONO(7)}>queue</text>
        {[0, 1, 2, 3].map((k) => <rect key={k} x={184 + k * 10} y={gy + 40 - k * 4} width="7" height={4 + k * 4} fill={AMB} opacity="0.6" />)}
        <text x="201" y={gy + 58} textAnchor="middle" fill={AMB} style={MONO(7)}>412 held</text>
      </g>
      <Panel x={gx} y={gy} w={400 - gx - 4} h="62" label="gateway" tone={A}>
        <text x={gx + 8} y={gy + 30} fill={INK} style={MONO(10)}>historian</text>
        <text x={gx + 8} y={gy + 43} fill={QUIET} style={MONO(7)}>ordered, idempotent</text>
        <text x={gx + 8} y={gy + 55} fill={FLD} style={MONO(7)}>0 rows lost</text>
      </Panel>
      {!mobile && (
        <g className="pf-field" style={{ animationDelay: "1.2s" }}>
          <line x1="4" y1={h - 44} x2="396" y2={h - 44} stroke={LINE} />
          <text x="4" y={h - 30} fill={QUIET} style={MONO(8)}>ota rollout · staged</text>
          {[["10%", FLD, 0], ["50%", FLD, 1], ["100%", LINE2, 2]].map(([l, c, i]) => (
            <g key={l}>
              <rect x={130 + i * 82} y={h - 40} width="70" height="10" rx="2" fill="none" stroke={c} />
              <rect x={130 + i * 82} y={h - 40} width={i === 2 ? 24 : 70} height="10" rx="2" fill={c} opacity="0.35" />
              <text x={165 + i * 82} y={h - 32} textAnchor="middle" fill={i === 2 ? QUIET : INK} style={MONO(7)}>{l}</text>
            </g>
          ))}
          <text x="4" y={h - 12} fill={QUIET} style={MONO(8)}>rule chain fires on device state, not on a dashboard refresh</text>
        </g>
      )}
    </Fig>
  );
}

Object.assign(window, { Fig, Panel, MONO, Head, FigAgents, FigDocs, FigForecast, FigVision, FigEdge, PF_C: { A, FLD, SIG, AMB, LINE, LINE2, QUIET, INK, BODY } });
