fix: page transition crossfade eliminates dark-mode flash on navigation

Removes the sequential fade-out → wait → fade-in pattern that causes
a visible black flash in dark mode between page transitions. Replaces
with immediate crossfade (new page fades in over old content, no wait).

Changes:
- layout.css: Add page-crossfade-in keyframe (0.18s) + prefers-reduced-motion override
- router.js: Remove outClass/inClass direction logic and oldPage fadeout wait

The new approach:
1. Old page remains visible until new page renders
2. New page fades in (0.18s) with full opacity, overlaying old content
3. No 120ms delay = no visible flash in dark mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ulas Kalayci
2026-04-29 13:09:21 +02:00
parent ca26befecd
commit 9b7909f690
2 changed files with 14 additions and 8 deletions
-8
View File
@@ -350,20 +350,12 @@ async function renderPage(route, previousPath = null) {
// Richtung bestimmen (previousPath ist der alte Pfad vor der Navigation)
const direction = getDirection(previousPath, route.path);
const outClass = direction === 'right' ? 'page-transition--out-left' : 'page-transition--out-right';
const inClass = direction === 'right' ? 'page-transition--in-right' : 'page-transition--in-left';
// Performance: backdrop-filter während Übergang deaktivieren (Android-Optimierung).
// glass.css setzt alle backdrop-filter im app-content auf none solange diese Klasse aktiv ist.
document.documentElement.classList.add('navigating');
// Alte Seite kurz ausfaden, falls vorhanden
const oldPage = content.querySelector('.page-transition');
if (oldPage) {
oldPage.classList.add(outClass);
await new Promise(r => setTimeout(r, 120));
}
// Alter Inhalt ist jetzt weg - altes Stylesheet kann entfernt werden
const pageWrapper = document.createElement('div');
pageWrapper.className = 'page-transition';
+14
View File
@@ -80,6 +80,11 @@
to { opacity: 0; transform: translateX(20px); }
}
@keyframes page-crossfade-in {
from { opacity: 0; }
to { opacity: 1; }
}
.page-transition--in-right {
animation: page-slide-in-right 0.2s var(--ease-out);
}
@@ -95,6 +100,11 @@
pointer-events: none;
}
.page-transition--crossfade {
animation: page-crossfade-in 0.18s var(--ease-out);
opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
.page-transition--in-right,
.page-transition--in-left {
@@ -105,6 +115,10 @@
.page-transition--out-right {
animation: none;
}
.page-transition--crossfade {
animation: none;
opacity: 1;
}
}
/* --------------------------------------------------------