diff --git a/frontend/app.js b/frontend/app.js index 7d87de8..4e3fe74 100755 --- a/frontend/app.js +++ b/frontend/app.js @@ -5584,7 +5584,6 @@ const SectionRail = (() => { // guessing an offset that is wrong on the next phone. function placeRail() { const r = rail(); - if (!r || r.classList.contains('hidden')) return; let occupied = 0; for (const id of ['bottomNav', 'miniBar']) { const el = document.getElementById(id); @@ -5597,7 +5596,10 @@ const SectionRail = (() => { const want = Math.round(occupied + 14); if (st.bottom !== want) { st.bottom = want; - r.style.setProperty('--rail-bottom', want + 'px'); + if (r) r.style.setProperty('--rail-bottom', want + 'px'); + // Published for anything else that must sit above the bottom bars — + // the watch-party panel's leave button was hidden behind them. + document.documentElement.style.setProperty('--bottom-chrome', Math.round(occupied) + 'px'); } } diff --git a/frontend/styles.css b/frontend/styles.css index 0c8c762..0a0a1c5 100755 --- a/frontend/styles.css +++ b/frontend/styles.css @@ -4070,8 +4070,21 @@ body.landscape-fs .player-stage { touch-action: none; } /* fullscreen (real or t .pt-send { display: flex; gap: 6px; } .pt-leave { background: transparent; border: none; color: var(--text-dim); font-size: 12px; cursor: pointer; text-decoration: underline; align-self: center; } @media (max-width: 720px) { - .party-panel { left: 8px; right: 8px; width: auto; top: auto; bottom: 8px; height: 62vh; } - .party-panel.min { height: auto; } + /* `bottom: 8px` put the panel's last child — "End the party" — underneath + the bottom nav and the mini player. --bottom-chrome is measured at runtime + (SectionRail.placeRail) because either bar can be absent. max-height keeps + the panel inside the viewport instead of growing off the top. */ + .party-panel { + left: 8px; right: 8px; width: auto; top: auto; + bottom: calc(var(--bottom-chrome, 88px) + 8px); + height: auto; + max-height: min(62vh, calc(100vh - var(--bottom-chrome, 88px) - 96px)); + } + .party-panel.min { height: auto; max-height: none; } + /* Whatever the content, the panel scrolls rather than hiding its own tail. */ + .pt-body { overflow-y: auto; } + /* The chat box used to take every spare pixel and push the buttons out. */ + .pt-chat { flex: 0 1 auto; max-height: 30vh; } } /* Uploads: cover art + badges on cards */ .thumb img.no-art { opacity: 0; } @@ -4235,7 +4248,7 @@ body.landscape-fs .player-stage { touch-action: none; } /* fullscreen (real or t them and overrides --rail-bottom; this is only the pre-measure default. */ .sec-rail { top: auto; - bottom: var(--rail-bottom, 150px); + bottom: var(--rail-bottom, calc(var(--bottom-chrome, 88px) + 14px)); transform: none; } }