OptimismBench / app /src /content /embeds /inverted-pair.html
seonglae's picture
OptimismBench interactive article (agentroom-based, no forced 3D)
389b51b
Raw
History Blame Contribute Delete
4.34 kB
<div id="ob-ip" role="group" aria-label="Interactive inverted-pair calculator. Adjust the model's probability of success and of failure; the Skew is the gap between them.">
<div class="ip-grid">
<div>
<div class="ip-q">"Probability of <b style="color:var(--opt,#e07a5f)">success</b>?"</div>
<input id="ip-pos" class="ip-range" type="range" min="0" max="100" value="70">
<div class="ip-val" style="color:var(--opt,#e07a5f)">P⁺ = <span id="ip-posv">70</span></div>
</div>
<div>
<div class="ip-q">"Probability of <b style="color:var(--pes,#3d5a80)">failure</b>?"</div>
<input id="ip-neg" class="ip-range" type="range" min="0" max="100" value="15">
<div class="ip-val" style="color:var(--pes,#3d5a80)">P⁻ = <span id="ip-negv">15</span></div>
</div>
</div>
<svg id="ip-svg" width="100%" height="84"></svg>
<div id="ip-out" class="ip-out"></div>
</div>
<style>
#ob-ip { font: 13px/1.45 system-ui, -apple-system, sans-serif; color: var(--text-color,#222); width:100%; max-width:560px; margin:0 auto; }
#ob-ip .ip-grid { display:grid; grid-template-columns:1fr 1fr; gap:20px; margin-bottom:6px; }
#ob-ip .ip-q { font-size:12.5px; color:var(--muted-color,#666); margin-bottom:6px; }
#ob-ip .ip-range { width:100%; }
#ob-ip #ip-pos { accent-color: var(--opt,#e07a5f); }
#ob-ip #ip-neg { accent-color: var(--pes,#3d5a80); }
#ob-ip .ip-val { font-size:21px; font-weight:700; margin-top:2px; }
#ob-ip .ip-out { text-align:center; font-size:14.5px; margin-top:4px; }
</style>
<script>
(function () {
var root = document.getElementById("ob-ip");
if (!root || !window.d3) { return; }
var d3 = window.d3, svg = d3.select("#ip-svg");
var pos = document.getElementById("ip-pos"), neg = document.getElementById("ip-neg");
function cssVar(n, fb) { var v = getComputedStyle(document.documentElement).getPropertyValue(n); return (v && v.trim()) || fb; }
function draw() {
var p = +pos.value, n = +neg.value, comp = 100 - n, skew = p - comp;
document.getElementById("ip-posv").textContent = p;
document.getElementById("ip-negv").textContent = n;
var OPT = cssVar("--opt", "#e07a5f"), PES = cssVar("--pes", "#3d5a80"), MUT = cssVar("--muted-color", "#666"), TXT = cssVar("--text-color", "#222"), BD = cssVar("--border-color", "#ccc");
var W = root.clientWidth || 520, m = 22, y = 40;
var x = d3.scaleLinear().domain([0, 100]).range([m, W - m]);
svg.attr("viewBox", "0 0 " + W + " 84").selectAll("*").remove();
svg.append("rect").attr("x", m).attr("y", y - 9).attr("width", W - 2 * m).attr("height", 18).attr("rx", 9).attr("fill", BD).attr("opacity", 0.35);
svg.append("rect").attr("x", m).attr("y", y - 9).attr("width", x(p) - m).attr("height", 18).attr("rx", 9).attr("fill", OPT).attr("opacity", 0.85);
svg.append("line").attr("x1", x(comp)).attr("x2", x(comp)).attr("y1", y - 17).attr("y2", y + 17).attr("stroke", PES).attr("stroke-width", 2).attr("stroke-dasharray", "3 3");
svg.append("text").attr("x", x(comp)).attr("y", y - 21).attr("text-anchor", "middle").attr("fill", PES).attr("font-size", 10).text("100 − P⁻ = " + comp);
if (p !== comp) {
var x1 = Math.min(x(p), x(comp)), x2 = Math.max(x(p), x(comp));
svg.append("rect").attr("x", x1).attr("y", y + 12).attr("width", x2 - x1).attr("height", 6).attr("rx", 2).attr("fill", skew > 0 ? OPT : PES);
svg.append("text").attr("x", (x1 + x2) / 2).attr("y", y + 33).attr("text-anchor", "middle").attr("fill", TXT).attr("font-size", 11).attr("font-weight", 600).text((skew > 0 ? "+" : "") + skew + " pts unaccounted for");
}
var verdict = skew > 1 ? "optimistic" : skew < -1 ? "pessimistic" : "coherent";
var vc = skew > 1 ? OPT : skew < -1 ? PES : MUT;
document.getElementById("ip-out").innerHTML = "Skew = P⁺ − (100 − P⁻) = " + p + " − " + comp + " = <b style='color:" + vc + "'>" + (skew > 0 ? "+" : "") + skew + "</b> <span style='color:" + vc + "'>(" + verdict + ")</span>";
}
pos.addEventListener("input", draw); neg.addEventListener("input", draw);
if (window.ResizeObserver) { new ResizeObserver(draw).observe(root); } else { window.addEventListener("resize", draw); }
new MutationObserver(draw).observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
draw();
})();
</script>