From 9c703d6e642640873ddf6f1b5202f74d4c9bf054 Mon Sep 17 00:00:00 2001 From: sravan Date: Sun, 19 Jul 2026 06:51:38 +0530 Subject: [PATCH] mobile: chat open = instant + quick opacity fade (no slide) (batch128) User chose the fade over chasing the WebView slide-teardown reflow. Open now: the cache- rendered conversation is placed instantly and fades opacity 0->1 over 140ms. No transform, no off-screen pane, no list-column display toggle -> nothing to reflow at the end, so the ~40ms end-of-slide settle cannot occur. Same afterOpenSlide queue flushes network reconcile/ pins/appends at fade-end. Desktop unaffected (fade is mobile-only via __freshOpen). Co-Authored-By: Claude Opus 4.8 --- server/public/home.html | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/server/public/home.html b/server/public/home.html index 1cc056b..27007f7 100644 --- a/server/public/home.html +++ b/server/public/home.html @@ -1110,10 +1110,11 @@ its own promoted GPU layer while the message DOM renders + scrolls to bottom. Phase 2 (.chat-anim, added by JS on a double-rAF AFTER the render is laid out & painted): the compositor transitions transform 100%→0 with the main thread idle → a true 60fps slide, not a jump. Dropped at transitionend. */ - body.chat-opening .content{display:block!important;transform:translate3d(100%,0,0);} /* ONLY the start transform — display/z-index/box-shadow/will-change all come from the resting body.chat-open rule above, so removing chat-opening/chat-anim at transitionend changes NOTHING (transform 0→none is a no-op, the layer stays promoted). Zero teardown = zero end-of-slide hitch. */ - body.chat-opening.chat-anim .content{transform:translate3d(0,0,0);transition:transform .3s cubic-bezier(.32,.72,0,1);} - body.chat-opening .chatcol{display:flex!important;position:absolute;inset:0;z-index:0;transform:translate3d(0,0,0);will-change:transform;backface-visibility:hidden;} - body.chat-opening.chat-anim .chatcol{transform:translate3d(-22%,0,0);transition:transform .3s cubic-bezier(.32,.72,0,1);} /* translate-only parallax — animating filter:brightness re-rasters the list every frame AND again on teardown; the dim isn't worth the jank. */ + /* OPEN = instant position + a quick opacity fade. No transform, no parallax, no list-column display + toggle → there is literally nothing to reflow when it finishes, so the old ~40ms end-of-slide settle + is gone by construction. The list (chatcol) stays display:none throughout; content fades in over the bg. */ + body.chat-opening .content{display:block!important;opacity:0;} + body.chat-opening .content.chat-fadein{opacity:1;transition:opacity .14s ease-out;} /* CLOSE / drag-back: reveal the list underneath (parallax in) while the conversation slides off right (.content moved by an inline transform in showWelcome()/the edge-drag gesture). */ body.chat-closing .content, body.chat-dragging .content{display:block!important;z-index:2;box-shadow:-12px 0 30px rgba(15,23,42,.18);will-change:transform;} @@ -1145,7 +1146,7 @@ -