diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f16cedb2..3b3f165e 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -6,6 +6,7 @@ import { ThemeProvider } from "@/components/ThemeProvider"; import { ThemeToggle } from "@/components/ThemeToggle"; import ScrollToTop from "@/components/ScrollToTop"; import BrandLogo from "@/components/BrandLogo"; +import SplashScreen from "@/components/SplashScreen"; export const metadata: Metadata = { title: "Reframe — Resize, trim, and export videos in your browser", @@ -75,6 +76,7 @@ export default function RootLayout({ Skip to main content +
{ + // Give the app a moment to load and display the splash screen + const fadeOutTimer = setTimeout(() => { + setIsFadingOut(true); + }, 1800); + + // Completely unmount after fade transition + const removeTimer = setTimeout(() => { + setIsVisible(false); + }, 2300); + + return () => { + clearTimeout(fadeOutTimer); + clearTimeout(removeTimer); + }; + }, []); + + // Avoid hydration mismatch by only rendering after mount + if (!isVisible) return null; + + return ( +
+
+ +

+ Reframe +

+
+
+ ); +} diff --git a/src/components/ThemeToggle.tsx b/src/components/ThemeToggle.tsx index 26464263..5f18baba 100644 --- a/src/components/ThemeToggle.tsx +++ b/src/components/ThemeToggle.tsx @@ -28,6 +28,16 @@ export function ThemeToggle() { ); } + if (!mounted) { + return ( + + ); + })} + + + {/* Brightness */}
diff --git a/src/components/VideoPreview.tsx b/src/components/VideoPreview.tsx index 7456ac89..89b9020c 100644 --- a/src/components/VideoPreview.tsx +++ b/src/components/VideoPreview.tsx @@ -234,6 +234,11 @@ export default function VideoPreview({ ref={videoRef} controls className={cn("w-full h-full object-contain transition-opacity duration-300", isLoading ? "opacity-0" : "opacity-100")} + style={{ + filter: recipe + ? `brightness(${1 + recipe.brightness}) contrast(${recipe.contrast}) saturate(${recipe.saturation})` + : undefined, + }} onLoadedData={() => setIsLoading(false)} playsInline muted={!recipe?.keepAudio}