From d4b7731bdc7feba774961379ce5a1ed719ab9625 Mon Sep 17 00:00:00 2001 From: librelad Date: Thu, 28 May 2026 00:58:04 +0100 Subject: [PATCH] fix(apps): drop cap when visible cards meet the natural row width so the box reaches the layout edge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fixed-width tracks change kept card widths uniform across categories but reintroduced the "large gap on the right" outside the glass box — with cards locked at 300px and the cap formula tracking exactly N cards, the box stopped wherever the visible cards ended, leaving up to 150px+ of empty parent space to its right on a wide viewport. Bringing back the natural-columns sentinel from the earlier pass. updateAppsCount measures the parent's inner width (minus the section's 90px of margin/padding/border), computes the column count the auto-fill grid would pick at full width, and passes a huge sentinel (99) as --app-count whenever visible cards >= that count. The formula then overshoots the 100%-44px parent cap and the box runs edge-to-edge. Cards themselves still come out at --app-min because the grid template is repeat(auto-fill, var(--app-min)) — no 1fr stretching — so the cross-category uniformity from the previous fix is preserved. Net effect: 1-2 cards on a 3-col viewport still shrink (no card-shaped hole), 3+ cards reach the right edge of the layout, every card lines up across categories regardless of which branch fires. Signed-off-by: librelad --- .../js/components/app/apps-manager.js | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/containers/libreportal/frontend/js/components/app/apps-manager.js b/containers/libreportal/frontend/js/components/app/apps-manager.js index e270d72..299dd2c 100755 --- a/containers/libreportal/frontend/js/components/app/apps-manager.js +++ b/containers/libreportal/frontend/js/components/app/apps-manager.js @@ -552,12 +552,17 @@ class AppsManager { }); } - // Sync --app-count on .apps-section so the CSS max-width formula shrinks - // the glass box around the visible cards (avoiding a card-shaped hole on - // the right). Cards themselves are fixed-width via the grid template, so - // card widths line up across categories — no "natural cols" measurement - // needed any more. Driven from render, sidebar search filter, and resize - // (the 100%-44px parent cap still depends on viewport width). + // Sync --app-count on .apps-section. The CSS formula shrinks the glass + // box around the visible cards when there are too few to fill a row + // (so 1-2 cards on a 3-col viewport don't leave a card-shaped hole). + // When the visible count already meets the natural full-width column + // count, we pass a large sentinel (99) so the formula overshoots the + // 100%-44px parent cap and the box reaches the layout edge — otherwise + // a row with "exactly enough" cards would leave a visible gap between + // the box's right edge and the parent. Cards themselves are fixed + // --app-min width via the grid template, so widths line up across + // categories regardless of which branch fires. Driven from render, + // sidebar search filter, and window resize. updateAppsCount() { const container = document.getElementById('apps-section'); if (!container) return; @@ -565,7 +570,20 @@ class AppsManager { container.querySelectorAll('.app-card').forEach(card => { if (card.style.display !== 'none') visible++; }); - container.style.setProperty('--app-count', Math.max(visible, 1)); + visible = Math.max(visible, 1); + + const style = getComputedStyle(container); + const minCol = parseFloat(style.getPropertyValue('--app-min')) || 300; + const gap = parseFloat(style.getPropertyValue('--app-gap')) || 20; + // Section eats 90px of parent's inner width before any card lands: + // 22px margin + 22px padding + 1px border, doubled. + const parent = container.parentElement; + const inside = parent ? Math.max(0, parent.clientWidth - 90) : 0; + const naturalCols = inside > 0 + ? Math.max(1, Math.floor((inside + gap) / (minCol + gap))) + : visible; + const effective = visible >= naturalCols ? 99 : visible; + container.style.setProperty('--app-count', effective); } // Client-side substring filter wired to the sidebar search box.