From 48d5e15f7fd8bab9e5cfb661f002c71e99c7cba6 Mon Sep 17 00:00:00 2001 From: claude Date: Tue, 16 Jun 2026 21:35:52 +0000 Subject: [PATCH] fix: Lumiere card dropdown clipped by card's backdrop-filter and transform .lumiere-card has both backdrop-filter and a hover transform, both of which create a new containing block for position:fixed descendants, trapping Popper dropdowns inside the card's overflow:hidden bounds. Fix: move .lumiere-card-actions outside .lumiere-card (sibling inside .lumiere-card-wrapper, which has position:relative but no filter or transform). The actions strip is now absolutely positioned at the card bottom with its own solid background and bottom border-radius. No backdrop-filter on the strip to avoid re-introducing the same trap. Co-Authored-By: Claude Sonnet 4.6 --- .../components/project-list-lumiere.tsx | 24 ++++++++++--------- .../pages/project-list-lumiere.scss | 20 +++++++++++++--- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/services/web/frontend/js/features/project-list/components/project-list-lumiere.tsx b/services/web/frontend/js/features/project-list/components/project-list-lumiere.tsx index ccb44c0fba..37c2309443 100644 --- a/services/web/frontend/js/features/project-list/components/project-list-lumiere.tsx +++ b/services/web/frontend/js/features/project-list/components/project-list-lumiere.tsx @@ -171,17 +171,19 @@ const ProjectCard = memo(function ProjectCard({ {date} -
- - - {project.compiler === 'quarto' ? ( - - ) : ( - - )} - - -
+ + {/* Actions live outside .lumiere-card so Popper dropdowns are not + clipped by the card's backdrop-filter / transform context. */} +
+ + + {project.compiler === 'quarto' ? ( + + ) : ( + + )} + +
) diff --git a/services/web/frontend/stylesheets/pages/project-list-lumiere.scss b/services/web/frontend/stylesheets/pages/project-list-lumiere.scss index e3695f109a..8b3a3a462a 100644 --- a/services/web/frontend/stylesheets/pages/project-list-lumiere.scss +++ b/services/web/frontend/stylesheets/pages/project-list-lumiere.scss @@ -537,14 +537,28 @@ $lum-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' wi } } - // Action strip — icon buttons that fade in when the card is hovered + // Action strip — lives *outside* .lumiere-card so the dropdown menus inside + // are not trapped by the card's backdrop-filter and transform (both of which + // create a new containing block for position:fixed, clipping Popper menus). + // position:absolute on the wrapper (which has no transform/filter) lets any + // position:fixed child escape to the viewport as expected. .lumiere-card-actions { + position: absolute; + bottom: 0; + left: 0; + right: 0; + z-index: 2; display: flex; align-items: center; justify-content: center; gap: 2px; padding: 3px 6px 5px; + // Solid background — intentionally no backdrop-filter here, which would + // also create a fixed containing block and trap the Popper dropdown. + background: rgba(255, 255, 255, 0.97); border-top: 1px solid rgba($lum-teal, 0.10); + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; opacity: 0; transition: opacity 0.15s ease; @@ -561,8 +575,8 @@ $lum-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' wi } } - .lumiere-card:hover .lumiere-card-actions, - .lumiere-card:focus-within .lumiere-card-actions { + .lumiere-card-wrapper:hover .lumiere-card-actions, + .lumiere-card-wrapper:focus-within .lumiere-card-actions { opacity: 1; }