Improve mobile swipe tabs with native scroll-snap

- Rewrite SwipeTabs to use CSS scroll-snap for smoother transitions
- Add GPU acceleration hints for fluid animations
- Use native scrolling behavior instead of manual touch handling
- Add swipe-tabs--snap and swipe-tabs--static variants
- Improve height transitions and layout containment
- Update dimension variables for better spacing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 17:08:50 +01:00
parent fc605f03c9
commit abd8f75efc
10 changed files with 552 additions and 112 deletions

View File

@@ -175,7 +175,7 @@ body {
/* Standard Section Title */
.section-title {
margin: 0 0 1rem 0;
margin: 0 0 var(--section-title-gap) 0;
font-size: 0.8rem;
font-weight: 600;
text-transform: uppercase;
@@ -185,7 +185,11 @@ body {
/* Standard Section Header */
.section-header {
margin-bottom: 1.5rem;
margin-bottom: var(--section-title-gap);
}
.section-header .section-title {
margin-bottom: 0;
}
/* Standard Page Section */
@@ -253,7 +257,7 @@ body {
flex: 1;
padding: var(--page-padding-y) var(--page-padding-x);
width: 100%;
max-width: 1600px;
max-width: var(--page-max-width);
margin: 0 auto;
}
@@ -267,7 +271,7 @@ body {
/* Admin tab content (for tabbed interfaces) */
.admin-tab-content {
padding: var(--page-padding-y) var(--page-padding-x);
max-width: 1600px;
max-width: var(--page-max-width);
margin: 0 auto;
width: 100%;
}
@@ -478,18 +482,96 @@ body {
/* ========== TAB CONTENT ANIMATIONS ========== */
/* Prevent layout shift when switching tabs */
.admin-tab-content {
.admin-tab-content:not(.swipe-tabs):not(.swipe-panel-content) {
display: grid;
grid-template-rows: 1fr;
transition: grid-template-rows 0.25s ease;
}
.admin-tab-content>div {
.admin-tab-content:not(.swipe-tabs):not(.swipe-panel-content)>div {
opacity: 0;
animation: tabFadeIn 0.25s ease forwards;
min-height: 0;
}
.admin-tab-swipe {
width: 100%;
max-width: none;
margin: 0;
}
/* Swipeable tab panels */
.swipe-tabs {
position: relative;
background: var(--color-bg-main);
touch-action: pan-y;
}
.swipe-tabs-track {
display: flex;
width: 100%;
}
.swipe-tabs-panel {
width: 100%;
min-height: 1px;
background: var(--color-bg-main);
}
.swipe-tabs--static {
overflow: hidden;
}
.swipe-tabs--static .swipe-tabs-panel {
flex: 0 0 100%;
overflow: hidden;
}
.swipe-tabs--snap {
overflow-x: auto;
overflow-y: hidden;
touch-action: pan-x pan-y;
scroll-snap-type: x mandatory;
overscroll-behavior-x: contain;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
-ms-overflow-style: none;
}
.swipe-tabs--snap::-webkit-scrollbar {
display: none;
}
.swipe-tabs--snap .swipe-tabs-panel {
flex: 0 0 100%;
overflow: hidden;
contain: paint;
scroll-snap-align: start;
scroll-snap-stop: always;
}
.swipe-tabs-panel-inner {
width: 100%;
}
.admin-tab-content.swipe-tabs {
display: block;
}
.admin-tab-content.swipe-tabs>div {
opacity: 1;
animation: none;
}
.swipe-panel-content {
display: block;
}
.swipe-panel-content>div {
opacity: 1;
animation: none;
}
@keyframes tabFadeIn {
0% {
opacity: 0;