diff --git a/src/App.tsx b/src/App.tsx
index 53704f3b..23da0412 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -24,6 +24,7 @@ import { ResilienceProvider } from "@/components/layout/ResilienceProvider";
import { useAdminRoutePreload } from "@/hooks/useAdminRoutePreload";
import { useVersionCheck } from "@/hooks/useVersionCheck";
import { cn } from "@/lib/utils";
+import { PageTransition } from "@/components/layout/PageTransition";
// Core routes (eager-loaded for best UX)
import Index from "./pages/Index";
@@ -164,8 +165,9 @@ function AppContent(): React.JSX.Element {
}>
-
-
+
+
+
{/* Core routes - eager loaded */}
} />
} />
@@ -443,7 +445,8 @@ function AppContent(): React.JSX.Element {
} />
-
+
+
diff --git a/src/components/layout/PageTransition.tsx b/src/components/layout/PageTransition.tsx
new file mode 100644
index 00000000..97a3fc7c
--- /dev/null
+++ b/src/components/layout/PageTransition.tsx
@@ -0,0 +1,34 @@
+import { ReactNode, useEffect, useState } from 'react';
+import { useLocation } from 'react-router-dom';
+
+interface PageTransitionProps {
+ children: ReactNode;
+}
+
+export function PageTransition({ children }: PageTransitionProps) {
+ const location = useLocation();
+ const [displayLocation, setDisplayLocation] = useState(location);
+ const [transitionStage, setTransitionStage] = useState<'fade-in' | 'fade-out'>('fade-in');
+
+ useEffect(() => {
+ if (location !== displayLocation) {
+ setTransitionStage('fade-out');
+ }
+ }, [location, displayLocation]);
+
+ const onAnimationEnd = () => {
+ if (transitionStage === 'fade-out') {
+ setTransitionStage('fade-in');
+ setDisplayLocation(location);
+ }
+ };
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/components/navigation/EntityBreadcrumb.tsx b/src/components/navigation/EntityBreadcrumb.tsx
new file mode 100644
index 00000000..fec24eaf
--- /dev/null
+++ b/src/components/navigation/EntityBreadcrumb.tsx
@@ -0,0 +1,87 @@
+import { Link } from 'react-router-dom';
+import { Home } from 'lucide-react';
+import {
+ Breadcrumb,
+ BreadcrumbList,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+} from '@/components/ui/breadcrumb';
+import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card';
+import { ParkPreviewCard } from '@/components/preview/ParkPreviewCard';
+import { CompanyPreviewCard } from '@/components/preview/CompanyPreviewCard';
+
+interface BreadcrumbSegment {
+ label: string;
+ href?: string;
+ showPreview?: boolean;
+ previewType?: 'park' | 'company';
+ previewSlug?: string;
+}
+
+interface EntityBreadcrumbProps {
+ segments: BreadcrumbSegment[];
+ className?: string;
+}
+
+export function EntityBreadcrumb({ segments, className }: EntityBreadcrumbProps) {
+ return (
+
+
+ {/* Home link */}
+
+
+
+
+ Home
+
+
+
+
+ {segments.map((segment, index) => {
+ const isLast = index === segments.length - 1;
+
+ return (
+
+
+ {isLast ? (
+ {segment.label}
+ ) : segment.showPreview && segment.previewSlug ? (
+
+
+
+
+ {segment.label}
+
+
+
+
+ {segment.previewType === 'park' && (
+
+ )}
+ {segment.previewType === 'company' && (
+
+ )}
+
+
+ ) : (
+
+
+ {segment.label}
+
+
+ )}
+
+ );
+ })}
+
+
+ );
+}
diff --git a/src/pages/DesignerDetail.tsx b/src/pages/DesignerDetail.tsx
index 3322d61a..5b193d45 100644
--- a/src/pages/DesignerDetail.tsx
+++ b/src/pages/DesignerDetail.tsx
@@ -1,5 +1,6 @@
import { useState, useEffect, lazy, Suspense } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
+import { EntityBreadcrumb } from '@/components/navigation/EntityBreadcrumb';
import { Header } from '@/components/layout/Header';
import { getBannerUrls } from '@/lib/cloudflareImageUtils';
import { Button } from '@/components/ui/button';
@@ -181,6 +182,15 @@ export default function DesignerDetail() {
+ {/* Breadcrumb Navigation */}
+
+
{/* Back Button and Edit Button */}