diff --git a/src/App.tsx b/src/App.tsx index 19c9751..78d9f0c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,6 @@ import remarkGfm from "remark-gfm"; // Components import { - AnimatedBackground, ProjectThumb, CascadeItem, FadeContainer, @@ -14,7 +13,6 @@ import { // Hooks import { - useSystemDarkMode, useGitHubReadme, useGitHubRepoImages, } from "./hooks"; @@ -31,13 +29,27 @@ export default function PortfolioAboveTheFold() { null, ); const [isContentVisible, setIsContentVisible] = useState(true); - const isDark = useSystemDarkMode(); // Handle project selection with fade transition const handleProjectSelect = (projectId: number) => { if (projectId === active) return; - // Start fade out + // If on mobile/tablet, trigger the modal instantly without waiting for fade-out + if (window.innerWidth < 1024) { + setIsContentVisible(false); // Reset content visibility for the cascade + setActive(projectId); + setDisplayedProject(projectId); + + // Wait for the modal wrapper to begin its CSS transition before starting the cascade + requestAnimationFrame(() => { + requestAnimationFrame(() => { + setIsContentVisible(true); + }); + }); + return; + } + + // Start fade out for desktop setIsContentVisible(false); // After fade out completes, update the project and fade in @@ -48,19 +60,31 @@ export default function PortfolioAboveTheFold() { requestAnimationFrame(() => { setIsContentVisible(true); }); - }, 200); // Match the fade-out duration + }, 300); // Match the fade-out duration }; // Handle closing with fade transition const handleClose = () => { setIsContentVisible(false); + + if (window.innerWidth < 1024) { + // Instantly start scaling down the modal on mobile + setActive(null); + setDisplayedProject(null); + requestAnimationFrame(() => { + setIsContentVisible(true); + }); + return; + } + + // On desktop, wait for fade-out before resetting project setTimeout(() => { setActive(null); setDisplayedProject(null); requestAnimationFrame(() => { setIsContentVisible(true); }); - }, 200); + }, 300); }; // Combine all projects for lookup @@ -87,40 +111,36 @@ export default function PortfolioAboveTheFold() { } = useGitHubReadme(activeRepo); return ( -
- -
- +
+
+
-

+

Hello, I'm

-

+

{profile.name}

-

- {profile.role} • {profile.location} +

+ {profile.role} {profile.location}

-

+

{profile.blurb}

-
+
Download CV Contact @@ -137,48 +157,24 @@ export default function PortfolioAboveTheFold() { const isActive = active === p.id; return ( - // Wrapper div creates the gradient border effect
- {/* Gradient border layer - always present, opacity controlled */} -
-
+
-
-

+
+

{ allProjectsList.find( (p) => @@ -345,9 +373,13 @@ export default function PortfolioAboveTheFold() {

@@ -366,7 +398,7 @@ export default function PortfolioAboveTheFold() { ?.tags.map((t, i) => ( {t} @@ -380,13 +412,15 @@ export default function PortfolioAboveTheFold() { >
{readmeLoading && ( -
- Loading README... +
+
+
+
)} {readmeError && !readmeLoading && ( -

+

{ allProjectsList.find( (p) => @@ -398,7 +432,7 @@ export default function PortfolioAboveTheFold() { )} {readmeContent && !readmeLoading && ( -

+
+

{ allProjectsList.find( (p) => @@ -487,12 +521,13 @@ export default function PortfolioAboveTheFold() { {/* Empty state view */} -

+
-

- Selected work +

+ Selected Work

@@ -512,9 +547,9 @@ export default function PortfolioAboveTheFold() { isContentVisible } > -

+

Click a project on the left to open - a short preview. + a quick preview and read more.

@@ -531,29 +566,6 @@ export default function PortfolioAboveTheFold() {
- -
-
-

- Skills -

-
- {skills.map((s, i) => ( - - {s} - - ))} -
-
- -
-
Available for freelance & contract
-
{profile.email}
-
-