Make the middle term match

HTML for this example

Select the code and use your copy shortcut. Changes in this preview are temporary.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Make the middle term match</title>
<style>:root{color-scheme:light;--ink:#202b32;--muted:#52616a;--paper:#fff;--bg:#eaf0f3;--accent:#17485d;--soft:#edf5f8;--line:#cbd8de;--heading:Georgia,serif}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:16px/1.65 system-ui,-apple-system,"Segoe UI",sans-serif}main{max-width:1040px;margin:28px auto;background:var(--paper);border:1px solid var(--line);border-radius:12px;overflow:hidden}header{padding:28px 32px;border-top:7px solid var(--accent);border-bottom:1px solid var(--line)}.kicker{color:var(--accent);margin:0 0 10px}h1{font:500 clamp(30px,5vw,46px)/1.15 var(--heading);letter-spacing:-.02em;margin:0 0 14px;max-width:850px}header p{margin:0;color:var(--muted)}.content{padding:0 32px 32px}h2{font:500 27px/1.25 var(--heading);margin:0 0 18px}h3{font-size:20px;line-height:1.35;margin:0 0 12px}p{margin:0 0 14px}p:last-child{margin-bottom:0}section{padding-top:28px;margin-top:28px;border-top:1px solid var(--line)}.hero{padding:24px;margin-top:24px;background:var(--soft);border-left:5px solid var(--accent);border-radius:4px}.hero p:first-child{font-size:21px;font-weight:650}.controls{display:flex;flex-wrap:wrap;gap:10px;margin:16px 0}button,.controls a{font:inherit;line-height:1.4;border:1px solid var(--accent);border-radius:6px;padding:12px 16px;background:var(--paper);color:var(--accent);cursor:pointer;text-decoration:none;max-width:100%}button:hover,.controls a:hover{background:var(--soft)}button[aria-pressed="true"],#check,#inspect,#rebuild,#apply{background:var(--accent);color:#fff}button:focus-visible,input:focus-visible,textarea:focus-visible,summary:focus-visible,a:focus-visible{outline:3px solid #c56412;outline-offset:3px}label{display:block;font-weight:650;margin:16px 0}input,textarea{display:block;font:inherit;line-height:1.55;color:var(--ink);background:var(--paper);border:1px solid #8297a2;border-radius:5px;padding:12px;width:100%;min-width:0;margin-top:8px}input[type="number"],input[type="date"]{max-width:320px}textarea{resize:vertical}.result{background:var(--soft);padding:18px 20px;border-left:4px solid var(--accent);font-weight:600;overflow-wrap:anywhere}.note{background:var(--soft);border:1px solid var(--line);padding:18px;border-radius:5px}.stage{padding:24px;background:var(--soft);border:1px solid var(--line);border-radius:8px}.record-list{display:grid;gap:14px;margin:20px 0}.record{padding:20px;border:1px solid var(--line);border-left:4px solid var(--accent);border-radius:4px}.record p{margin-bottom:8px}.two-col{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px}.two-col>section{margin-top:0}.metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:20px}.metrics p{font-size:16px!important;font-weight:400!important}.metrics strong{display:block;font-size:30px;font-weight:650;line-height:1.3;font-variant-numeric:tabular-nums;margin-top:8px}.timeline{list-style:none;padding:0;margin:0;counter-reset:phase}.timeline li{padding:14px 0 14px 20px;border-left:3px solid var(--accent);border-bottom:1px solid var(--line)}details{border:1px solid var(--line);border-radius:5px;padding:16px 18px;margin:20px 0}summary{cursor:pointer;font-weight:650}details[open] summary{margin-bottom:16px}dl{display:grid;grid-template-columns:1fr 1.5fr;gap:12px 20px}dt{font-weight:650}dd{margin:0}blockquote{margin:20px 0;padding:20px 24px;border-left:5px solid var(--accent);font:500 27px/1.5 var(--heading);background:var(--soft)}.expression{font-size:27px;font-weight:650;line-height:1.5;overflow-wrap:anywhere}.sample{padding:20px;background:var(--soft)}footer{padding:22px 32px;color:var(--muted);background:var(--soft);border-top:1px solid var(--line)}[hidden]{display:none!important}.sound-map{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-template-areas:". ahead ." "left center right" ". behind .";gap:8px;text-align:center;padding:20px 0;border:1px dashed var(--accent);background:radial-gradient(circle,transparent 35%,var(--line) 35.3%,transparent 35.7%)}.sound-map p{margin:0;padding:12px 4px;overflow-wrap:anywhere}.map-ahead{grid-area:ahead}.map-left{grid-area:left}.map-center{grid-area:center;font-weight:700}.map-right{grid-area:right}.map-behind{grid-area:behind}.partner{background:var(--soft);padding:24px;border-radius:12px}.partner blockquote:empty{display:none}.route-tree{border-left:3px solid var(--accent);padding-left:24px;display:grid;gap:20px}.route-tree article{padding:18px;background:var(--soft);border-radius:6px}.counters{display:flex;flex-wrap:wrap;gap:8px}.counter{display:inline-flex;align-items:center;justify-content:center;border:2px solid;border-radius:50%;width:56px;height:56px;font-size:16px;font-weight:650}.counter.red{color:#882f27;background:#ffebe7;border-color:#ba5145}.counter.blue{color:#18467a;background:#e2efff;border-color:#3f71a5}.counter-stage{padding:20px;border:1px dashed var(--accent);border-radius:8px}.facts{padding-left:24px}.facts li{margin-bottom:10px}
body.spanish{--bg:#f8e9df;--accent:#8b342a;--soft:#fff0e7;--line:#e5c7b6;--ink:#3c251e}body.asset{--bg:#142632;--accent:#154e69;--soft:#eaf4f8}body.sop{--bg:#e7e8e5;--accent:#484e3f;--soft:#f4f4ed;--heading:system-ui,sans-serif}body.fundraising{--bg:#f0e9f5;--accent:#65377b;--soft:#f7effb;--line:#d9c5e3}body.outdoor{--bg:#e2e9dd;--accent:#2e5b36;--soft:#edf4e9;--line:#bdcfb6}body.about{--bg:#eef0ff;--accent:#51439a;--soft:#f2f0ff;--line:#d4cee9}body.volunteer{--bg:#f1e3d6;--accent:#824128;--soft:#fbf0e5;--line:#ddc5ad}body.event{--bg:#222735;--accent:#303a65;--soft:#edf0fa;--line:#c8cfe2;--heading:system-ui,sans-serif}body.invoice{--bg:#dfece9;--accent:#176253;--soft:#eaf6f2;--line:#bed8d0;--heading:system-ui,sans-serif}body.backlog{--bg:#e6e3ee;--accent:#59447a;--soft:#f4f0fa;--line:#d5cbe5}body.sitemap{--bg:#e5edf2;--accent:#235574;--soft:#edf5fb;--heading:system-ui,sans-serif}body.cooperative{--bg:#f3ecd8;--accent:#795c16;--soft:#fbf5e5;--line:#ddce9f}body.factoring{--bg:#102d2b;--accent:#165d4d;--soft:#e7f6ef;--heading:system-ui,sans-serif}body.ratio{--bg:#fae8da;--accent:#883b2a;--soft:#fff3e8}body.fragments{--bg:#e7e1d7;--accent:#443c31;--soft:#f5f1e9;--line:#d0c6b7}body.nouns{--bg:#eee5f4;--accent:#67417d;--soft:#f8f0fc;--line:#dbc7e5}
@media(max-width:640px){main{margin:0;border-radius:0;border-left:0;border-right:0}header{padding:24px 20px}.content{padding:0 20px 24px}footer{padding:20px}.hero,.stage,.partner{padding:18px}h1{font-size:34px}h2{font-size:26px}.two-col{grid-template-columns:1fr;gap:16px}.controls button,.controls a{flex:1 1 135px}.metrics{grid-template-columns:1fr 1fr}.hero .metrics{gap:14px}.metrics strong{font-size:27px}.sound-map{font-size:16px}.sound-map p{padding:14px 2px}.route-tree{padding-left:16px}.expression{font-size:24px}dl{grid-template-columns:1fr}blockquote{padding:16px;font-size:24px}input[type="number"],input[type="date"]{max-width:100%}}</style>
</head>
<body class="factoring"><main><header><p class="kicker">Three monic trinomial cards · integer-factor scope · expression identities</p><h1>Make the middle term match</h1></header><div class="content"><div class="hero"><p>(x + m)(x + n) = x² + (m + n)x + mn</p><p>Both conditions: m + n = b AND mn = c. These are expressions, not equations to solve for x.</p></div><section><h2>Choose the target</h2><div class="controls"><button type="button" id="p1" aria-pressed="true">P1 · positive middle</button><button type="button" id="p2" aria-pressed="false">P2 · negative middle</button><button type="button" id="p3" aria-pressed="false">P3 · integer-pair limit</button></div><p id="target" class="expression">P1: x² + 13x + 40</p><div class="two-col"><label for="m">Integer m<input id="m" type="number" value="" min="-50" max="50" step="1"></label><label for="n">Integer n<input id="n" type="number" value="" min="-50" max="50" step="1"></label></div><div class="controls"><button type="button" id="check" >Check pair</button><button type="button" id="pairs" >Inspect integer pairs</button><button type="button" id="reset" >Reset</button></div><p id="result" class="result" role="status" aria-live="polite">Unanswered. Enter two integer constants.</p><p id="trace">Try 4 and 10 to inspect the middle-term distractor.</p><label for="reason">Explain the coefficient match (teacher review)<textarea id="reason" rows="3"></textarea></label></section><section><h2>Separate teacher reference</h2><details><summary>View the three-card key</summary><p>P1: 5 and 8 → sum 13, product 40. P2: −5 and −8 → sum −13, product 40. P3: product-one integer pairs have sums 2 and −2, not 3.</p><p>No integer pair is not the same as no real factors or no roots. Swapping constants gives the same factorization.</p></details><p>Blank candidate table: card ID · m/n · sum/product · proposed factors · expansion · reason. No free-reason grading or saved learner work.</p></section></div><footer><p>Local example only. Controls send nothing and save no changes; reloading restores the sample. Keep your worked factorization separately.</p></footer><noscript>Enable JavaScript to use this interactive example.</noscript></main>
<script>
(()=>{
'use strict';
const q=s=>document.querySelector(s);const put=(s,t)=>{q(s).textContent=t;};const on=(s,fn,event='click')=>q(s).addEventListener(event,fn);const esc=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));const mark=(ids,chosen)=>ids.forEach(id=>q(id).setAttribute('aria-pressed',String(id===chosen)));
const cards=[{b:13,c:40,name:'P1: x² + 13x + 40'},{b:-13,c:40,name:'P2: x² − 13x + 40'},{b:3,c:1,name:'P3: x² + 3x + 1'}];let card=0;const term=(v,suffix='')=>(v<0?' − ':' + ')+Math.abs(v)+suffix;function choose(i){card=i;mark(['#p1','#p2','#p3'],'#p'+(i+1));put('#target',cards[i].name);q('#m').value='';q('#n').value='';q('#reason').value='';put('#result','Unanswered. Enter two integer constants.');put('#trace','Compare both coefficients with the target.');}['#p1','#p2','#p3'].forEach((id,i)=>on(id,()=>choose(i)));['#m','#n'].forEach(id=>on(id,()=>{put('#result','Pair changed. Check both coefficients.');put('#trace','No current expansion.');},'input'));on('#check',()=>{const a=q('#m').value.trim(),b=q('#n').value.trim();if(!a||!b){put('#result','Unanswered. Enter two integer constants.');put('#trace','No current expansion.');return;}if(!/^-?\d+$/.test(a)||!/^-?\d+$/.test(b)||Math.abs(Number(a))>50||Math.abs(Number(b))>50){put('#result','Unsupported input. Use integer constants from −50 to 50.');put('#trace','No current expansion.');return;}const m=Number(a),n=Number(b),sum=m+n,product=m*n,c=cards[card];put('#result','Sum '+sum+' / target '+c.b+'; product '+product+' / target '+c.c+'. '+(sum===c.b&&product===c.c?'Both coefficients match.':'Revise: '+(sum!==c.b?'middle coefficient differs':'constant differs')+'.'));put('#trace','(x'+term(m)+')(x'+term(n)+') = x²'+term(n,'x')+term(m,'x')+term(product)+' = x²'+term(sum,'x')+term(product));});on('#pairs',()=>{const c=cards[card],pairs=[];for(let m=-50;m<=50;m++)for(let n=m;n<=50;n++)if(m*n===c.c)pairs.push([m,n]);const matches=pairs.filter(([m,n])=>m+n===c.b);put('#result',matches.length?'Matching integer pair: '+matches.map(p=>p.join(', ')).join('; ')+'. Both sum and product match.':'No pair in the integer-factor scope. This does not mean no real factors.');put('#trace','Product '+c.c+' candidates: '+pairs.map(([m,n])=>'('+m+', '+n+') sum '+(m+n)).join('; ')+'.');});on('#reset',()=>choose(0));
})();
</script>
</body>
</html>