diff --git a/apps/frontend/app/[locale]/page.tsx b/apps/frontend/app/[locale]/page.tsx
index 262c40c..895f078 100644
--- a/apps/frontend/app/[locale]/page.tsx
+++ b/apps/frontend/app/[locale]/page.tsx
@@ -27,6 +27,7 @@ import {
import { useTranslations, useLocale } from 'next-intl';
import { useAuth } from '@/lib/context/auth-context';
import { LandingHeader, LandingFooter } from '@/components/layout';
+import { DemoVideoModal } from '@/components/DemoVideoModal';
function AnimatedCounter({
end,
@@ -96,6 +97,7 @@ export default function LandingPage() {
const isHowInView = useInView(howRef, { once: true, amount: 0.2 });
const [billingYearly, setBillingYearly] = useState(false);
+ const [isDemoOpen, setIsDemoOpen] = useState(false);
const { scrollYProgress } = useScroll();
const backgroundY = useTransform(scrollYProgress, [0, 1], ['0%', '50%']);
@@ -374,26 +376,23 @@ export default function LandingPage() {
) : (
- <>
-
- {t('hero.ctaRegister')}
-
-
-
- {t('hero.ctaDemo')}
-
- >
+
+ {t('hero.ctaRegister')}
+
+
)}
+
@@ -1076,6 +1075,8 @@ export default function LandingPage() {
+
+ setIsDemoOpen(false)} />
);
}
diff --git a/apps/frontend/public/assets/videos/demo-xpeditis.mp4 b/apps/frontend/public/assets/videos/demo-xpeditis.mp4
new file mode 100644
index 0000000..8788246
Binary files /dev/null and b/apps/frontend/public/assets/videos/demo-xpeditis.mp4 differ
diff --git a/apps/frontend/public/assets/videos/demo-xpeditis.webm b/apps/frontend/public/assets/videos/demo-xpeditis.webm
new file mode 100644
index 0000000..3578c55
Binary files /dev/null and b/apps/frontend/public/assets/videos/demo-xpeditis.webm differ
diff --git a/apps/frontend/src/components/DemoVideoModal.tsx b/apps/frontend/src/components/DemoVideoModal.tsx
new file mode 100644
index 0000000..e6813d6
--- /dev/null
+++ b/apps/frontend/src/components/DemoVideoModal.tsx
@@ -0,0 +1,74 @@
+'use client';
+
+import { useEffect, useCallback } from 'react';
+import { createPortal } from 'react-dom';
+import { motion, AnimatePresence } from 'framer-motion';
+import { X } from 'lucide-react';
+
+interface DemoVideoModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+}
+
+export function DemoVideoModal({ isOpen, onClose }: DemoVideoModalProps) {
+ const handleKeyDown = useCallback(
+ (e: KeyboardEvent) => {
+ if (e.key === 'Escape') onClose();
+ },
+ [onClose]
+ );
+
+ useEffect(() => {
+ if (!isOpen) return;
+ document.addEventListener('keydown', handleKeyDown);
+ document.body.style.overflow = 'hidden';
+ return () => {
+ document.removeEventListener('keydown', handleKeyDown);
+ document.body.style.overflow = '';
+ };
+ }, [isOpen, handleKeyDown]);
+
+ if (typeof document === 'undefined') return null;
+
+ return createPortal(
+
+ {isOpen && (
+
+ e.stopPropagation()}
+ >
+
+
+
+
+
+
+ )}
+ ,
+ document.body
+ );
+}