diff --git a/src/app/globals.css b/src/app/globals.css index cc07b39..946c1c5 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1445,12 +1445,14 @@ h3 { } /* Fix 2: Task Hover Actions */ -.teuxdeux-task-item { +.teuxdeux-task-item, +.time-slot-task { /* Ensure positioning context for absolute actions if needed, though flex is used */ position: relative; } -.teuxdeux-task-item .task-actions { +.teuxdeux-task-item .task-actions, +.time-slot-task .task-actions { display: flex; align-items: center; gap: 2px; @@ -1461,7 +1463,8 @@ h3 { padding-left: 8px; } -.teuxdeux-task-item:hover .task-actions { +.teuxdeux-task-item:hover .task-actions, +.time-slot-task:hover .task-actions { opacity: 1; } @@ -1563,4 +1566,71 @@ h3 { .teuxdeux-btn-primary:hover { background: #333; +} + +/* --- VIEW TRANSITION ANIMATION (TeuxDeux-like) --- */ + +.teuxdeux-days-grid { + view-transition-name: week-grid; +} + +@keyframes slideOutToLeft { + to { + transform: translateX(-100%); + opacity: 0.8; + } +} + +@keyframes slideInFromRight { + from { + transform: translateX(100%); + } + + to { + transform: translateX(0); + } +} + +@keyframes slideOutToRight { + to { + transform: translateX(100%); + opacity: 0.8; + } +} + +@keyframes slideInFromLeft { + from { + transform: translateX(-100%); + } + + to { + transform: translateX(0); + } +} + +::view-transition-group(week-grid) { + animation-duration: 0.5s; + animation-timing-function: ease-in-out; +} + +/* Next Week: Old slides Left, New enters from Right */ +[data-transition-direction="next"]::view-transition-old(week-grid) { + animation: slideOutToLeft 0.5s ease-in-out both; + mix-blend-mode: normal; +} + +[data-transition-direction="next"]::view-transition-new(week-grid) { + animation: slideInFromRight 0.5s ease-in-out both; + mix-blend-mode: normal; +} + +/* Prev Week: Old slides Right, New enters from Left */ +[data-transition-direction="prev"]::view-transition-old(week-grid) { + animation: slideOutToRight 0.5s ease-in-out both; + mix-blend-mode: normal; +} + +[data-transition-direction="prev"]::view-transition-new(week-grid) { + animation: slideInFromLeft 0.5s ease-in-out both; + mix-blend-mode: normal; } \ No newline at end of file diff --git a/src/components/TeuxDeuxView.tsx b/src/components/TeuxDeuxView.tsx index a97a78e..7026855 100644 --- a/src/components/TeuxDeuxView.tsx +++ b/src/components/TeuxDeuxView.tsx @@ -203,11 +203,16 @@ export default function TeuxDeuxView() { // Navigation handlers with proper slide animation // Simplified: Immediate state update with slide-in animation to prevent blank flash const navigate = (newDate: Date, direction: 'left' | 'right') => { - setCurrentWeekStart(newDate); - setSlideDirection(direction === 'left' ? 'in-left' : 'in-right'); - - // Clear animation after it completes - setTimeout(() => setSlideDirection(null), 500); + // Use View Transition API for smooth 'TeuxDeux' slide (simultaneous old/new) + if (typeof document !== 'undefined' && 'startViewTransition' in document) { + document.documentElement.dataset.transitionDirection = direction === 'left' ? 'next' : 'prev'; + (document as any).startViewTransition(() => { + setCurrentWeekStart(newDate); + setSlideDirection(null); + }); + } else { + setCurrentWeekStart(newDate); + } }; const goToPrevWeek = () => navigate(new Date(currentWeekStart.getTime() - 7 * 24 * 60 * 60 * 1000), 'right'); @@ -565,7 +570,15 @@ export default function TeuxDeuxView() { toggleTask(task.id); }} > - {task.title} + {task.title} +