From f9225f0d21ee70730740e9eb32f091b63d0ee991 Mon Sep 17 00:00:00 2001 From: Ray Slakinski <19767+rays@users.noreply.github.com> Date: Sat, 19 Sep 2026 19:10:39 -0400 Subject: [PATCH] Keep the bottom bar clear of the home indicator (#46) body is a grid of topbar / main / status / player, and nothing in the page accounted for a display's own intrusions. Mobile Safari hides that by insetting the layout viewport to the safe area, so the site was fine in a browser -- but a full-screen shell, the native app or the site added to an iOS home screen, hands the page the whole display, and the last row landed under the home indicator with its seek bar and times half cut off. viewport-fit=cover asks for the whole screen deliberately, and the bars along the edges now pay for the insets in padding: the bottom for the indicator, left and right for the notch in landscape. A browser with its own chrome reports nought and nothing moves. The padding has to be longhand, and there is a comment saying so, because the minifier drops the space between a calc() and the value after it in a shorthand -- padding:7px calc(12px + var(--safe-r))7px ... -- and a browser then throws the whole declaration away. The bars lost all their padding, which moved the item list far enough that the pull-to-refresh browser test stopped finding it; nothing reported an error, and the page still loaded. buildStyle now fails the build on a calc() run into its neighbour rather than trusting it. Co-Authored-By: Claude Opus 5 --- web/app.css | 33 +++++++++++++++++++++++++++++---- web/build.mjs | 9 ++++++++- web/index.html | 2 +- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/web/app.css b/web/app.css index e36d19d..c782386 100644 --- a/web/app.css +++ b/web/app.css @@ -500,8 +500,22 @@ a{color:var(--accent)} } .iconbtn:hover{background:var(--raise);color:var(--fg)} /* One toolbar across the window, as the original had: grouped buttons, search on the right. */ +/* The display's own intrusions -- the home indicator along the bottom, the notch at one side in + landscape. viewport-fit=cover hands the page the whole screen, which is what a standalone + shell and an iOS home-screen app both give it, so the bars along the edges pay for them in + padding. A browser with its own chrome reports nought and nothing moves. */ +:root{ + --safe-b:env(safe-area-inset-bottom,0px); + --safe-l:env(safe-area-inset-left,0px); + --safe-r:env(safe-area-inset-right,0px); +} #topbar{ - display:flex;align-items:center;gap:10px;padding:7px 12px;min-width:0;overflow:hidden; + display:flex;align-items:center;gap:10px;min-width:0;overflow:hidden; + /* Longhand, and it has to stay longhand: the minifier runs a calc() in a padding shorthand + into the value after it -- `calc(12px + var(--safe-r))7px` -- and the browser then throws + the whole declaration away, leaving the bar with no padding at all. */ + padding-top:7px;padding-bottom:7px; + padding-left:calc(12px + var(--safe-l));padding-right:calc(12px + var(--safe-r)); background:var(--panel);border-bottom:1px solid var(--line); } #topbar .grow{flex:1} @@ -830,7 +844,9 @@ body.playing .eq i:nth-child(3){animation-delay:-.6s} #player{ border-top:1px solid var(--line);background:var(--panel); display:none;grid-template-columns:auto 1fr auto;gap:14px;align-items:center; - padding:9px 16px;box-shadow:0 -6px 24px rgba(6,10,16,.4); + padding-top:9px;padding-bottom:calc(9px + var(--safe-b)); + padding-left:calc(16px + var(--safe-l));padding-right:calc(16px + var(--safe-r)); + box-shadow:0 -6px 24px rgba(6,10,16,.4); } #player.on{display:grid} /* #audio is a