ScienceGrade 85 pages

Interactive Newton's Laws of Motion Lesson for 8th Grade

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.

Interactive Newton's Laws of Motion Lesson for 8th Grade
Live preview - answer the questions as a student would
Pages
Law #1: Objects Like to Keep Doing Their Thing

Live preview - click through and answer the questions just like a student would. Auto-grading is on.

What students will learn

  • State Newton's first law and connect it to inertia
  • Apply Newton's second law, F = ma, to predict motion
  • Identify action-reaction force pairs
  • See all three laws in one real-world scenario
›View the lesson source

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&rsquo;s first law is about inertia &mdash; 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 &mdash; 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 &times; friction-coefficient, and deceleration = friction &divide; 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 &times; coefficient) but also doubles the inertia - they cancel, so friction slows both pucks at exactly the same rate. Only the surface (the demo&rsquo;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&rsquo;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 &mdash; 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 &times; 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&sup2;. 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&sup2;. a = F / m: keep the mass fixed and double the force, and the quotient doubles - 20 &divide; 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&sup2;</button>
          <button class="opt" id="qSame" type="button">It stays 5 m/s&sup2;</button>
          <button class="opt" id="qHalf" type="button">It halves to 2.5 m/s&sup2;</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&sup2;. 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 &divide; 2 = 5, then 20 &divide; 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&sup2;.";
        ["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 &mdash; that&rsquo;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&rsquo;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 &mdash; 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&rsquo;s Law 1 (inertia).",
          m2: "Same push, more mass, less acceleration - that&rsquo;s Law 2 (F = ma).",
          m3: "Push water back, water pushes you forward - that&rsquo;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&rsquo;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&rsquo;s 1st law|Newton&rsquo;s 2nd law|Newton&rsquo;s 3rd law|None of the laws" correct="Newton&rsquo;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&rsquo;s 1st law|Newton&rsquo;s 2nd law|Newton&rsquo;s 3rd law|Friction only" correct="Newton&rsquo;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&rsquo;s 1st law|Newton&rsquo;s 2nd law|Newton&rsquo;s 3rd law|Buoyancy" correct="Newton&rsquo;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>