[object Object]

← back to Wallco Ai

polish(modals): proper slide-in via translateX (was display:none, no animation) · viewport-safe width using min(480px, 92vw) · clean shadow seam when side-by-side (was bleeding pair shadow over chat) · 260ms cubic-bezier easing · mobile breakpoint 920px

81b730859529634bea41e686ad031d0601a79872 · 2026-05-11 21:50:10 -0700 · Steve

Files touched

Diff

commit 81b730859529634bea41e686ad031d0601a79872
Author: Steve <steve@designerwallcoverings.com>
Date:   Mon May 11 21:50:10 2026 -0700

    polish(modals): proper slide-in via translateX (was display:none, no animation) · viewport-safe width using min(480px, 92vw) · clean shadow seam when side-by-side (was bleeding pair shadow over chat) · 260ms cubic-bezier easing · mobile breakpoint 920px
---
 server.js | 47 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/server.js b/server.js
index a3cd86e..04c52ef 100644
--- a/server.js
+++ b/server.js
@@ -950,14 +950,30 @@ ${isAdmin ? `
   .decision .btn-pair { background:#16140f; color:#d2b15c; border-color:#3a3631; }
   .decision .btn-pair:hover { background:#d2b15c; color:#0f0e0c; border-color:#d2b15c; }
   /* Pair modal */
-  #pair-modal { position:fixed; top:0; right:0; bottom:0; width:480px; background:#16140f; border-left:1px solid #2a2825; display:none; flex-direction:column; z-index:1001; box-shadow:-8px 0 20px rgba(0,0,0,.4); color:#e8e2d6; font:13px/1.4 -apple-system, system-ui, sans-serif; transition: right .22s ease; }
-  #pair-modal.open { display:flex; }
-  /* Side-by-side when both right-pinned modals are open — pair stays at right edge, chat shifts left by pair's width */
-  body:has(#pair-modal.open):has(#chat-modal.open) #chat-modal { right: 480px; }
-  body:has(#chat-modal.open):has(#pair-modal.open) #pair-modal { box-shadow: -8px 0 20px rgba(0,0,0,.4), -1px 0 0 #2a2825; }
-  @media (max-width: 900px) {
-    body:has(#pair-modal.open):has(#chat-modal.open) #chat-modal { right: 0; opacity: 0; pointer-events: none; }
-    #pair-modal, #chat-modal { width: 100vw; max-width: 480px; }
+  /* Right-pinned drawers — pair + chat. Side-by-side when both open. */
+  :root { --modal-pair-w: 480px; --modal-chat-w: 420px; }
+  #pair-modal {
+    position:fixed; top:0; right:0; bottom:0;
+    width: min(var(--modal-pair-w), 92vw);
+    background:#16140f; border-left:1px solid #2a2825;
+    display:flex; flex-direction:column; z-index:1001;
+    box-shadow:-8px 0 20px rgba(0,0,0,.4);
+    color:#e8e2d6; font:13px/1.4 -apple-system, system-ui, sans-serif;
+    transform: translateX(100%);
+    transition: transform .26s cubic-bezier(.4,0,.2,1), right .26s cubic-bezier(.4,0,.2,1);
+    visibility: hidden;
+  }
+  #pair-modal.open { transform: translateX(0); visibility: visible; }
+  /* Side-by-side when both right-pinned modals are open — chat slides left by pair's width */
+  body:has(#pair-modal.open):has(#chat-modal.open) #chat-modal { right: var(--modal-pair-w); }
+  /* When chat is to the left of pair, drop pair's left-shadow (it overlapped chat) and add a clean seam */
+  body:has(#chat-modal.open):has(#pair-modal.open) #pair-modal { box-shadow: none; border-left-color: #3a3631; }
+  body:has(#chat-modal.open):has(#pair-modal.open) #chat-modal { border-right: 1px solid #2a2825; }
+  /* Narrow viewport — can't fit both. Hide chat while pair is open; user toggles between them. */
+  @media (max-width: 920px) {
+    body:has(#pair-modal.open):has(#chat-modal.open) #chat-modal { right: 0; opacity: 0; visibility: hidden; pointer-events: none; }
+    #pair-modal { width: min(var(--modal-pair-w), 100vw); }
+    #chat-modal { width: min(var(--modal-chat-w), 100vw); }
   }
   #pair-modal header { padding:14px 18px; border-bottom:1px solid #2a2825; display:flex; gap:10px; align-items:center; }
   #pair-modal header .ctx-main { flex:1; font-size:12px; color:#d2b15c; }
@@ -993,8 +1009,18 @@ ${isAdmin ? `
   .chip:hover { background:#4a443d; color:#fff; }
   .chip.has-chat { border-color: var(--chip-hot); color: var(--chip-hot); }
   /* chat side panel */
-  #chat-modal { position:fixed; top:0; right:0; bottom:0; width:420px; background:#16140f; border-left:1px solid #2a2825; display:none; flex-direction:column; z-index:1000; box-shadow:-8px 0 20px rgba(0,0,0,.4); color:#e8e2d6; font:13px/1.4 -apple-system, system-ui, sans-serif; transition: right .22s ease; }
-  #chat-modal.open { display:flex; }
+  #chat-modal {
+    position:fixed; top:0; right:0; bottom:0;
+    width: min(var(--modal-chat-w), 92vw);
+    background:#16140f; border-left:1px solid #2a2825;
+    display:flex; flex-direction:column; z-index:1000;
+    box-shadow:-8px 0 20px rgba(0,0,0,.4);
+    color:#e8e2d6; font:13px/1.4 -apple-system, system-ui, sans-serif;
+    transform: translateX(100%);
+    transition: transform .26s cubic-bezier(.4,0,.2,1), right .26s cubic-bezier(.4,0,.2,1), opacity .2s;
+    visibility: hidden;
+  }
+  #chat-modal.open { transform: translateX(0); visibility: visible; }
   #chat-modal header { padding:14px 18px; border-bottom:1px solid #2a2825; display:flex; gap:10px; align-items:center; }
   #chat-modal header .ctx-main { flex:1; font-size:12px; color:#d2b15c; }
   #chat-modal header .ctx-sub  { font-size:10px; color:#888; }
@@ -1574,6 +1600,7 @@ ${htmlHeader('')}
 </main>
 ${FOOTER}
 ${HAMBURGER_JS}
+${req.query.figcap === '1' ? '<script src="https://mcp.figma.com/mcp/html-to-design/capture.js" async></script>' : ''}
 </body>
 </html>`;
 }

← 292faa8 tick 13: palette-rebalance batch — 10 new SDXL designs targe  ·  back to Wallco Ai  ·  feat: admin design ratings + RLHF-lite retry on /design/:id 8e98a62 →