diff --git a/src/static/css/style.css b/src/static/css/style.css index 46f4af7..09db3f2 100644 --- a/src/static/css/style.css +++ b/src/static/css/style.css @@ -2133,12 +2133,19 @@ a.dev-source-pill:hover { font-size: 12px; color: var(--accent); font-weight: 600; } -/* === Blur for First Refresh === */ -.tab-panels.blurred .tab-panel { +/* === Blur for First Refresh === + * Liegt auf #incident-view, damit Header (Titel/Aktionen/Beschreibung) und + * Tab-Panels gemeinsam unscharf werden. will-change + translateZ erzwingen + * einen persistenten GPU-Composite-Layer, sodass der Effekt bei Window-Resize + * und Reflow nicht zerschossen wird. Keine Transition: Blur soll schlagartig + * kommen und schlagartig gehen, sonst sieht man waehrend des Reflows einen + * lesbaren Zwischenzustand. */ +#incident-view.refresh-blurred { filter: blur(8px); pointer-events: none; user-select: none; - transition: filter 0.4s ease; + will-change: filter; + transform: translateZ(0); } /* === Disabled Actions During First Refresh === */ @@ -4035,7 +4042,6 @@ a.dev-source-pill:hover { .tab-panel .ht-timeline-container { min-height: 200px; } -.tab-panels.blurred { filter: blur(4px); pointer-events: none; } .grid-stack .card-header:active { cursor: grabbing; diff --git a/src/static/js/app.js b/src/static/js/app.js index 1d94dfa..9176f83 100644 --- a/src/static/js/app.js +++ b/src/static/js/app.js @@ -735,12 +735,12 @@ const App = { if (prevOverlay) prevOverlay.style.display = 'none'; const prevMini = document.getElementById('progress-mini'); if (prevMini) prevMini.style.display = 'none'; - const grid = document.querySelector('.tab-panels'); + const blurTarget = document.getElementById('incident-view'); // Wenn gerade ein erster Refresh laeuft, Blur stehen lassen statt // remove+add im selben Tick — CSS filter:blur greift sonst nicht. const _restState = isRefreshing ? UI._progressState[id] : null; const _willReBlur = _restState && _restState.isFirst && !_restState.minimized; - if (grid && !_willReBlur) grid.classList.remove('blurred'); + if (blurTarget && !_willReBlur) blurTarget.classList.remove('refresh-blurred'); if (isRefreshing) { const state = UI._progressState[id]; diff --git a/src/static/js/components.js b/src/static/js/components.js index 5a05c8c..1d39084 100644 --- a/src/static/js/components.js +++ b/src/static/js/components.js @@ -334,16 +334,16 @@ const UI = { // Blocking (no close) for first refresh if (state.isFirst) { overlay.classList.add('blocking'); - // Apply blur to grid - const grid = document.querySelector('.tab-panels'); - if (grid) { - grid.classList.add('blurred'); + // Apply blur to incident-view (Header + Tab-Panels gemeinsam). + const blurTarget = document.getElementById('incident-view'); + if (blurTarget) { + blurTarget.classList.add('refresh-blurred'); // Sicherheitsnetz: bei viel DOM-Reshuffle im selben Tick // (Display-Wechsel, renderSidebar, leere innerHTML) greift // CSS filter:blur erst beim naechsten Layout-Pass. Im // naechsten Frame nochmal setzen — idempotent. requestAnimationFrame(() => { - if (state && state.isFirst) grid.classList.add('blurred'); + if (state && state.isFirst) blurTarget.classList.add('refresh-blurred'); }); } } else { @@ -474,8 +474,8 @@ const UI = { if (incidentId === App.currentIncidentId) { // Remove blur - const grid = document.querySelector('.tab-panels'); - if (grid) grid.classList.remove('blurred'); + const blurTarget = document.getElementById('incident-view'); + if (blurTarget) blurTarget.classList.remove('refresh-blurred'); const overlay = document.getElementById('progress-overlay'); if (overlay) { @@ -568,8 +568,8 @@ const UI = { if (!incidentId) incidentId = App.currentIncidentId; // Remove blur - const grid = document.querySelector('.tab-panels'); - if (grid) grid.classList.remove('blurred'); + const blurTarget = document.getElementById('incident-view'); + if (blurTarget) blurTarget.classList.remove('refresh-blurred'); if (incidentId === App.currentIncidentId) { const overlay = document.getElementById('progress-overlay');