diff --git a/public/css/styles.css b/public/css/styles.css index 6b2328b..ab981f4 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -452,20 +452,24 @@ button.loading::after { ============================================ */ /* Modals: the overlay locks body scroll (overflow:hidden on ), so a panel - taller than the viewport would have its bottom cut off and the Save button - unreachable. Let the OVERLAY itself scroll like a page — the panel grows to - its natural height, and the overlay scrolls to reveal it. The panel uses - `margin:auto`, which centers a short panel but — unlike `align-items:center` - — does NOT clip the top when the panel is taller than the viewport (the - classic flexbox top-clip bug), so both the close button (top) and the Save - button (bottom) stay reachable. Applies on every screen size: the - Bewerbung-hinzufügen form has enough fields (Datum bis Interne Notizen) to - overflow even on a laptop, not just a phone. */ + taller than the viewport must scroll. The scroll container is the INNER + wrapper, not the backdrop, and it gets a DEFINITE height:100vh + overflow-y:auto. + A mere min-height:100vh (Tailwind's min-h-screen) is not enough: in Safari the + flex wrapper then does NOT grow to fit the panel, the panel overflows visibly + ("card geht aus dem Bild") but the container reports no overflow — so nothing + scrolls and the Save button is unreachable. A definite height + overflow + forces a real scroll container in every browser. The panel keeps margin:auto + so a SHORT modal stays centered, while a tall one starts at the top (no + top-clip) and scrolls to the bottom. -webkit-overflow-scrolling gives older + iOS momentum touch scrolling. */ .fixed.inset-0 { - overflow-y: auto !important; + overflow: hidden !important; } .fixed.inset-0 > .min-h-screen { - min-height: 100vh; + height: 100vh !important; + min-height: 0 !important; + overflow-y: auto !important; + -webkit-overflow-scrolling: touch; align-items: flex-start !important; } .fixed.inset-0 > .min-h-screen > .max-w-lg, diff --git a/server.js b/server.js index cba9e65..e5d6ee5 100644 --- a/server.js +++ b/server.js @@ -158,6 +158,18 @@ app.use('/api/indeed-import', (req, res, next) => { // Set EJS as template engine app.set('view engine', 'ejs'); + +// Cache-busting-Version für styles.css: die mtime der Datei beim Start. Wirkt +// nur als Query-Parameter am , also nach jedem Deploy (neuer +// Container → neue mtime → neue URL) erzwingt sie einen echten NeuDownload — +// "no-cache" allein reicht manchmal nicht, wenn ein Browser die alte Datei +// hart zwischengespeichert hat. Innerhalb eines Laufs bleibt der Wert stabil. +try { + const cssStat = fs.statSync(path.join(__dirname, 'public', 'css', 'styles.css')); + app.locals.assetVersion = String(cssStat.mtimeMs || Date.now()); +} catch (e) { + app.locals.assetVersion = String(Date.now()); +} app.set('views', path.join(__dirname, 'views')); // --------------------------------------------------------------------------- diff --git a/views/partials/head.ejs b/views/partials/head.ejs index b885faf..f2cb12a 100644 --- a/views/partials/head.ejs +++ b/views/partials/head.ejs @@ -20,4 +20,4 @@ tailwind.config = { darkMode: 'class' }; - +