-
-
+
+
Plateforme B2B de Fret Maritime #1 en Europe
@@ -369,7 +369,7 @@ export default function LandingPage() {
initial={{ opacity: 0, y: 20 }}
animate={isHeroInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.3 }}
- className="text-5xl lg:text-7xl font-bold text-white mb-6 leading-tight"
+ className="text-3xl sm:text-5xl lg:text-7xl font-bold text-white mb-4 sm:mb-6 leading-tight"
>
Réservez votre fret
@@ -382,7 +382,7 @@ export default function LandingPage() {
initial={{ opacity: 0, y: 20 }}
animate={isHeroInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.4 }}
- className="text-xl lg:text-2xl text-white/80 mb-12 max-w-3xl mx-auto leading-relaxed"
+ className="text-base sm:text-xl lg:text-2xl text-white/80 mb-8 sm:mb-12 max-w-3xl mx-auto leading-relaxed px-2"
>
Comparez les tarifs de 50+ compagnies maritimes, réservez en ligne et suivez vos
envois en temps réel.
@@ -392,14 +392,14 @@ export default function LandingPage() {
initial={{ opacity: 0, y: 20 }}
animate={isHeroInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.5 }}
- className="flex flex-col sm:flex-row items-center justify-center space-y-4 sm:space-y-0 sm:space-x-6 mb-12"
+ className="flex flex-col sm:flex-row items-center justify-center gap-3 sm:gap-6 mb-12 px-4 sm:px-0"
>
{isAuthenticated && user ? (
Accéder au tableau de bord
@@ -410,7 +410,7 @@ export default function LandingPage() {
href="/register"
target="_blank"
rel="noopener noreferrer"
- className="group px-8 py-4 bg-brand-turquoise text-white rounded-lg hover:bg-brand-turquoise/90 transition-all hover:shadow-2xl hover:scale-105 font-semibold text-lg w-full sm:w-auto flex items-center justify-center space-x-2"
+ className="group px-6 sm:px-8 py-3 sm:py-4 bg-brand-turquoise text-white rounded-lg hover:bg-brand-turquoise/90 transition-all hover:shadow-2xl hover:scale-105 font-semibold text-base sm:text-lg w-full sm:w-auto flex items-center justify-center space-x-2"
>
Créer un compte gratuit
@@ -419,7 +419,7 @@ export default function LandingPage() {
href="/login"
target="_blank"
rel="noopener noreferrer"
- className="px-8 py-4 bg-white text-brand-navy rounded-lg hover:bg-gray-50 transition-all hover:shadow-xl font-semibold text-lg w-full sm:w-auto"
+ className="px-6 sm:px-8 py-3 sm:py-4 bg-white text-brand-navy rounded-lg hover:bg-gray-50 transition-all hover:shadow-xl font-semibold text-base sm:text-lg w-full sm:w-auto text-center"
>
Voir la démo
@@ -452,12 +452,12 @@ export default function LandingPage() {
{/* Stats Section */}
-
+
{stats.map((stat, index) => {
@@ -477,7 +477,7 @@ export default function LandingPage() {
initial={{ scale: 0 }}
animate={isStatsInView ? { scale: 1 } : {}}
transition={{ duration: 0.5, delay: index * 0.1 }}
- className="text-5xl lg:text-6xl font-bold text-brand-navy mb-2 tabular-nums"
+ className="text-3xl sm:text-5xl lg:text-6xl font-bold text-brand-navy mb-2 tabular-nums"
>
{/* Features Section */}
-
-
+
+
-
+
Pourquoi choisir Xpeditis ?
-
+
Une plateforme complète pour gérer tous vos besoins en fret maritime
@@ -620,23 +620,23 @@ export default function LandingPage() {
-
+
{/* Header */}
Tarifs
-
+
Des plans adaptés à votre activité
-
+
De l'accès découverte au partenariat sur mesure — évoluez à tout moment.
@@ -959,19 +959,19 @@ export default function LandingPage() {
{/* Testimonials Section */}
-
+
-
+
Ils nous font confiance
-
+
Découvrez les témoignages de nos clients satisfaits
@@ -1014,18 +1014,18 @@ export default function LandingPage() {
{/* CTA Section */}
-
+
-
+
Prêt à simplifier votre fret maritime ?
-
+
Rejoignez des centaines de transitaires qui font confiance à Xpeditis pour leurs
expéditions maritimes.
@@ -1033,14 +1033,14 @@ export default function LandingPage() {
{isAuthenticated && user ? (
Accéder au tableau de bord
@@ -1051,7 +1051,7 @@ export default function LandingPage() {
href="/register"
target="_blank"
rel="noopener noreferrer"
- className="group px-8 py-4 bg-brand-turquoise text-white rounded-lg hover:bg-brand-turquoise/90 transition-all hover:shadow-2xl hover:scale-105 font-semibold text-lg w-full sm:w-auto flex items-center justify-center space-x-2"
+ className="group px-6 sm:px-8 py-3 sm:py-4 bg-brand-turquoise text-white rounded-lg hover:bg-brand-turquoise/90 transition-all hover:shadow-2xl hover:scale-105 font-semibold text-base sm:text-lg w-full sm:w-auto flex items-center justify-center space-x-2"
>
Créer un compte gratuit
@@ -1060,7 +1060,7 @@ export default function LandingPage() {
href="/login"
target="_blank"
rel="noopener noreferrer"
- className="px-8 py-4 bg-brand-navy text-white rounded-lg hover:bg-brand-navy/90 transition-all hover:shadow-xl font-semibold text-lg w-full sm:w-auto"
+ className="px-6 sm:px-8 py-3 sm:py-4 bg-brand-navy text-white rounded-lg hover:bg-brand-navy/90 transition-all hover:shadow-xl font-semibold text-base sm:text-lg w-full sm:w-auto text-center"
>
Se connecter
@@ -1070,7 +1070,7 @@ export default function LandingPage() {
diff --git a/apps/frontend/src/components/CookieConsent.tsx b/apps/frontend/src/components/CookieConsent.tsx
index 0050b1d..76af003 100644
--- a/apps/frontend/src/components/CookieConsent.tsx
+++ b/apps/frontend/src/components/CookieConsent.tsx
@@ -11,6 +11,7 @@ import { motion, AnimatePresence } from 'framer-motion';
import { Cookie, X, Settings, Check, Shield } from 'lucide-react';
import { useCookieConsent } from '@/lib/context/cookie-context';
import type { CookiePreferences } from '@/lib/api/gdpr';
+import { usePathname } from 'next/navigation';
export default function CookieConsent() {
const {
@@ -27,6 +28,12 @@ export default function CookieConsent() {
} = useCookieConsent();
const [localPrefs, setLocalPrefs] = useState
(preferences);
+ const pathname = usePathname();
+ // On dashboard pages, mobile has a bottom nav bar (h-16 = 64px). Offset to avoid overlap.
+ const isDashboard = pathname?.startsWith('/dashboard');
+ // Classes to apply only on mobile when on the dashboard
+ const mobileOffset = isDashboard ? 'bottom-16 lg:bottom-0' : 'bottom-0';
+ const mobileButtonOffset = isDashboard ? 'bottom-20 lg:bottom-4' : 'bottom-4';
// Sync local prefs when context changes
React.useEffect(() => {
@@ -53,7 +60,7 @@ export default function CookieConsent() {
exit={{ scale: 0, opacity: 0 }}
transition={{ type: 'spring', stiffness: 260, damping: 20 }}
onClick={openPreferences}
- className="fixed bottom-4 left-4 z-40 p-3 bg-brand-navy text-white rounded-full shadow-lg hover:bg-brand-navy/90 focus:outline-none focus:ring-2 focus:ring-brand-turquoise focus:ring-offset-2 transition-colors"
+ className={`fixed left-4 z-40 p-3 bg-brand-navy text-white rounded-full shadow-lg hover:bg-brand-navy/90 focus:outline-none focus:ring-2 focus:ring-brand-turquoise focus:ring-offset-2 transition-colors ${mobileButtonOffset}`}
aria-label="Ouvrir les paramètres de cookies"
>
@@ -69,7 +76,7 @@ export default function CookieConsent() {
animate={{ y: 0, opacity: 1 }}
exit={{ y: 100, opacity: 0 }}
transition={{ type: 'spring', stiffness: 300, damping: 30 }}
- className="fixed bottom-0 left-0 right-0 z-50 bg-white border-t border-gray-200 shadow-2xl"
+ className={`fixed left-0 right-0 z-50 bg-white border-t border-gray-200 shadow-2xl ${mobileOffset}`}
>
diff --git a/apps/frontend/src/components/layout/LandingHeader.tsx b/apps/frontend/src/components/layout/LandingHeader.tsx
index e225a22..4e9ca88 100644
--- a/apps/frontend/src/components/layout/LandingHeader.tsx
+++ b/apps/frontend/src/components/layout/LandingHeader.tsx
@@ -10,8 +10,11 @@ import {
BookOpen,
LayoutDashboard,
Code2,
+ Menu,
+ X,
} from 'lucide-react';
import { useAuth } from '@/lib/context/auth-context';
+import { usePathname } from 'next/navigation';
interface LandingHeaderProps {
transparentOnTop?: boolean;
@@ -21,7 +24,14 @@ interface LandingHeaderProps {
export function LandingHeader({ transparentOnTop = false, activePage }: LandingHeaderProps) {
const [isScrolled, setIsScrolled] = useState(false);
const [isCompanyMenuOpen, setIsCompanyMenuOpen] = useState(false);
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const { user, isAuthenticated, loading } = useAuth();
+ const pathname = usePathname();
+
+ // Close mobile menu on route change
+ useEffect(() => {
+ setIsMobileMenuOpen(false);
+ }, [pathname]);
const companyMenuItems = [
{ href: '/about', label: 'À propos', icon: Info, description: 'Notre histoire et mission' },
@@ -66,6 +76,7 @@ export function LandingHeader({ transparentOnTop = false, activePage }: LandingH
};
return (
+ <>
-
-
+
+
+
+ {/* Mobile hamburger button */}
+
+
+
+ {/* Mobile menu drawer */}
+
+ {isMobileMenuOpen && (
+ <>
+ {/* Backdrop */}
+ setIsMobileMenuOpen(false)}
+ />
+ {/* Drawer */}
+
+ {/* Drawer header */}
+
+
+
+
+
+ {/* Nav links */}
+
+
+ {/* Auth section */}
+
+ {loading ? (
+
+ ) : isAuthenticated && user ? (
+
+
+ {getUserInitials()}
+
+
{getFullName()}
+
+
+ ) : (
+ <>
+
+ Connexion
+
+
+ Commencer Gratuitement
+
+ >
+ )}
+
+
+ >
+ )}
+
+ >
);
}
diff --git a/apps/frontend/src/components/ui/PageHeader.tsx b/apps/frontend/src/components/ui/PageHeader.tsx
new file mode 100644
index 0000000..2a566f1
--- /dev/null
+++ b/apps/frontend/src/components/ui/PageHeader.tsx
@@ -0,0 +1,30 @@
+import { ReactNode } from 'react';
+
+interface PageHeaderProps {
+ title: string;
+ description?: string;
+ actions?: ReactNode;
+}
+
+/**
+ * Consistent page header for dashboard pages.
+ * Mobile: actions appear above title (right-aligned).
+ * Desktop: title on the left, actions on the right.
+ */
+export function PageHeader({ title, description, actions }: PageHeaderProps) {
+ return (
+
+ {actions && (
+
+ {actions}
+
+ )}
+
+
{title}
+ {description && (
+
{description}
+ )}
+
+
+ );
+}