slide animation
CI/CD Pipeline / Build and Push PocketBase Docker Image (push) Successful in 13s
CI/CD Pipeline / i18n Catalog Check (push) Successful in 31s
CI/CD Pipeline / Build and Push App Docker Image (push) Successful in 3m25s
CI/CD Pipeline / Deploy to Kubernetes (push) Successful in 8m29s

This commit is contained in:
2026-09-11 08:32:42 -07:00
parent c4a9d47180
commit 9ed3f7169e
13 changed files with 120 additions and 65 deletions
+72 -28
View File
@@ -50,62 +50,97 @@ textarea,
transform: scale(0.90) translateY(-4px);
}
/* keep the page tappable mid-transition (rapid tab switching) */
::view-transition {
pointer-events: none;
}
/* Theme texture overlays (scanlines, rays, grain) paint ABOVE all content; a
real element with its own transition group keeps them on top and static
mid-transition — a body::before overlay sinks into the root snapshot and
blinks off the content for the duration of every transition. */
.flxn-theme-overlay {
position: fixed;
pointer-events: none;
view-transition-name: theme-overlay;
}
/* Root (wallpaper + tab bar) is identical across routes — swap it instantly
instead of crossfading; Safari's plus-lighter blend of the pair dims the
whole backdrop mid-fade. Same explicit-state treatment for the header and
theme overlay. */
::view-transition-old(root),
::view-transition-new(root),
::view-transition-old(page),
::view-transition-new(page),
::view-transition-old(app-header),
::view-transition-new(app-header) {
::view-transition-old(theme-overlay) {
animation: none;
opacity: 0;
}
::view-transition-new(root),
::view-transition-new(app-header),
::view-transition-new(theme-overlay) {
animation: none;
opacity: 1;
mix-blend-mode: normal;
}
::view-transition-image-pair(root),
::view-transition-image-pair(app-header),
::view-transition-image-pair(theme-overlay),
::view-transition-image-pair(page) {
isolation: auto;
}
::view-transition-old(page),
::view-transition-new(page) {
animation-duration: 180ms;
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
mix-blend-mode: normal;
}
/* content pushes edge-to-edge over the static theme background; panes stay
transparent so the background never appears to move. The header is not in
these rules on purpose: it crossfades in place (its own group's default) —
sliding its chrome reads as a band appearing on continuous-bg themes */
html[data-nav-direction="forward"]::view-transition-old(page) {
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-under-out;
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-out-left;
}
html[data-nav-direction="forward"]::view-transition-new(page) {
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-over-in;
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-in-right;
}
html[data-nav-direction="back"]::view-transition-old(page) {
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-over-out;
z-index: 1;
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-out-right;
}
html[data-nav-direction="back"]::view-transition-new(page) {
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-under-in;
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-in-left;
}
/* a header appearing or disappearing rides with its page instead of popping;
opacity overrides the pinned instant-swap defaults above */
html[data-nav-direction="forward"][data-header-vt="exit"]::view-transition-old(app-header) {
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-header-out;
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-out-left;
opacity: 1;
}
html[data-nav-direction="back"][data-header-vt="exit"]::view-transition-old(app-header) {
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-over-out;
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-out-right;
opacity: 1;
}
html[data-nav-direction="forward"][data-header-vt="enter"]::view-transition-new(app-header) {
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-over-in;
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-in-right;
}
html[data-nav-direction="back"][data-header-vt="enter"]::view-transition-new(app-header) {
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-header-in;
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-in-left;
}
@keyframes flxn-page-over-in {
@keyframes flxn-page-out-left {
to { transform: translateX(-100%); }
}
@keyframes flxn-page-in-right {
from { transform: translateX(100%); }
}
@keyframes flxn-page-over-out {
@keyframes flxn-page-out-right {
to { transform: translateX(100%); }
}
@keyframes flxn-page-under-out {
to { transform: translateX(-25%); opacity: 0.8; }
}
@keyframes flxn-page-under-in {
from { transform: translateX(-25%); opacity: 0.8; }
}
@keyframes flxn-header-out {
45% { opacity: 0; }
to { transform: translateX(-25%); opacity: 0; }
}
@keyframes flxn-header-in {
from { transform: translateX(-25%); opacity: 0; }
@keyframes flxn-page-in-left {
from { transform: translateX(-100%); }
}
@keyframes flxn-vt-fade-out {
@@ -130,6 +165,15 @@ html[data-nav-direction="back"][data-header-vt="enter"]::view-transition-new(app
animation: 120ms ease both flxn-vt-fade-in !important;
}
::view-transition-old(root),
::view-transition-old(app-header),
::view-transition-old(theme-overlay),
::view-transition-new(root),
::view-transition-new(app-header),
::view-transition-new(theme-overlay) {
animation: none !important;
}
.app,
[data-drawer-level] {
transition: none;