Mobile-first: swipe groups, bottom nav, slide-out drawer, responsive
- Swipe left/right between groups with overlay animation - BottomNav: Tasks/Calendar/Chat/Settings (mobile only) - Header: slide-out drawer on mobile, full on desktop - GroupSelector: scroll-snap, auto-scroll active - TaskCard: compact mobile layout, swipe-to-complete - Safe area insets, 44px touch targets - react-swipeable for touch gestures Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,15 @@ select {
|
|||||||
font-size: 16px; /* Prevent zoom on iOS */
|
font-size: 16px; /* Prevent zoom on iOS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Touch targets - minimum 44px for accessibility */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
button,
|
||||||
|
a,
|
||||||
|
[role="button"] {
|
||||||
|
min-height: 44px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@layer utilities {
|
@layer utilities {
|
||||||
.scrollbar-hide {
|
.scrollbar-hide {
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
@@ -60,6 +69,38 @@ select {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Smooth scrolling with snap */
|
||||||
|
.snap-x {
|
||||||
|
scroll-snap-type: x mandatory;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
.snap-center {
|
||||||
|
scroll-snap-align: center;
|
||||||
|
}
|
||||||
|
.snap-mandatory {
|
||||||
|
scroll-snap-type: x mandatory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bottom navigation responsive */
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.bottom-nav {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.desktop-sidebar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 641px) {
|
||||||
|
.bottom-nav {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Safe area for notched devices */
|
||||||
|
.safe-area-bottom {
|
||||||
|
padding-bottom: env(safe-area-inset-bottom, 0px);
|
||||||
|
}
|
||||||
|
|
||||||
/* Smooth page transitions */
|
/* Smooth page transitions */
|
||||||
main {
|
main {
|
||||||
animation: fadeIn 0.15s ease-out;
|
animation: fadeIn 0.15s ease-out;
|
||||||
@@ -76,6 +117,112 @@ main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Slide-in animations for drawer */
|
||||||
|
@keyframes slideInRight {
|
||||||
|
from {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slideInRight {
|
||||||
|
animation: slideInRight 0.25s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Swipe overlay animations */
|
||||||
|
@keyframes slideOverlayLeft {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(40px) scale(0.9);
|
||||||
|
}
|
||||||
|
30% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0) scale(1);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0) scale(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-20px) scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideOverlayRight {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-40px) scale(0.9);
|
||||||
|
}
|
||||||
|
30% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0) scale(1);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0) scale(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(20px) scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slideOverlayLeft {
|
||||||
|
animation: slideOverlayLeft 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slideOverlayRight {
|
||||||
|
animation: slideOverlayRight 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Content slide animations for group switch */
|
||||||
|
@keyframes slideContentLeft {
|
||||||
|
0% {
|
||||||
|
opacity: 0.3;
|
||||||
|
transform: translateX(30px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideContentRight {
|
||||||
|
0% {
|
||||||
|
opacity: 0.3;
|
||||||
|
transform: translateX(-30px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slideContentLeft {
|
||||||
|
animation: slideContentLeft 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slideContentRight {
|
||||||
|
animation: slideContentRight 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fade-in for backdrop */
|
||||||
|
@keyframes fadeInBackdrop {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fadeIn {
|
||||||
|
animation: fadeInBackdrop 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mobile overscroll behavior */
|
/* Mobile overscroll behavior */
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
html {
|
html {
|
||||||
|
|||||||
Reference in New Issue
Block a user