diff --git a/wasm/repl/repl.js b/wasm/repl/repl.js index 7b2f8d5..57e3e8e 100644 --- a/wasm/repl/repl.js +++ b/wasm/repl/repl.js @@ -287,8 +287,13 @@ function renderAll() { } transcriptEl.appendChild(block); } - // Body owns the scroll now; jump it to the latest entry. - window.scrollTo({ top: document.documentElement.scrollHeight, behavior: "instant" }); + // Body owns the scroll now; jump to the bottom after layout settles. + // requestAnimationFrame lets the just-mounted DOM contribute to + // scrollHeight before we measure — otherwise on first load the page + // sticks at the top because the transcript hasn't been laid out yet. + requestAnimationFrame(() => { + window.scrollTo({ top: document.documentElement.scrollHeight, behavior: "instant" }); + }); } // ─── Input handling ───────────────────────────────────────────────── diff --git a/www/repl/repl.js b/www/repl/repl.js index 7b2f8d5..57e3e8e 100644 --- a/www/repl/repl.js +++ b/www/repl/repl.js @@ -287,8 +287,13 @@ function renderAll() { } transcriptEl.appendChild(block); } - // Body owns the scroll now; jump it to the latest entry. - window.scrollTo({ top: document.documentElement.scrollHeight, behavior: "instant" }); + // Body owns the scroll now; jump to the bottom after layout settles. + // requestAnimationFrame lets the just-mounted DOM contribute to + // scrollHeight before we measure — otherwise on first load the page + // sticks at the top because the transcript hasn't been laid out yet. + requestAnimationFrame(() => { + window.scrollTo({ top: document.documentElement.scrollHeight, behavior: "instant" }); + }); } // ─── Input handling ─────────────────────────────────────────────────