From f5691841078e6a242d89f58c2fd15b233f99e3e8 Mon Sep 17 00:00:00 2001 From: Mark Dumay <61946753+markdumay@users.noreply.github.com> Date: Thu, 9 Jul 2026 21:11:36 +0200 Subject: [PATCH] feat(lightbox): fade the dialog in and out Replace the fade-in-only keyframe with transition-based fades on both open and close, using @starting-style for the entry value and allow-discrete on display/overlay so the dialog animates out before it leaves the top layer. The backdrop fades too. Still gated behind prefers-reduced-motion; unsupported browsers simply skip the animation. Co-Authored-By: Claude Opus 4.8 (1M context) --- assets/scss/components/_lightbox.scss | 41 +++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/assets/scss/components/_lightbox.scss b/assets/scss/components/_lightbox.scss index 0345c706..197aa616 100644 --- a/assets/scss/components/_lightbox.scss +++ b/assets/scss/components/_lightbox.scss @@ -61,19 +61,48 @@ dialog.lightbox { } @media (prefers-reduced-motion: no-preference) { + // Fade + subtle scale on both open and close. `@starting-style` supplies the + // pre-open value so the entry transition runs, and `allow-discrete` on + // `display`/`overlay` keeps the dialog in the top layer long enough to animate + // out before it is hidden. Browsers without these features simply skip the + // animation (the dialog appears/disappears instantly) — no worse than a cut. + dialog.lightbox { + opacity: 0; + transform: scale(0.98); + transition: + opacity 0.2s ease-out, + transform 0.2s ease-out, + overlay 0.2s ease-out allow-discrete, + display 0.2s ease-out allow-discrete; + } + dialog.lightbox[open] { - animation: lightbox-in 0.15s ease-out; + opacity: 1; + transform: scale(1); } - @keyframes lightbox-in { - from { + @starting-style { + dialog.lightbox[open] { opacity: 0; transform: scale(0.98); } + } + + dialog.lightbox::backdrop { + opacity: 0; + transition: + opacity 0.2s ease-out, + overlay 0.2s ease-out allow-discrete, + display 0.2s ease-out allow-discrete; + } - to { - opacity: 1; - transform: scale(1); + dialog.lightbox[open]::backdrop { + opacity: 1; + } + + @starting-style { + dialog.lightbox[open]::backdrop { + opacity: 0; } } }