aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-30 15:43:42 +0200
committeruser <user@clank>2026-08-30 15:43:42 +0200
commit37f79de1f52c67fa99af8da8f9f96f5f26604ffb (patch)
treee27d1d83ba4d6b6bf48c87fa38fc9a0a71cb9f5a
parentwebdemo: fit with font size, not scale -- a transform misplaces clicks (diff)
downloadslosh-37f79de1f52c67fa99af8da8f9f96f5f26604ffb.tar.gz
slosh-37f79de1f52c67fa99af8da8f9f96f5f26604ffb.tar.xz
slosh-37f79de1f52c67fa99af8da8f9f96f5f26604ffb.zip
web: centre the floating logo in the air above the terminal
A fixed top worked at one viewport height and overlapped the pinned terminal at others: the terminal's top edge is (viewport - the stage's lift padding) / 2 - half the player, which no constant tracks. Measure it instead, centre the logo in what remains, and hide it outright when a short viewport leaves no air -- hiding beats overlapping. Re-placed on resize and by a ResizeObserver on the player mounts, not on the pin: the players are zero-height until their casts arrive, and the pin is a 100vh box that never resizes, so watching it would freeze the placement at the pre-load height.
-rw-r--r--web/index.html24
-rw-r--r--web/site.css3
2 files changed, 27 insertions, 0 deletions
diff --git a/web/index.html b/web/index.html
index f491f24..db43867 100644
--- a/web/index.html
+++ b/web/index.html
@@ -297,6 +297,30 @@ if (bigLogo && littleLogo && "IntersectionObserver" in window) {
}).observe(bigLogo);
}
+// ...and vertically centred in the air between the viewport top and the
+// pinned terminal's top edge. That edge is (viewport - the stage's lift
+// padding) / 2 - half the player, which moves with both the window and the
+// player's own height -- so it is measured, not guessed in CSS. Hidden when
+// the air runs out rather than allowed to overlap the terminal.
+const stagePin = document.querySelector(".stage-pin");
+function placeLittleLogo() {
+ const player = stagePin && stagePin.querySelector(".stage-active");
+ if (!player || !littleLogo) return;
+ const pad = parseFloat(getComputedStyle(stagePin).paddingBottom) || 0;
+ const termTop = (innerHeight - pad) / 2 - player.offsetHeight / 2;
+ const air = termTop - littleLogo.offsetHeight;
+ littleLogo.style.top = Math.max(8, air / 2) + "px";
+ littleLogo.style.visibility = air >= 16 ? "" : "hidden";
+}
+if (stagePin && littleLogo) {
+ placeLittleLogo();
+ window.addEventListener("resize", placeLittleLogo);
+ // The players size themselves when their casts arrive -- and the pin is a
+ // 100vh box that never resizes, so watch the players, not the pin.
+ const ro = new ResizeObserver(placeLittleLogo);
+ for (const el of stagePin.querySelectorAll("[data-sloshcast]")) ro.observe(el);
+}
+
// The install box opens on the platform reading it; the tabs are CSS.
const ua = navigator.userAgent;
const os = /Windows/i.test(ua) ? "windows" : /Mac/i.test(ua) ? "macos" : "linux";
diff --git a/web/site.css b/web/site.css
index a5b28c4..d9764f9 100644
--- a/web/site.css
+++ b/web/site.css
@@ -57,6 +57,9 @@ kbd {
.logo-float {
position: fixed;
+ /* The resting value only: the script centres it in the air between the
+ * viewport top and the pinned terminal's top edge, which no fixed number
+ * tracks across viewport heights. */
top: 13.8rem;
/* Centred on the stage column: the tour is layout-centred and the stage
* is the 3fr of its 3fr/2fr split, so the terminal's midline sits at