diff --git a/packages/core/src/dom/media/custom-media-element/index.ts b/packages/core/src/dom/media/custom-media-element/index.ts index 23579300..f675ea62 100644 --- a/packages/core/src/dom/media/custom-media-element/index.ts +++ b/packages/core/src/dom/media/custom-media-element/index.ts @@ -106,9 +106,10 @@ function getVideoTemplateHTML(attrs: Record): string { } video::-webkit-media-text-track-container { - transition: transform var(--media-caption-track-duration, 0) ease-out; + transition: translate var(--media-caption-track-duration, 0) ease-out; transition-delay: var(--media-caption-track-delay, 0); - transform: translateY(var(--media-caption-track-y, 0)) scale(0.98); + translate: 0 var(--media-caption-track-y, 0); + scale: 0.98; z-index: 1; font-family: inherit; } diff --git a/packages/html/src/define/base.css b/packages/html/src/define/base.css index 845ef2ea..80ac3605 100644 --- a/packages/html/src/define/base.css +++ b/packages/html/src/define/base.css @@ -15,9 +15,10 @@ video-player video { } video-player video::-webkit-media-text-track-container { - transition: transform var(--media-caption-track-duration, 0) ease-out; + transition: translate var(--media-caption-track-duration, 0) ease-out; transition-delay: var(--media-caption-track-delay, 0); - transform: translateY(var(--media-caption-track-y, 0)) scale(0.98); + translate: 0 var(--media-caption-track-y, 0); + scale: 0.98; z-index: 1; font-family: inherit; } diff --git a/packages/skins/src/default/css/components/buttons.css b/packages/skins/src/default/css/components/buttons.css index 6784e32d..7c00bca4 100644 --- a/packages/skins/src/default/css/components/buttons.css +++ b/packages/skins/src/default/css/components/buttons.css @@ -17,7 +17,7 @@ color: oklch(0 0 0); font-weight: 500; text-align: center; - transition-property: background-color, color, outline-offset, transform; + transition-property: background-color, color, outline-offset, scale; transition-duration: 150ms; transition-timing-function: ease-out; cursor: pointer; @@ -58,7 +58,7 @@ } &:active { - transform: scale(0.9); + scale: 0.9; } & .media-icon { diff --git a/packages/skins/src/default/css/components/captions.css b/packages/skins/src/default/css/components/captions.css index 6d69862e..4b5dfa59 100644 --- a/packages/skins/src/default/css/components/captions.css +++ b/packages/skins/src/default/css/components/captions.css @@ -3,31 +3,20 @@ ========================================================================== */ .media-default-skin { - --media-caption-track-duration: 150ms; - --media-caption-track-delay: 600ms; + --media-caption-track-duration: var(--media-controls-transition-duration); + --media-caption-track-delay: calc(var(--media-controls-transition-delay) + 25ms); --media-caption-track-y: -0.5rem; &:has(.media-controls[data-visible]) { - --media-caption-track-delay: 25ms; --media-caption-track-y: -3.5rem; } - - @media (prefers-reduced-motion: reduce) { - --media-caption-track-duration: 50ms; - } } .media-default-skin video::-webkit-media-text-track-container { - /* NOTE: The delay must account for the controls delay/duration */ - transition: transform var(--media-caption-track-duration) ease-out; + transition: translate var(--media-caption-track-duration) ease-out; transition-delay: var(--media-caption-track-delay); - transform: translateY(var(--media-caption-track-y)) scale(0.98); + translate: 0 var(--media-caption-track-y); + scale: 0.98; z-index: 1; font-family: inherit; } - -@media (prefers-reduced-motion: reduce) { - .media-default-skin video::-webkit-media-text-track-container { - transition-duration: 50ms; - } -} diff --git a/packages/skins/src/default/css/components/error.css b/packages/skins/src/default/css/components/error.css index 286f5fa1..b21d9c10 100644 --- a/packages/skins/src/default/css/components/error.css +++ b/packages/skins/src/default/css/components/error.css @@ -20,7 +20,7 @@ border-radius: 1.75rem; color: oklch(1 0 0); font-size: 0.875rem; - transition-property: opacity, transform; + transition-property: opacity, scale; transition-duration: 500ms; transition-delay: 100ms; transition-timing-function: linear( @@ -46,7 +46,7 @@ .media-default-skin .media-error[data-starting-style] .media-error__dialog, .media-default-skin .media-error[data-ending-style] .media-error__dialog { opacity: 0; - transform: scale(0.5); + scale: 0.5; } .media-default-skin .media-error__content { @@ -63,6 +63,7 @@ .media-default-skin .media-error__description { opacity: 0.7; + overflow-wrap: anywhere; } .media-default-skin .media-error__actions { diff --git a/packages/skins/src/default/css/components/popup.css b/packages/skins/src/default/css/components/popup.css index 6f667888..25581c39 100644 --- a/packages/skins/src/default/css/components/popup.css +++ b/packages/skins/src/default/css/components/popup.css @@ -8,13 +8,13 @@ border: 0; color: inherit; overflow: visible; - transition-property: transform, scale, opacity, filter; + transition-property: scale, opacity, filter; transition-duration: 150ms; &[data-starting-style], &[data-ending-style] { opacity: 0; - transform: scale(0.5); + scale: 0.5; filter: blur(8px); } diff --git a/packages/skins/src/default/css/components/preview.css b/packages/skins/src/default/css/components/preview.css index 2e1cfbdd..e2f141ec 100644 --- a/packages/skins/src/default/css/components/preview.css +++ b/packages/skins/src/default/css/components/preview.css @@ -36,7 +36,7 @@ position: absolute; top: 50%; left: 50%; - transform: translate(-50%, -50%); + translate: -50% -50%; opacity: 0; } diff --git a/packages/skins/src/default/css/components/slider.css b/packages/skins/src/default/css/components/slider.css index f767d126..0bc70f5e 100644 --- a/packages/skins/src/default/css/components/slider.css +++ b/packages/skins/src/default/css/components/slider.css @@ -47,7 +47,7 @@ .media-default-skin .media-slider__thumb { z-index: 10; position: absolute; - transform: translate(-50%, -50%); + translate: -50% -50%; width: 0.625rem; height: 0.625rem; background-color: currentColor; diff --git a/packages/skins/src/default/css/video.css b/packages/skins/src/default/css/video.css index 586b4357..24e51278 100644 --- a/packages/skins/src/default/css/video.css +++ b/packages/skins/src/default/css/video.css @@ -29,11 +29,27 @@ --media-surface-shadow-color: oklch(0 0 0 / 0.15); --media-surface-backdrop-filter: blur(16px) saturate(1.5); --media-video-border-radius: var(--media-border-radius, 2rem); + --media-controls-transition-duration: 100ms; + --media-controls-transition-delay: 0ms; @media (prefers-color-scheme: dark) { --media-border-color: oklch(1 0 0 / 0.1); } + &:has(.media-controls:not([data-visible])) { + /* Slight delay to hide controls on non-touch devices after interaction */ + @media (pointer: fine) { + --media-controls-transition-delay: 500ms; + --media-controls-transition-duration: 300ms; + } + @media (pointer: coarse) { + --media-controls-transition-duration: 150ms; + } + @media (prefers-reduced-motion: reduce) { + --media-controls-transition-duration: 100ms; + } + } + /* Inner border ring */ &::after { content: ""; @@ -60,41 +76,45 @@ inset-inline: 0.75rem; z-index: 10; color: var(--media-color-primary, oklch(1 0 0)); - will-change: scale, transform, filter, opacity; transition-timing-function: ease-out; + transition-duration: var(--media-controls-transition-duration); + transition-delay: var(--media-controls-transition-delay); transform-origin: bottom; @media (pointer: fine) { - transition-property: scale, transform, filter, opacity; - transition-duration: 100ms; - transition-delay: 0ms; + will-change: scale, filter, opacity; + transition-property: scale, filter, opacity; + } + + @media (pointer: coarse) { + will-change: scale, opacity; + transition-property: scale, opacity; } &:not([data-visible]) { opacity: 0; pointer-events: none; scale: 0.9; - filter: blur(8px); @media (pointer: fine) { - transition-duration: 300ms; - transition-delay: 500ms; + filter: blur(8px); @media (prefers-reduced-motion: reduce) { - transition-duration: 100ms; + filter: blur(0); } } @media (prefers-reduced-motion: reduce) { scale: 1; - filter: blur(0); } } } /* Hide cursor when controls are hidden in fullscreen */ -.media-default-skin--video:fullscreen:has(.media-controls:not([data-visible])) { - cursor: none; +@media (pointer: fine) { + .media-default-skin--video:fullscreen:has(.media-controls:not([data-visible])) { + cursor: none; + } } /* ========================================================================== @@ -117,6 +137,7 @@ transition-property: scale, opacity, filter; transition-duration: 150ms; transform-origin: bottom; + pointer-events: none; & .media-preview__thumbnail { max-width: 11rem; diff --git a/packages/skins/src/default/tailwind/components/error.ts b/packages/skins/src/default/tailwind/components/error.ts index b2255d48..0d77c79f 100644 --- a/packages/skins/src/default/tailwind/components/error.ts +++ b/packages/skins/src/default/tailwind/components/error.ts @@ -14,6 +14,6 @@ export const error = { ), content: 'flex flex-col gap-2 px-2 pt-2 pb-1.5', title: 'font-semibold leading-tight', - description: 'opacity-70', + description: 'opacity-70 wrap-anywhere', actions: 'flex gap-2 *:flex-1', }; diff --git a/packages/skins/src/default/tailwind/video.tailwind.ts b/packages/skins/src/default/tailwind/video.tailwind.ts index 4a6bb0f6..7b959c7c 100644 --- a/packages/skins/src/default/tailwind/video.tailwind.ts +++ b/packages/skins/src/default/tailwind/video.tailwind.ts @@ -27,6 +27,12 @@ export const root = (isShadowDOM: boolean) => !isShadowDOM, }, '[--media-video-border-radius:var(--media-border-radius,2rem)]', + '[--media-controls-transition-duration:100ms]', + '[--media-controls-transition-delay:0ms]', + '[@media(pointer:fine)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-delay:500ms]', + '[@media(pointer:fine)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:300ms]', + '[@media(pointer:coarse)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:150ms]', + 'motion-reduce:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:100ms]', // Poster image '[&>img]:absolute [&>img]:inset-0 [&>img]:w-full [&>img]:h-full [&>img]:rounded-[inherit]', '[&>img]:[object-fit:var(--media-object-fit,contain)] [&>img]:[object-position:var(--media-object-position,center)] [&>img]:pointer-events-none', @@ -34,15 +40,13 @@ export const root = (isShadowDOM: boolean) => '[&>img:not([data-visible])]:opacity-0', // Caption track CSS variables (consumed by the native caption bridge in light DOM) '[--media-caption-track-y:-0.5rem]', - '[--media-caption-track-delay:600ms]', - '[--media-caption-track-duration:150ms]', - 'motion-reduce:[--media-caption-track-duration:50ms]', - 'has-[[data-controls][data-visible]]:[--media-caption-track-delay:25ms]', + '[--media-caption-track-delay:calc(var(--media-controls-transition-delay)_+_25ms)]', + '[--media-caption-track-duration:var(--media-controls-transition-duration)]', 'has-[[data-controls][data-visible]]:[--media-caption-track-y:-3.5rem]', // Native caption track container !isShadowDOM ? [ - '[&_video::-webkit-media-text-track-container]:transition-transform', + '[&_video::-webkit-media-text-track-container]:transition-[translate]', '[&_video::-webkit-media-text-track-container]:duration-(--media-caption-track-duration)', '[&_video::-webkit-media-text-track-container]:ease-out', '[&_video::-webkit-media-text-track-container]:delay-(--media-caption-track-delay)', @@ -88,20 +92,17 @@ export const controls = cn( // Position 'absolute bottom-3 inset-x-3', '[color:var(--media-color-primary,oklch(1_0_0))] z-10', - // Transitions (fine pointer only — instant toggle on touch to avoid dead-zone taps) - 'will-change-[scale,transform,filter,opacity]', - '[@media(pointer:fine)]:transition-[scale,transform,filter,opacity]', 'ease-out origin-bottom', - '[@media(pointer:fine)]:delay-0 [@media(pointer:fine)]:duration-100', + 'duration-(--media-controls-transition-duration)', + 'delay-(--media-controls-transition-delay)', + '[@media(pointer:fine)]:will-change-[scale,filter,opacity]', + '[@media(pointer:fine)]:transition-[scale,filter,opacity]', + '[@media(pointer:coarse)]:will-change-[scale,opacity]', + '[@media(pointer:coarse)]:transition-[scale,opacity]', // Hidden state 'not-data-visible:pointer-events-none not-data-visible:opacity-0', - 'not-data-visible:blur-sm not-data-visible:scale-90', - '[@media(pointer:fine)]:not-data-visible:delay-500', - '[@media(pointer:fine)]:not-data-visible:duration-300', - // Reduced motion + hidden - '[@media(pointer:fine)]:motion-reduce:not-data-visible:duration-100', - 'motion-reduce:not-data-visible:blur-none', - 'motion-reduce:not-data-visible:scale-100' + 'motion-safe:not-data-visible:scale-90', + '[@media(pointer:fine)]:motion-safe:not-data-visible:blur-sm' ); /* ========================================================================== diff --git a/packages/skins/src/minimal/css/components/buttons.css b/packages/skins/src/minimal/css/components/buttons.css index 378a1078..15f4fc6d 100644 --- a/packages/skins/src/minimal/css/components/buttons.css +++ b/packages/skins/src/minimal/css/components/buttons.css @@ -32,7 +32,7 @@ font-weight: 500; text-align: center; text-shadow: inherit; - transition-property: background-color, color, outline-offset, transform; + transition-property: background-color, color, outline-offset, scale; transition-duration: 150ms; transition-timing-function: ease-out; cursor: pointer; @@ -72,7 +72,7 @@ } &:active { - transform: scale(0.9); + scale: 0.9; } & .media-icon { diff --git a/packages/skins/src/minimal/css/components/captions.css b/packages/skins/src/minimal/css/components/captions.css index b44f09d0..a092ac7c 100644 --- a/packages/skins/src/minimal/css/components/captions.css +++ b/packages/skins/src/minimal/css/components/captions.css @@ -3,25 +3,20 @@ ========================================================================== */ .media-minimal-skin { - --media-caption-track-duration: 150ms; - --media-caption-track-delay: 600ms; + --media-caption-track-duration: var(--media-controls-transition-duration); + --media-caption-track-delay: calc(var(--media-controls-transition-delay) + 25ms); --media-caption-track-y: -0.5rem; &:has(.media-controls[data-visible]) { - --media-caption-track-delay: 25ms; --media-caption-track-y: -3rem; } - - @media (prefers-reduced-motion: reduce) { - --media-caption-track-duration: 50ms; - } } .media-minimal-skin video::-webkit-media-text-track-container { - /* NOTE: The delay must account for the controls delay/duration */ - transition: transform var(--media-caption-track-duration) ease-out; + transition: translate var(--media-caption-track-duration) ease-out; transition-delay: var(--media-caption-track-delay); - transform: translateY(var(--media-caption-track-y)) scale(0.98); + translate: 0 var(--media-caption-track-y); + scale: 0.98; z-index: 1; font-family: inherit; } diff --git a/packages/skins/src/minimal/css/components/error.css b/packages/skins/src/minimal/css/components/error.css index 00d86001..7a2c5556 100644 --- a/packages/skins/src/minimal/css/components/error.css +++ b/packages/skins/src/minimal/css/components/error.css @@ -21,7 +21,7 @@ color: oklch(1 0 0); font-size: 0.875rem; text-shadow: 0 1px 0 oklch(0 0 0 / 0.5); - transition-property: opacity, transform; + transition-property: opacity, scale; transition-duration: 500ms; transition-delay: 100ms; transition-timing-function: linear( @@ -47,7 +47,7 @@ .media-minimal-skin .media-error[data-starting-style] .media-error__dialog, .media-minimal-skin .media-error[data-ending-style] .media-error__dialog { opacity: 0; - transform: scale(0.5); + scale: 0.5; } .media-minimal-skin .media-error__content { @@ -64,6 +64,7 @@ .media-minimal-skin .media-error__description { opacity: 0.7; + overflow-wrap: anywhere; } .media-minimal-skin .media-error__actions { diff --git a/packages/skins/src/minimal/css/components/popup.css b/packages/skins/src/minimal/css/components/popup.css index 6145f885..37047917 100644 --- a/packages/skins/src/minimal/css/components/popup.css +++ b/packages/skins/src/minimal/css/components/popup.css @@ -8,13 +8,13 @@ border: 0; color: inherit; overflow: visible; - transition-property: transform, scale, opacity, filter; + transition-property: scale, opacity, filter; transition-duration: 150ms; &[data-starting-style], &[data-ending-style] { opacity: 0; - transform: scale(0.5); + scale: 0.5; filter: blur(8px); } diff --git a/packages/skins/src/minimal/css/components/preview.css b/packages/skins/src/minimal/css/components/preview.css index ac1618f8..7c21e59e 100644 --- a/packages/skins/src/minimal/css/components/preview.css +++ b/packages/skins/src/minimal/css/components/preview.css @@ -27,7 +27,7 @@ position: absolute; top: 50%; left: 50%; - transform: translate(-50%, -50%); + translate: -50% -50%; opacity: 0; } diff --git a/packages/skins/src/minimal/css/components/slider.css b/packages/skins/src/minimal/css/components/slider.css index 294c76b4..37e8c284 100644 --- a/packages/skins/src/minimal/css/components/slider.css +++ b/packages/skins/src/minimal/css/components/slider.css @@ -47,7 +47,7 @@ /* Thumb */ .media-minimal-skin .media-slider__thumb { position: absolute; - transform: translate(-50%, -50%); + translate: -50% -50%; z-index: 10; width: 0.75rem; height: 0.75rem; diff --git a/packages/skins/src/minimal/css/video.css b/packages/skins/src/minimal/css/video.css index 176294dd..4bf6388a 100644 --- a/packages/skins/src/minimal/css/video.css +++ b/packages/skins/src/minimal/css/video.css @@ -23,11 +23,27 @@ background: oklch(0 0 0); --media-border-color: oklch(0 0 0 / 0.15); --media-video-border-radius: var(--media-border-radius, 0.75rem); + --media-controls-transition-duration: 100ms; + --media-controls-transition-delay: 0ms; @media (prefers-color-scheme: dark) { --media-border-color: oklch(1 0 0 / 0.15); } + &:has(.media-controls:not([data-visible])) { + /* Slight delay to hide controls on non-touch devices after interaction */ + @media (pointer: fine) { + --media-controls-transition-delay: 500ms; + --media-controls-transition-duration: 300ms; + } + @media (pointer: coarse) { + --media-controls-transition-duration: 150ms; + } + @media (prefers-reduced-motion: reduce) { + --media-controls-transition-duration: 100ms; + } + } + /* Inner border ring */ &::after { content: ""; @@ -57,37 +73,38 @@ gap: 0.5rem; padding: 2rem 0.375rem 0.375rem 0.375rem; color: var(--media-color-primary, oklch(1 0 0)); + transition-duration: var(--media-controls-transition-duration); + transition-delay: var(--media-controls-transition-delay); + transition-timing-function: ease-out; @media (pointer: fine) { - will-change: transform, filter, opacity; - transition-property: transform, filter, opacity; - transition-duration: 75ms; - transition-delay: 0ms; - transition-timing-function: ease-out; + will-change: translate, filter, opacity; + transition-property: translate, filter, opacity; } - @container media-root (width > 40rem) { - gap: 0.875rem; - padding: 2.5rem 0.75rem 0.75rem 0.75rem; + @media (pointer: coarse) { + will-change: translate, opacity; + transition-property: translate, opacity; } &:not([data-visible]) { opacity: 0; pointer-events: none; + translate: 0 100%; @media (pointer: fine) { - transform: translateY(100%); filter: blur(8px); - transition-duration: 500ms; - transition-delay: 500ms; - - @media (prefers-reduced-motion: reduce) { - scale: 1; - transform: translateY(0); - filter: blur(0); - transition-duration: 100ms; - } } + + @media (prefers-reduced-motion: reduce) { + translate: 0 0; + filter: blur(0); + } + } + + @container media-root (width > 40rem) { + gap: 0.875rem; + padding: 2.5rem 0.75rem 0.75rem 0.75rem; } } diff --git a/packages/skins/src/minimal/tailwind/components/error.ts b/packages/skins/src/minimal/tailwind/components/error.ts index 30144c0b..37252842 100644 --- a/packages/skins/src/minimal/tailwind/components/error.ts +++ b/packages/skins/src/minimal/tailwind/components/error.ts @@ -15,6 +15,6 @@ export const error = { ), content: 'flex flex-col gap-2 py-1.5', title: 'font-semibold leading-tight', - description: 'opacity-70', + description: 'opacity-70 wrap-anywhere', actions: 'flex gap-2 *:flex-1', }; diff --git a/packages/skins/src/minimal/tailwind/video.tailwind.ts b/packages/skins/src/minimal/tailwind/video.tailwind.ts index e8a9b695..b1423a41 100644 --- a/packages/skins/src/minimal/tailwind/video.tailwind.ts +++ b/packages/skins/src/minimal/tailwind/video.tailwind.ts @@ -25,6 +25,12 @@ export const root = (isShadowDOM: boolean) => !isShadowDOM, }, '[--media-video-border-radius:var(--media-border-radius,0.75rem)]', + '[--media-controls-transition-duration:100ms]', + '[--media-controls-transition-delay:0ms]', + '[@media(pointer:fine)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-delay:500ms]', + '[@media(pointer:fine)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:300ms]', + '[@media(pointer:coarse)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:150ms]', + 'motion-reduce:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:100ms]', // Poster image '[&>img]:absolute [&>img]:inset-0 [&>img]:w-full [&>img]:h-full [&>img]:rounded-[inherit]', '[&>img]:[object-fit:var(--media-object-fit,contain)] [&>img]:[object-position:var(--media-object-position,center)] [&>img]:pointer-events-none', @@ -32,15 +38,13 @@ export const root = (isShadowDOM: boolean) => '[&>img:not([data-visible])]:opacity-0', // Caption track CSS variables (consumed by the native caption bridge in light DOM) '[--media-caption-track-y:-0.5rem]', - '[--media-caption-track-delay:600ms]', - '[--media-caption-track-duration:150ms]', - 'motion-reduce:[--media-caption-track-duration:50ms]', - 'has-[[data-controls][data-visible]]:[--media-caption-track-delay:25ms]', - 'has-[[data-controls][data-visible]]:[--media-caption-track-y:-3.5rem]', + '[--media-caption-track-delay:calc(var(--media-controls-transition-delay)_+_25ms)]', + '[--media-caption-track-duration:var(--media-controls-transition-duration)]', + 'has-[[data-controls][data-visible]]:[--media-caption-track-y:-3rem]', // Native caption track container !isShadowDOM ? [ - '[&_video::-webkit-media-text-track-container]:transition-transform', + '[&_video::-webkit-media-text-track-container]:transition-[translate]', '[&_video::-webkit-media-text-track-container]:duration-(--media-caption-track-duration)', '[&_video::-webkit-media-text-track-container]:ease-out', '[&_video::-webkit-media-text-track-container]:delay-(--media-caption-track-delay)', @@ -68,21 +72,17 @@ export const controls = cn( 'absolute bottom-0 inset-x-0', 'pt-8 px-1.5 pb-1.5 gap-2', '[color:var(--media-color-primary,oklch(1_0_0))] z-10', - // Transitions (fine pointer only — instant toggle on touch to avoid dead-zone taps) - 'will-change-[translate,filter,opacity]', - '[@media(pointer:fine)]:transition-[translate,filter,opacity]', 'ease-out', - '[@media(pointer:fine)]:delay-0 [@media(pointer:fine)]:duration-75', + 'duration-(--media-controls-transition-duration)', + 'delay-(--media-controls-transition-delay)', + '[@media(pointer:fine)]:will-change-[translate,filter,opacity]', + '[@media(pointer:fine)]:transition-[translate,filter,opacity]', + '[@media(pointer:coarse)]:will-change-[translate,opacity]', + '[@media(pointer:coarse)]:transition-[translate,opacity]', // Hidden state 'not-data-visible:opacity-0 not-data-visible:pointer-events-none', - 'not-data-visible:translate-y-full not-data-visible:blur-sm', - '[@media(pointer:fine)]:not-data-visible:delay-500', - '[@media(pointer:fine)]:not-data-visible:duration-500', - // Reduced motion + hidden - '[@media(pointer:fine)]:motion-reduce:not-data-visible:duration-100', - 'motion-reduce:not-data-visible:translate-y-0', - 'motion-reduce:not-data-visible:blur-none', - 'motion-reduce:not-data-visible:scale-100', + 'motion-safe:not-data-visible:translate-y-full', + '[@media(pointer:fine)]:motion-safe:not-data-visible:blur-sm', // Wider container '@sm/media-root:pt-10 @sm/media-root:px-3 @sm/media-root:pb-3', '@sm/media-root:gap-3.5'