An interactive physics lesson on Newton's three laws of motion. Tune friction to land a puck in a target zone, tune force and mass to hit a finish time, steer a rocket with action-reaction, match real scenarios to the right law, and take an auto-graded quiz on inertia, F = ma, and action-reaction pairs.
Live preview - click through and answer the questions just like a student would. Auto-grading is on.
This is the exact lesson code rendered by the interactive player above. It was generated by Glowsmith’s AI from a one-line prompt. Copy it, edit it, and generate your own.
<lesson>
<page>
<style>
*{box-sizing:border-box}
body{font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Arial;color:#1f2937;line-height:1.6;max-width:720px;margin:0 auto}
h1{font-size:1.6rem;color:#0f172a;margin:0 0 4px}
.sub{color:#64748b;font-size:0.95rem;margin:0 0 18px}
p{font-size:0.95rem}
.explain-demo{border:1px solid #dbe2ea;border-radius:16px;background:#f8fafc;padding:14px;margin:14px 0}
.explain-demo .tag{display:inline-block;font-size:0.7rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#059669;background:#ecfdf5;border:1px solid #a7f3d0;border-radius:999px;padding:2px 10px;margin-bottom:10px}
.tb-demo{display:grid;gap:12px}
.track{position:relative;height:70px;background:#dbeafe;border-radius:12px;border:1px solid #bfdbfe;overflow:hidden;margin:6px 0}
.puck{position:absolute;bottom:16px;left:10px;width:36px;height:36px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#93c5fd,#2563eb);box-shadow:0 4px 10px rgba(37,99,235,.4)}
.zone{position:absolute;bottom:0;top:0;left:140px;width:36px;background:repeating-linear-gradient(45deg,rgba(220,38,38,.28),rgba(220,38,38,.28) 6px,rgba(255,255,255,.0) 6px,rgba(255,255,255,.0) 12px);opacity:0;transition:opacity .4s ease}
.marker{position:absolute;top:4px;font-size:0.7rem;color:#dc2626;font-weight:700}
.row label{display:flex;justify-content:space-between;font-size:0.85rem;font-weight:600;color:#334155;margin-bottom:4px}
input[type=range]{width:100%;accent-color:#2563eb}
.btn-row{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
button{border:none;border-radius:999px;padding:10px 18px;font-size:0.9rem;font-weight:600;cursor:pointer;transition:transform .15s ease,background .15s ease}
button:hover{transform:translateY(-1px)}
button:disabled{opacity:.5;cursor:not-allowed}
#launchBtn,#dLaunch{background:#2563eb;color:#fff}
.tb-note{text-align:center;font-size:0.9rem;color:#334155;margin:0}
.readout{display:flex;gap:16px;justify-content:center;font-size:0.9rem;color:#334155;flex-wrap:wrap}
.readout b{font-size:1.2rem}
.opts{display:grid;grid-template-columns:1fr;gap:10px}
.opt{border:1px solid #e2e8f0;border-radius:12px;background:#fff;padding:14px;font-size:0.95rem;color:#334155;cursor:pointer;transition:transform .15s ease,border-color .15s ease;text-align:left}
.opt:hover{transform:translateY(-1px);border-color:#93c5fd}
.opt.on{border-color:#2563eb;background:#eff6ff;color:#1d4ed8;font-weight:700}
.opt:disabled{opacity:.55;cursor:not-allowed}
.lead-in{margin-top:18px;padding:10px 14px;border-left:4px solid #2563eb;background:#eff6ff;border-radius:0 10px 10px 0;font-size:0.95rem;color:#1e3a8a}
</style>
<h1>Law #1: Objects Like to Keep Doing Their Thing</h1>
<p class="sub">Newton’s first law is about inertia — the love of staying put or staying in motion.</p>
<p>An object at rest stays at rest, and an object in motion stays in motion, <em>unless a force acts on it</em>. The force that fights motion here is <strong>friction</strong>. Play with the free launch below first — it is not graded.</p>
<div class="explain-demo">
<span class="tag">Explore (not graded)</span>
<div class="tb-demo">
<div class="row">
<label>Friction <span id="dfv">30</span></label>
<input id="dfS" type="range" min="1" max="100" value="30">
</div>
<div class="track">
<div class="puck" id="dPuck"></div>
</div>
<div class="readout">
<span>Stop point <b id="dStop">?</b></span>
<span>Friction force <b id="dFric">0.30</b></span>
</div>
<div class="btn-row">
<button id="dLaunch" type="button">Launch demo puck</button>
</div>
<p class="tb-note" id="dNote1">Free play: low friction slides far, high friction stops fast. The puck keeps going until friction acts.</p>
</div>
</div>
<p class="lead-in">Now a real Law-1 question. Two pucks slide across the same ice at the same speed. Puck A is light; Puck B has twice the mass. Which puck stops sooner?</p>
<task-block title="Which puck stops first?" data-question-key="new-t1" feedback-correct="Both stop at the same distance! Friction force = weight × friction-coefficient, and deceleration = friction ÷ mass. Doubling the mass doubles the friction but also doubles the inertia - they cancel out, so both pucks slow down identically." feedback-incorrect="A heavier puck presses into the ice harder (more friction), but it also resists slowing down more (more inertia). Those two effects cancel - the deceleration is the same, so the stopping distance is the same." submit-label="Check my prediction">
<div class="tb-demo">
<div class="opts">
<button class="opt" id="pLight" type="button">The light puck A stops sooner</button>
<button class="opt" id="pHeavy" type="button">The heavy puck B stops sooner</button>
<button class="opt" id="pSame" type="button">Both stop at the same distance</button>
</div>
<p class="tb-note" id="n1">Pick which puck stops first, then submit.</p>
</div>
</task-block>
<script>
function puckStopX(f) {
if (f <= 0) return 520;
return Math.round(10 + 3400 / (f + 20));
}
var animTimer = null;
function animateEl(el, toX) {
if (!el) return;
if (animTimer) { clearInterval(animTimer); animTimer = null; }
var start = 10, x = start, i = 0;
var steps = Math.max(10, Math.round(Math.abs(toX - start) / 6));
animTimer = setInterval(function () {
i++;
x = start + (toX - start) * (i / steps);
el.style.left = x + "px";
if (i >= steps) { clearInterval(animTimer); animTimer = null; }
}, 14);
}
window.__modelxTaskState = { pick: "" };
window.__modelxGetTaskState = function () { return window.__modelxTaskState; };
window.__modelxGradeTask = function (s) { return s.pick === "same" ? 100 : 0; };
window.__modelxOnTaskSubmitted = function (score) {
var note = document.getElementById("n1");
if (note) note.innerHTML = score >= 100 ? "Both skid the same distance. Doubling the mass doubles the friction force (weight × coefficient) but also doubles the inertia - they cancel, so friction slows both pucks at exactly the same rate. Only the surface (the demo’s friction slider) changes the stop." : "Not quite. The heavy puck is pressed into the ice harder, but it also has more inertia - those two effects cancel, so friction decelerates both pucks identically and they stop at the same spot.";
["pLight", "pHeavy", "pSame"].forEach(function (id) { var el = document.getElementById(id); if (el) el.disabled = true; });
};
function updateFricOut(id, lblId, fricId) {
var f = +document.getElementById(id).value;
var lbl = document.getElementById(lblId); if (lbl) lbl.textContent = f;
var fric = document.getElementById(fricId); if (fric) fric.textContent = (f / 100).toFixed(2);
}
document.addEventListener("input", function (e) {
if (e.target.id === "dfS") {
updateFricOut("dfS", "dfv", "dFric");
var stop = document.getElementById("dStop"); if (stop) stop.textContent = "?";
}
});
var TASK_MAP = { pLight: "light", pHeavy: "heavy", pSame: "same" };
document.addEventListener("click", function (e) {
var id = e.target.id;
if (id === "dLaunch") {
var f = +document.getElementById("dfS").value;
var x = puckStopX(f);
var stop = document.getElementById("dStop"); if (stop) stop.textContent = x + "px";
animateEl(document.getElementById("dPuck"), x);
var note = document.getElementById("dNote1");
if (note) note.textContent = "Stops at " + x + "px with friction " + f + ". Lower friction = further slide, higher friction = shorter slide.";
return;
}
if (TASK_MAP[id]) {
window.__modelxTaskState.pick = TASK_MAP[id];
["pLight", "pHeavy", "pSame"].forEach(function (i) { var el = document.getElementById(i); if (el) el.classList.toggle("on", i === id); });
var n1 = document.getElementById("n1");
if (n1) n1.textContent = "Prediction picked. Submit to check.";
}
});
</script>
</page>
<page>
<style>
*{box-sizing:border-box}
body{font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Arial;color:#1f2937;line-height:1.6;max-width:720px;margin:0 auto}
h1{font-size:1.6rem;color:#0f172a;margin:0 0 4px}
.sub{color:#64748b;font-size:0.95rem;margin:0 0 18px}
p{font-size:0.95rem}
.explain-demo{border:1px solid #dbe2ea;border-radius:16px;background:#f8fafc;padding:14px;margin:14px 0}
.explain-demo .tag{display:inline-block;font-size:0.7rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#059669;background:#ecfdf5;border:1px solid #a7f3d0;border-radius:999px;padding:2px 10px;margin-bottom:10px}
.tb-demo{display:grid;gap:12px}
.eq{text-align:center;font-size:1.3rem;font-weight:800;color:#0f172a;letter-spacing:.5px}
.row label{display:flex;justify-content:space-between;font-size:0.85rem;font-weight:600;color:#334155;margin-bottom:4px}
input[type=range]{width:100%;accent-color:#4f46e5}
.road{position:relative;height:70px;background:#e0e7ff;border-radius:12px;border:1px solid #c7d2fe;overflow:hidden;margin:6px 0}
.finish{position:absolute;right:10px;top:0;bottom:0;width:4px;background:#dc2626;opacity:.7}
.cart{position:absolute;bottom:8px;left:8px;width:52px;height:34px;transition:left .02s linear}
.cart .body{width:52px;height:18px;background:#4f46e5;border-radius:6px 6px 0 0}
.cart .w{position:absolute;top:22px;width:12px;height:12px;border-radius:50%;background:#1e1b4b}
.cart .w1{left:6px}.cart .w2{right:6px}
.readout{display:flex;gap:16px;justify-content:center;font-size:0.9rem;color:#334155;flex-wrap:wrap}
.readout b{font-size:1.2rem}
.band{text-align:center;font-size:0.85rem;color:#4f46e5;font-weight:700;opacity:0;transition:opacity .4s ease}
.opts{display:grid;grid-template-columns:1fr;gap:10px}
.opt{border:1px solid #e2e8f0;border-radius:12px;background:#fff;padding:14px;font-size:0.95rem;color:#334155;cursor:pointer;transition:transform .15s ease,border-color .15s ease;text-align:left}
.opt:hover{transform:translateY(-1px);border-color:#a5b4fc}
.opt.on{border-color:#4f46e5;background:#eef2ff;color:#3730a3;font-weight:700}
.opt:disabled{opacity:.55;cursor:not-allowed}
.btn-row{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
button{border:none;border-radius:999px;padding:10px 18px;font-size:0.9rem;font-weight:600;cursor:pointer;transition:transform .15s ease}
button:hover{transform:translateY(-1px)}
button:disabled{opacity:.5;cursor:not-allowed}
#goBtn,#dGo{background:#4f46e5;color:#fff}
.tb-note{text-align:center;font-size:0.9rem;color:#334155;margin:0}
.lead-in{margin-top:18px;padding:10px 14px;border-left:4px solid #2563eb;background:#eff6ff;border-radius:0 10px 10px 0;font-size:0.95rem;color:#1e3a8a}
</style>
<h1>Law #2: Force, Mass, and Acceleration</h1>
<p class="sub">Newton’s second law is the famous equation F = ma.</p>
<p>Acceleration comes from <strong>a = F / m</strong>: more force, more acceleration; more mass, less acceleration. Try the free cart below — it is not graded.</p>
<div class="explain-demo">
<span class="tag">Explore (not graded)</span>
<div class="tb-demo">
<div class="eq">F = m × a</div>
<div class="row">
<label>Force (N) <span id="dF2v">10</span></label>
<input id="dF2S" type="range" min="0" max="100" value="10">
</div>
<div class="row">
<label>Mass (kg) <span id="dM2v">2</span></label>
<input id="dM2S" type="range" min="1" max="20" value="2">
</div>
<div class="road">
<div class="finish"></div>
<div class="cart" id="dCart2">
<div class="body"></div>
<div class="w w1"></div>
<div class="w w2"></div>
</div>
</div>
<div class="readout">
<span>Acceleration <b id="dA2">5.0</b> m/s²</span>
<span>Finish time <b id="dT2">?</b> s</span>
</div>
<div class="btn-row">
<button id="dGo" type="button">Launch demo cart</button>
</div>
<p class="tb-note" id="dNote2">Free play: raise force or lower mass and watch the cart race.</p>
</div>
</div>
<p class="lead-in">Now a Law-2 question. A cart is pushed with force 10 N and accelerates at 5 m/s². Keep the mass the same and double the force to 20 N. What happens to the acceleration?</p>
<task-block title="Double the force - what happens?" data-question-key="new-t2" feedback-correct="It doubles to 10 m/s². a = F / m: keep the mass fixed and double the force, and the quotient doubles - 20 ÷ 2 = 10." feedback-incorrect="a = F / m. The mass stays 2 kg, and the force doubles from 10 to 20 - divide the new force by the mass." submit-label="Check my prediction">
<div class="tb-demo">
<div class="opts">
<button class="opt" id="qDouble" type="button">It doubles to 10 m/s²</button>
<button class="opt" id="qSame" type="button">It stays 5 m/s²</button>
<button class="opt" id="qHalf" type="button">It halves to 2.5 m/s²</button>
<button class="opt" id="qZero" type="button">It drops to 0</button>
</div>
<p class="tb-note" id="n2">Force 10 N, mass 2 kg, acceleration 5 m/s². Double the force to 20 N and pick the new acceleration, then submit.</p>
</div>
</task-block>
<script>
var CART_DIST = 300;
function cartTime(f, m) {
if (f <= 0) return Infinity;
return Math.sqrt((2 * CART_DIST) / (f / m));
}
var cartTimer = null;
function runCartEl(cart, f, m, done) {
if (!cart) return;
if (cartTimer) { clearInterval(cartTimer); cartTimer = null; }
var t = cartTime(f, m);
if (!isFinite(t)) return;
var steps = Math.min(120, Math.max(20, Math.round(t * 20)));
var i = 0;
cart.style.left = "8px";
cartTimer = setInterval(function () {
i++;
var x = 8 + 480 * Math.pow(i / steps, 2);
cart.style.left = x + "px";
if (i >= steps) { clearInterval(cartTimer); cartTimer = null; if (done) done(); }
}, 50);
}
function updateDemoCart() {
var f = +document.getElementById("dF2S").value;
var m = +document.getElementById("dM2S").value;
var a = document.getElementById("dA2"); if (a) a.textContent = (f / m).toFixed(1);
var t = cartTime(f, m);
var tOut = document.getElementById("dT2"); if (tOut) tOut.textContent = isFinite(t) ? t.toFixed(1) : "infinite";
}
window.__modelxTaskState = { pick: "" };
window.__modelxGetTaskState = function () { return window.__modelxTaskState; };
window.__modelxGradeTask = function (s) { return s.pick === "double" ? 100 : 0; };
window.__modelxOnTaskSubmitted = function (score) {
var note = document.getElementById("n2");
if (note) note.innerHTML = score >= 100 ? "Correct. a = F / m with the mass held at 2 kg: 10 ÷ 2 = 5, then 20 ÷ 2 = 10 - double the force, double the acceleration." : "Work the formula: a = F / m. Mass stays 2 kg, force rises from 10 N to 20 N, so the acceleration rises from 5 to 10 m/s².";
["qDouble", "qSame", "qHalf", "qZero"].forEach(function (id) { var el = document.getElementById(id); if (el) el.disabled = true; });
};
document.addEventListener("input", function (e) {
if (e.target.id === "dF2S" || e.target.id === "dM2S") {
var fv = document.getElementById("dF2v"); if (fv) fv.textContent = document.getElementById("dF2S").value;
var mv = document.getElementById("dM2v"); if (mv) mv.textContent = document.getElementById("dM2S").value;
updateDemoCart();
}
});
var TASK_MAP2 = { qDouble: "double", qSame: "same", qHalf: "half", qZero: "zero" };
document.addEventListener("click", function (e) {
var id = e.target.id;
if (id === "dGo") {
var f = +document.getElementById("dF2S").value;
var m = +document.getElementById("dM2S").value;
runCartEl(document.getElementById("dCart2"), f, m, null);
var note = document.getElementById("dNote2");
if (note) note.textContent = "Demo cart ran! Try a bigger force or a smaller mass to see it cross faster.";
return;
}
if (TASK_MAP2[id]) {
window.__modelxTaskState.pick = TASK_MAP2[id];
["qDouble", "qSame", "qHalf", "qZero"].forEach(function (i) { var el = document.getElementById(i); if (el) el.classList.toggle("on", i === id); });
var n2 = document.getElementById("n2");
if (n2) n2.textContent = "Prediction picked. Submit to check.";
}
});
</script>
</page>
<page>
<style>
*{box-sizing:border-box}
body{font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Arial;color:#1f2937;line-height:1.6;max-width:720px;margin:0 auto}
h1{font-size:1.6rem;color:#0f172a;margin:0 0 4px}
.sub{color:#64748b;font-size:0.95rem;margin:0 0 18px}
p{font-size:0.95rem}
.explain-demo{border:1px solid #dbe2ea;border-radius:16px;background:#f8fafc;padding:14px;margin:14px 0}
.explain-demo .tag{display:inline-block;font-size:0.7rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#059669;background:#ecfdf5;border:1px solid #a7f3d0;border-radius:999px;padding:2px 10px;margin-bottom:10px}
.tb-demo{display:grid;gap:12px}
.scene{position:relative;height:230px;border:1px solid #bfdbfe;border-radius:14px;background:linear-gradient(180deg,#e0f2fe,#f8fafc);overflow:hidden}
.lbl-air{position:absolute;right:14px;top:10px;font-size:0.8rem;color:#be123c;font-weight:700;opacity:0;transition:opacity .3s ease}
.lbl-up{position:absolute;left:50%;top:10px;transform:translateX(-50%);font-size:0.8rem;color:#1d4ed8;font-weight:700;opacity:0;transition:opacity .3s ease}
.rocket{position:absolute;left:50%;bottom:20px;transform:translateX(-50%);transition:bottom .04s linear}
.stream{position:absolute;left:50%;transform:translateX(-50%);bottom:8px;width:14px;height:0;background:linear-gradient(#93c5fd,#1d4ed8);border-radius:4px;opacity:0}
.opts{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.opt{border:1px solid #e2e8f0;border-radius:12px;background:#fff;padding:14px;font-size:1rem;font-weight:700;color:#334155;cursor:pointer;transition:transform .15s ease,border-color .15s ease}
.opt:hover{transform:translateY(-1px);border-color:#bfdbfe}
.opt.on{border-color:#2563eb;background:#eff6ff;color:#1d4ed8}
.opt:disabled{opacity:.55;cursor:not-allowed}
.btn-row{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
button{border:none;border-radius:999px;padding:10px 18px;font-size:0.9rem;font-weight:600;cursor:pointer;transition:transform .15s ease;background:#2563eb;color:#fff}
button:hover{transform:translateY(-1px)}
button:disabled{opacity:.5;cursor:not-allowed}
.tb-note{text-align:center;font-size:0.9rem;color:#334155;margin:0}
.lead-in{margin-top:18px;padding:10px 14px;border-left:4px solid #2563eb;background:#eff6ff;border-radius:0 10px 10px 0;font-size:0.95rem;color:#1e3a8a}
</style>
<h1>Law #3: Every Action Has an Equal and Opposite Reaction</h1>
<p class="sub">Push something, and it pushes back — that’s how rockets fly.</p>
<p>A rocket fires hot gas <strong>downward</strong>. The gas pushes down on the world (action), and the world pushes the rocket up with equal strength (reaction). Watch the free demo launch as many times as you like.</p>
<div class="explain-demo">
<span class="tag">Explore (not graded)</span>
<div class="tb-demo">
<div class="scene">
<span class="lbl-up" id="dLblUp">rocket moves up</span>
<span class="lbl-air" id="dLblAir">gas pushed down</span>
<div class="stream" id="dStream"></div>
<div class="rocket" id="dRocket"></div>
</div>
<div class="btn-row">
<button id="dLaunch3" type="button">Launch demo rocket</button>
</div>
<p class="tb-note" id="dNote3">Free play: watch the gas stream down while the rocket goes up.</p>
</div>
</div>
<p class="lead-in">Now apply the rule to a brand-new setup. A fire extinguisher is strapped to a wheeled cart. You squeeze the handle and gas shoots out the LEFT side. Which way does the cart move?</p>
<task-block title="Extinguisher cart - which way?" data-question-key="new-t3" feedback-correct="The cart rolls RIGHT! Gas is shoved out the left (action), so the cart gets the equal-and-opposite push to the right (reaction)." feedback-incorrect="The reaction is the equal-and-opposite push. The gas is shoved one way, so the cart is shoved the other way." submit-label="Check my prediction">
<div class="tb-demo">
<div class="opts">
<button class="opt" id="tUp" type="button">Up</button>
<button class="opt" id="tDown" type="button">Down</button>
<button class="opt" id="tLeft" type="button">Left</button>
<button class="opt" id="tRight" type="button">Right</button>
</div>
<p class="tb-note" id="n3">Gas shoots out the left side. The cart feels the equal-and-opposite push. Pick a direction, then submit.</p>
</div>
</task-block>
<script>
function rocketSvg() {
return "<svg viewBox=\"0 0 40 56\" width=\"40\" height=\"56\"><path d=\"M20 2 C20 2 30 14 30 26 C30 38 26 46 20 54 C14 46 10 38 10 26 C10 14 20 2 20 2 Z\" fill=\"#dbeafe\" stroke=\"#1d4ed8\" stroke-width=\"2\"/><circle cx=\"20\" cy=\"26\" r=\"6\" fill=\"#f1f5f9\" stroke=\"#1d4ed8\" stroke-width=\"2\"/></svg>";
}
var rTimer = null;
function flyRocket(el, stream) {
if (!el || !stream) return;
if (rTimer) { clearInterval(rTimer); rTimer = null; }
stream.style.opacity = "1";
stream.style.height = "60px";
var pos = 20, i = 0;
rTimer = setInterval(function () {
i++;
pos += 3;
el.style.bottom = pos + "px";
if (i > 40) { clearInterval(rTimer); rTimer = null; stream.style.opacity = "0"; stream.style.height = "0"; }
}, 30);
}
var rocketEl = document.getElementById("dRocket");
if (rocketEl) rocketEl.innerHTML = rocketSvg();
window.__modelxTaskState = { pick: "" };
window.__modelxGetTaskState = function () { return window.__modelxTaskState; };
window.__modelxGradeTask = function (s) { return s.pick === "right" ? 100 : 0; };
window.__modelxOnTaskSubmitted = function (score) {
var note = document.getElementById("n3");
if (note) note.innerHTML = score >= 100 ? "Right! The gas is pushed left, so by Newton’s third law the cart is pushed right with equal strength. Action and reaction, in opposite directions, every time." : "Gas exits one way, cart rolls the other. The gas goes left, so the equal-and-opposite reaction shoves the cart right.";
["tUp", "tDown", "tLeft", "tRight"].forEach(function (id) { var el = document.getElementById(id); if (el) el.disabled = true; });
};
var TASK_MAP3 = { tUp: "up", tDown: "down", tLeft: "left", tRight: "right" };
document.addEventListener("click", function (e) {
var t = e.target;
var id = t.id;
if (id === "dLaunch3") {
var dl = document.getElementById("dLblAir"); if (dl) dl.style.opacity = "1";
var dl2 = document.getElementById("dLblUp"); if (dl2) dl2.style.opacity = "1";
flyRocket(document.getElementById("dRocket"), document.getElementById("dStream"));
var note = document.getElementById("dNote3");
if (note) note.textContent = "Gas down, rocket up - two forces in an equal-and-opposite pair.";
return;
}
if (TASK_MAP3[id]) {
window.__modelxTaskState.pick = TASK_MAP3[id];
["tUp", "tDown", "tLeft", "tRight"].forEach(function (i) { var el = document.getElementById(i); if (el) el.classList.toggle("on", i === id); });
var n3 = document.getElementById("n3");
if (n3) n3.textContent = "Direction picked. Submit to check.";
}
});
</script>
</page>
<page>
<style>
*{box-sizing:border-box}
body{font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Arial;color:#1f2937;line-height:1.6;max-width:720px;margin:0 auto}
h1{font-size:1.6rem;color:#0f172a;margin:0 0 4px}
.sub{color:#64748b;font-size:0.95rem;margin:0 0 18px}
p{font-size:0.95rem}
.explain-demo{border:1px solid #dbe2ea;border-radius:16px;background:#f8fafc;padding:14px;margin:14px 0}
.explain-demo .tag{display:inline-block;font-size:0.7rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#059669;background:#ecfdf5;border:1px solid #a7f3d0;border-radius:999px;padding:2px 10px;margin-bottom:10px}
.tb-demo{display:grid;gap:12px}
.guess{display:grid;grid-template-columns:1fr;gap:10px}
.guess button{border:1px solid #e2e8f0;border-radius:12px;background:#fff;padding:12px 14px;font-size:0.95rem;color:#334155;cursor:pointer;transition:transform .15s ease,border-color .15s ease;text-align:left}
.guess button:hover{transform:translateY(-1px);border-color:#bfdbfe}
.guess button.on{border-color:#16a34a;background:#f0fdf4;font-weight:700;color:#166534}
.guess button:disabled{opacity:.55;cursor:not-allowed}
.law-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
.law-card{border:1px solid #dbe2ea;border-radius:14px;padding:14px;background:#fff}
.law-card h3{margin:0 0 6px;font-size:0.95rem;color:#0f172a}
.law-card p{margin:0;font-size:0.85rem;color:#475569;line-height:1.5}
.match-row{display:grid;grid-template-columns:1fr 1fr;gap:10px;align-items:center}
.match-row label{font-size:0.9rem;color:#334155;font-weight:600}
.match-row select{padding:8px 10px;border:1px solid #c7d2fe;border-radius:10px;font-size:0.9rem;background:#fff}
.match-row select:disabled{opacity:.7}
.match-row select.good{border-color:#16a34a;background:#f0fdf4}
.match-row select.wrong{border-color:#dc2626;background:#fef2f2}
.tb-note{text-align:center;font-size:0.9rem;color:#334155;margin:0}
.lead-in{margin-top:18px;padding:10px 14px;border-left:4px solid #2563eb;background:#eff6ff;border-radius:0 10px 10px 0;font-size:0.95rem;color:#1e3a8a}
</style>
<h1>All Three Laws in Action</h1>
<p class="sub">Real life stacks the laws together. Can you spot them?</p>
<p>Try the free guessing game first — tap a scenario and the law is revealed instantly.</p>
<div class="explain-demo">
<span class="tag">Explore (not graded)</span>
<div class="tb-demo">
<div class="guess">
<button id="ds1" type="button" data-label="A kicked ball on ice slides for ages">A kicked ball on ice slides for ages</button>
<button id="ds2" type="button" data-label="Pedal harder and the bike speeds up more">Pedal harder and the bike speeds up more</button>
<button id="ds3" type="button" data-label="Jumping up pushes your feet against the ground">Jumping up pushes your feet against the ground</button>
</div>
<p class="tb-note" id="dNote4">Tap a scenario to reveal which law explains it.</p>
</div>
</div>
<p class="lead-in">Now match each scenario to its law - no cheat sheet this time. The demo taught you the pattern; apply it to these new situations.</p>
<task-block title="Match each scenario to its law" data-question-key="new-t4" feedback-correct="All matched! Inertia, F = ma, and action-reaction are the three ways motion changes." feedback-incorrect="Book on a table = rest stays rest. Heavy cart = mass fights force. Swimmer = forces in pairs." submit-label="Grade my match">
<div class="tb-demo">
<div class="match-row">
<label>A book sits on a table and stays put forever.</label>
<select id="m1"><option value="">choose a law</option><option value="1">Law 1</option><option value="2">Law 2</option><option value="3">Law 3</option></select>
</div>
<div class="match-row">
<label>A full grocery cart is harder to push than an empty one.</label>
<select id="m2"><option value="">choose a law</option><option value="1">Law 1</option><option value="2">Law 2</option><option value="3">Law 3</option></select>
</div>
<div class="match-row">
<label>A swimmer pushes water backward to move forward.</label>
<select id="m3"><option value="">choose a law</option><option value="1">Law 1</option><option value="2">Law 2</option><option value="3">Law 3</option></select>
</div>
<p class="tb-note" id="n4">Pick a law for each scenario, then submit.</p>
</div>
</task-block>
<script>
var MATCH = { m1: "1", m2: "2", m3: "3" };
var DEMO4 = { ds1: "Law 1 - inertia", ds2: "Law 2 - F = ma", ds3: "Law 3 - action/reaction" };
window.__modelxGetTaskState = function () {
return { m1: document.getElementById("m1").value, m2: document.getElementById("m2").value, m3: document.getElementById("m3").value };
};
window.__modelxGradeTask = function (s) {
var good = 0;
Object.keys(MATCH).forEach(function (k) { if (s[k] === MATCH[k]) good++; });
return good === 3 ? 100 : good * 33;
};
window.__modelxOnTaskSubmitted = function (score) {
var explain = {
m1: "The book stays at rest until a force acts - that’s Law 1 (inertia).",
m2: "Same push, more mass, less acceleration - that’s Law 2 (F = ma).",
m3: "Push water back, water pushes you forward - that’s Law 3 (action-reaction)."
};
Object.keys(MATCH).forEach(function (k) {
var sel = document.getElementById(k);
if (!sel) return;
var good = sel.value === MATCH[k];
sel.classList.toggle("good", good);
sel.classList.toggle("wrong", !good);
sel.disabled = true;
});
var note = document.getElementById("n4");
if (note) note.innerHTML = score >= 100 ? "Perfect. " + explain.m1 + " " + explain.m2 + " " + explain.m3 : "Here’s the full picture: " + explain.m1 + " " + explain.m2 + " " + explain.m3;
};
document.addEventListener("change", function (e) {
if (e.target.id === "m1" || e.target.id === "m2" || e.target.id === "m3") {
var picked = ["m1", "m2", "m3"].filter(function (k) { return document.getElementById(k).value !== ""; }).length;
var note = document.getElementById("n4");
if (note) note.textContent = picked === 3 ? "All three matched! Submit to grade." : picked + " of 3 matched.";
}
});
document.addEventListener("click", function (e) {
var id = e.target.id;
if (DEMO4[id]) {
var el = document.getElementById(id);
if (el) {
el.classList.add("on");
el.disabled = true;
el.textContent = el.getAttribute("data-label") + " = " + DEMO4[id];
}
var note = document.getElementById("dNote4");
if (note) note.textContent = "Revealed! Tap the others to compare.";
}
});
</script>
</page>
<page>
<style>
*{box-sizing:border-box}
body{font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Arial;color:#1f2937;line-height:1.6;max-width:720px;margin:0 auto}
h1{font-size:1.6rem;color:#0f172a;margin:0 0 4px}
.sub{color:#64748b;font-size:0.95rem;margin:0 0 18px}
p{font-size:0.95rem}
.sum{border:1px solid #dbe2ea;border-radius:14px;background:#f8fafc;padding:16px;font-size:0.95rem;color:#334155}
.sum b{color:#0f172a}
</style>
<h1>Name That Law</h1>
<p class="sub">Four scenarios. Name the law at work.</p>
<div class="sum">
<p><b>Law 1</b>: inertia - no force, no change in motion.<br>
<b>Law 2</b>: F = ma - force, mass, and acceleration.<br>
<b>Law 3</b>: action-reaction pairs.</p>
</div>
<question-block question="A hockey puck on nearly frictionless ice keeps sliding. This best demonstrates..." answers="Newton’s 1st law|Newton’s 2nd law|Newton’s 3rd law|None of the laws" correct="Newton’s 1st law" mode="single" feedback-correct="Yes! Rest stays rest, motion stays motion, until a force acts." feedback-incorrect="Which law is about objects keeping their state of motion?" data-question-key="new-q1"></question-block>
<question-block question="Pushing a full grocery cart is harder than pushing an empty one. This best demonstrates..." answers="Newton’s 1st law|Newton’s 2nd law|Newton’s 3rd law|Friction only" correct="Newton’s 2nd law" mode="single" feedback-correct="Correct! More mass (F = ma) means more force for the same acceleration." feedback-incorrect="Which law connects force, mass, and acceleration?" data-question-key="new-q2"></question-block>
<question-block question="A swimmer pushes water backward to move forward. This best demonstrates..." answers="Newton’s 1st law|Newton’s 2nd law|Newton’s 3rd law|Buoyancy" correct="Newton’s 3rd law" mode="single" feedback-correct="Right! Push water back (action), water pushes you forward (reaction)." feedback-incorrect="Which law says forces come in equal and opposite pairs?" data-question-key="new-q3"></question-block>
<dropdown-question text="If you double the mass of a cart while keeping the same force, the acceleration will __blank__." options="double|stay the same|be cut in half|go to zero" correct="be cut in half" feedback-correct="Correct! a = F / m, so bigger m means smaller a." feedback-incorrect="Divide F by the new mass and see what changes." data-question-key="new-q4"></dropdown-question>
<script></script>
</page>
</lesson>