/* 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 ; } 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 ( {children} ); } /* A hairline panel with a mono caption — the recurring container inside figures. */ function Panel({ x, y, w, h, label, children, tone }) { return ( {label && {label}} {children} ); } /* ── 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 ; if (kind === "human") return ; if (kind === "tool") return ; if (kind === "exit") return ; return ; }; return ( {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 ( {glyph(kind, y)} {name} {detail} 5000 ? AMB : QUIET} style={MONO(9)}>{ms > 5000 ? (ms / 1000).toFixed(1) + "s" : ms + "ms"} ); })} {[["elapsed", "42.0s"], ["billable", "800ms"], ["tokens", "5.7k"], ["cost", "$0.041"]].slice(0, mobile ? 3 : 4).map((r, i) => ( {r[0]} {r[1]} ))} {!mobile && ( {["erp: read + post", "po table: read", "mailbox: read"].map((t, i) => ( {t} ))} )} below 0.85 clerk review, page attached ); } /* ── 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 ( {fields.map((f, i) => ( ))} page 1 of 2 {fields.map((f, i) => { const y = 30 + i * rowH; const bad = f[2] < 0.9; return ( {f[0]} {f[1]} {f[2].toFixed(2)} {bad && held for review} ); })} {!mobile && ( {[["formats", "9 families"], ["pages/min", "42"], ["auto-posted", "94%"]].map((r, i) => ( {r[0]} {r[1]} ))} )} ); } /* ── 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 ( {ticks.map((t) => ( {Math.round(180 + t * 120)} ))} MW {!mobile && act.filter((_, i) => i % 6 === 0).map((q, i) => )} now 287 MW ±14 {(mobile ? ["jan", "apr", "jul"] : ["jun 25", "sep", "dec", "mar 26", "jun"]).map((m, i, arr) => ( {m} ))} {!mobile && ( residual, back-test {Array.from({ length: 30 }).map((_, i) => { const r = Math.sin(i / 2.2) * 6 + Math.sin(i / 5) * 3; return 0 ? plotB + 40 - r : plotB + 40} width="4" height={Math.abs(r)} fill={Math.abs(r) > 7 ? AMB : FLD} opacity="0.75" />; })} mape 4.1% · holdout, not fitted drift check: weekly )} ); } /* ── 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 ( {[1, 2, 3].map((i) => )} {[1, 2].map((i) => )} cam-08 · line 3 · 0.6 m/s {Array.from({ length: 9 }).map((_, i) => )} {items.map(([n, col, conf, label]) => ( {conf} {label} ))} {!mobile && ( {stages.map((s, i) => ( {s[0]} {s[1]}ms · resolves {s[3]} ))} )} {[["items / min", "112"], ["contested", "1.4%"], ["on edge", "no uplink"], ["labels added", "18 / shift"]].slice(0, mobile ? 2 : 4).map((r, i) => ( {r[0]} {r[1]} ))} ); } /* ── 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 ( {Array.from({ length: devs }).map((_, i) => { const y = dTop + i * dGap; return ( esp32-{110 + i} {[0, 1, 2].map((b) => )} {[40, 62, 55, 48][i]} msg/day ); })} queue {[0, 1, 2, 3].map((k) => )} 412 held historian ordered, idempotent 0 rows lost {!mobile && ( ota rollout · staged {[["10%", FLD, 0], ["50%", FLD, 1], ["100%", LINE2, 2]].map(([l, c, i]) => ( {l} ))} rule chain fires on device state, not on a dashboard refresh )} ); } Object.assign(window, { Fig, Panel, MONO, Head, FigAgents, FigDocs, FigForecast, FigVision, FigEdge, PF_C: { A, FLD, SIG, AMB, LINE, LINE2, QUIET, INK, BODY } });