Your calm window into the Atmosphere. morgen.blue
rss atproto
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

revert(ui): drop welcome→login view transition

The View Transition API uses bitmap snapshots, which can't fake "the same
element" morphing across very different aspect ratios — corners and inset
shadow visibly distort and the cross-fade reads as an overlay. Removing it
in favour of a plain navigation with a small fade-in on the login form.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+7 -79
-40
resources/css/app.css
··· 196 196 var(--color-sand-brown) 100% 197 197 ); 198 198 } 199 - 200 - ::view-transition-group(window), 201 - ::view-transition-old(window), 202 - ::view-transition-new(window), 203 - ::view-transition-group(brand-logo), 204 - ::view-transition-old(brand-logo), 205 - ::view-transition-new(brand-logo) { 206 - animation-duration: 420ms; 207 - animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1); 208 - } 209 - 210 - ::view-transition-new(login-form) { 211 - animation: morgenblau-fade-in 200ms ease-out 220ms both; 212 - } 213 - ::view-transition-old(login-form) { 214 - animation: morgenblau-fade-out 140ms ease-out both; 215 - } 216 - @keyframes morgenblau-fade-in { 217 - from { 218 - opacity: 0; 219 - transform: translateY(4px); 220 - } 221 - to { 222 - opacity: 1; 223 - transform: none; 224 - } 225 - } 226 - @keyframes morgenblau-fade-out { 227 - to { 228 - opacity: 0; 229 - } 230 - } 231 - 232 - @media (prefers-reduced-motion: reduce) { 233 - ::view-transition-group(*), 234 - ::view-transition-old(*), 235 - ::view-transition-new(*) { 236 - animation: none !important; 237 - } 238 - }
-1
resources/js/components/window.tsx
··· 22 22 return ( 23 23 <div 24 24 data-slot="window" 25 - style={{ viewTransitionName: 'window' }} 26 25 className={cn( 27 26 'overflow-hidden rounded-tl-[4rem] rounded-tr-[4rem] rounded-br-[0.5rem] rounded-bl-[0.5rem]', 28 27 VARIANT_STYLES[variant],
+1 -4
resources/js/layouts/auth/auth-login-layout.tsx
··· 12 12 variant="sunrise" 13 13 className="flex flex-1 items-center justify-center text-white" 14 14 > 15 - <AppLogoIcon 16 - className="size-16" 17 - style={{ viewTransitionName: 'brand-logo' }} 18 - /> 15 + <AppLogoIcon className="size-16" /> 19 16 </Window> 20 17 </div> 21 18 );
-24
resources/js/lib/view-transition.ts
··· 1 - import { router } from '@inertiajs/react'; 2 - 3 - export function visitWithTransition(href: string) { 4 - const prefersReduced = 5 - typeof window !== 'undefined' && 6 - window.matchMedia('(prefers-reduced-motion: reduce)').matches; 7 - 8 - if ( 9 - typeof document === 'undefined' || 10 - !document.startViewTransition || 11 - prefersReduced 12 - ) { 13 - router.visit(href); 14 - 15 - return; 16 - } 17 - 18 - document.startViewTransition( 19 - () => 20 - new Promise<void>((resolve) => { 21 - router.visit(href, { onFinish: () => resolve() }); 22 - }), 23 - ); 24 - }
+1 -1
resources/js/pages/auth/login.tsx
··· 17 17 const [pending, setPending] = useState(false); 18 18 19 19 return ( 20 - <div style={{ viewTransitionName: 'login-form' }} className="space-y-8"> 20 + <div className="space-y-8 motion-safe:animate-in motion-safe:duration-200 motion-safe:fade-in"> 21 21 <Head title="Sign in" /> 22 22 23 23 <header className="space-y-1">
+5 -9
resources/js/pages/welcome.tsx
··· 1 + import { Head, router, usePage } from '@inertiajs/react'; 2 + import { useEffect } from 'react'; 1 3 import AppLogoIcon from '@/components/app-logo-icon'; 2 4 import { Button } from '@/components/ui/button'; 3 5 import { Window } from '@/components/window'; 4 - import { visitWithTransition } from '@/lib/view-transition'; 5 6 import { dashboard, login } from '@/routes'; 6 - import { Head, usePage } from '@inertiajs/react'; 7 - import { useEffect } from 'react'; 8 7 9 8 export default function Welcome() { 10 9 const { auth } = usePage().props; ··· 26 25 } 27 26 28 27 event.preventDefault(); 29 - visitWithTransition(auth.user ? dashboard().url : login().url); 28 + router.visit(auth.user ? dashboard().url : login().url); 30 29 }; 31 30 window.addEventListener('keydown', handler); 32 31 ··· 42 41 className="flex min-h-[calc(100svh-3rem)] items-center justify-center" 43 42 > 44 43 <div className="flex flex-col items-center gap-8 px-6 text-center text-white"> 45 - <AppLogoIcon 46 - className="size-16" 47 - style={{ viewTransitionName: 'brand-logo' }} 48 - /> 44 + <AppLogoIcon className="size-16" /> 49 45 <div className="space-y-3"> 50 46 <h1>Morgenblau</h1> 51 47 <p className="max-w-xl text-base text-balance"> ··· 57 53 <Button 58 54 variant="ghost-on-gradient" 59 55 className="text-base" 60 - onClick={() => visitWithTransition(target)} 56 + onClick={() => router.visit(target)} 61 57 > 62 58 Begin 63 59 </Button>