aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-30 16:29:56 +0200
committeruser <user@clank>2026-08-30 16:29:56 +0200
commit17c9fd17c4f0502f3453347c3b0842f3bb4d6ca1 (patch)
treeb939cba6e8f9c13b98d92b0b71708a32b2288aba
parentwebdemo: no attach splash -- the welcome float already greets (diff)
downloadslosh-17c9fd17c4f0502f3453347c3b0842f3bb4d6ca1.tar.gz
slosh-17c9fd17c4f0502f3453347c3b0842f3bb4d6ca1.tar.xz
slosh-17c9fd17c4f0502f3453347c3b0842f3bb4d6ca1.zip
web: the demo machine can be powered off
A caption under the running machine offers the off switch, dressed as a link inside a sentence. Dropping the iframe out of the DOM tears the whole VM down -- emulator, kernel, disk cache, the lot -- the stage shrinks back into the poster (the original nodes come back from a stash, listeners and all, so the boot button is immediately live again), and the scroll follows both ways. Reload always did this; the button does it without taking the rest of the page with it.
-rw-r--r--web/index.html20
-rw-r--r--web/site.css13
2 files changed, 31 insertions, 2 deletions
diff --git a/web/index.html b/web/index.html
index c967655..91679f7 100644
--- a/web/index.html
+++ b/web/index.html
@@ -186,6 +186,9 @@
<button class="boot" type="button" id="boot_btn">boot the machine</button>
<p class="aside">riscv64 · TinyEMU, compiled to wasm · yours until you reload</p>
</div>
+ <p class="aside try-live" id="try_live" hidden>The machine is yours until
+ you <button class="linkish" type="button" id="kill_btn">power it
+ off</button> — that forgets it entirely, and the button comes back.</p>
</section>
<!-- ================================================================ -->
@@ -367,13 +370,15 @@ if (stagePin && littleLogo) {
// the front page keeps costing two files until someone asks for a machine.
// Small screens go to the page itself instead of embedding it.
const bootBtn = document.getElementById("boot_btn");
-if (bootBtn)
+if (bootBtn) {
+ const stage = document.getElementById("try_stage");
+ const live = document.getElementById("try_live");
+ const poster = [...stage.children]; // stashed while the machine runs
bootBtn.addEventListener("click", () => {
if (matchMedia("(max-width: 54rem)").matches) {
location.href = "demo/";
return;
}
- const stage = document.getElementById("try_stage");
stage.classList.add("booted"); // full height first: the guest reads the
const frame = document.createElement("iframe"); // room once, at boot
frame.src = "demo/?embed=1";
@@ -385,7 +390,18 @@ if (bootBtn)
// centred. Smooth for free -- the page scrolls smooth globally.
stage.scrollIntoView({ block: "center" });
frame.addEventListener("load", () => frame.contentWindow.focus());
+ live.hidden = false;
});
+ // Power off: dropping the iframe out of the DOM tears the whole machine
+ // down -- emulator, kernel, disk cache, the lot -- and the poster returns
+ // from the stash, offering to do it all again.
+ document.getElementById("kill_btn").addEventListener("click", () => {
+ stage.classList.remove("booted");
+ stage.replaceChildren(...poster);
+ live.hidden = true;
+ stage.scrollIntoView({ block: "center" });
+ });
+}
// The install box opens on the platform reading it; the tabs are CSS.
const ua = navigator.userAgent;
diff --git a/web/site.css b/web/site.css
index 5dd2162..d9b38fc 100644
--- a/web/site.css
+++ b/web/site.css
@@ -256,6 +256,19 @@ section > p:last-child { margin-bottom: 0; }
background: var(--bg);
}
+.try-live { text-align: center; }
+
+/* A button dressed as a link, for verbs that live inside a sentence. */
+.linkish {
+ padding: 0;
+ border: 0;
+ background: none;
+ color: var(--pink);
+ font: inherit;
+ cursor: pointer;
+}
+.linkish:hover { color: #fff; text-decoration: underline; }
+
/* ---- the install box ------------------------------------------------- */
/* Pick a platform, read only its instructions. Hidden radios, labels drawn
* like a slosh tab strip, one panel each; the switching is CSS. */