diff --git a/public/images/portfolio1.jpg b/public/images/portfolio1.jpg deleted file mode 100644 index 545e94a..0000000 Binary files a/public/images/portfolio1.jpg and /dev/null differ diff --git a/public/images/portfolio2.jpg b/public/images/portfolio2.jpg index 545e94a..903104c 100644 Binary files a/public/images/portfolio2.jpg and b/public/images/portfolio2.jpg differ diff --git a/src/app/about.js b/src/app/about.js new file mode 100644 index 0000000..e69de29 diff --git a/src/app/about/page.js b/src/app/about/page.js new file mode 100644 index 0000000..9bad24b --- /dev/null +++ b/src/app/about/page.js @@ -0,0 +1,12 @@ +"use client"; + +export default function About() { + return ( +
+

About Me

+

+ This is the about page. +

+
+ ); +} \ No newline at end of file diff --git a/src/app/components/FadeInSection.js b/src/app/components/FadeInSection.js index c80d999..097c71d 100644 --- a/src/app/components/FadeInSection.js +++ b/src/app/components/FadeInSection.js @@ -6,25 +6,21 @@ const FadeInSection = ({ children }) => { const domRef = useRef(); const [hasBeenVisible, setHasBeenVisible] = useState(false); const [opacity, setOpacity] = useState(0); - useEffect(() => { const thresholds = Array.from({ length: 101 }, (_, i) => i / 100); const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { - // If 30% or more of the element is visible and it hasn't been set visible before... if (entry.intersectionRatio >= 0.3 && !hasBeenVisible) { setHasBeenVisible(true); setOpacity(1); } else if (!hasBeenVisible) { - // Gradually update opacity until the threshold is met setOpacity(entry.intersectionRatio); } }); }, { threshold: thresholds, - // A slight negative bottom margin delays the fade until more of the section is in view rootMargin: "0px 0px -20% 0px", } ); diff --git a/src/app/globals.css b/src/app/globals.css index fc7e717..15d2488 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -15,7 +15,7 @@ html { min-height: 100vh; background: linear-gradient(135deg, #000000, #1a001a); overflow-x: hidden; - overscroll-behavior: none; /* Prevents scrolling past the boundaries */ + overscroll-behavior: none; } .container { @@ -24,6 +24,10 @@ html { padding: 2rem; } +.textLeft { + font-size: 2rem; +} + .header { text-align: center; margin-bottom: 2rem; @@ -71,7 +75,6 @@ html { color: #cccccc; } -/* Default fade-in section: occupies at least one full viewport */ .fade-in-section { min-height: 90vh; display: flex; @@ -83,10 +86,9 @@ html { will-change: opacity, transform; } -/* Custom override for the first content section */ .firstSection { - min-height: auto; /* Remove full viewport height requirement */ - padding: 2rem 0; /* Add vertical padding if needed */ + min-height: auto; + padding: 2rem 0; } .section { @@ -102,17 +104,18 @@ html { .buttonLeft { padding: 1rem; flex: 1; + display: flex; + align-items: center; + justify-content: center; } -/* Button container aligned to the left */ .buttonLeft { display: flex; - justify-content: center; /* Centers the button horizontally */ - align-items: center; /* Centers vertically */ - width: 100%; /* Ensures it takes full width */ + justify-content: center; + align-items: center; + width: 100%; } -/* Slightly smaller images */ .imageRight img, .imageLeft img { width: 90%; @@ -120,7 +123,6 @@ html { border-radius: 8px; } -/* Enlarged Learn More button with dark purple tones */ .learnMoreButton { padding: 1rem 2rem; font-size: 1.25rem; @@ -136,7 +138,6 @@ html { background-color: #2e002e; } -/* Scroll Prompt styling with no background */ .scrollPrompt { position: fixed; bottom: 20px; @@ -150,21 +151,39 @@ html { background: none; } -/* When section is fully visible */ .fade-in-section.is-visible { opacity: 1; transform: none; } -/* Hide scrollbar for Chrome, Safari, Opera */ ::-webkit-scrollbar { display: none; } -/* Hide scrollbar for IE, Edge and Firefox */ body { - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; + scrollbar-width: none; +} + +@keyframes pulseBorder { + 0% { + box-shadow: 0 0 5px #4b004b; + } + 50% { + box-shadow: 0 0 20px #600060; + } + 100% { + box-shadow: 0 0 5px #4b004b; + } +} + +.imageRight img, +.imageLeft img { + width: 90%; + height: auto; + border-radius: 8px; + border: 4px solid #3d003d; + animation: pulseBorder 1.5s infinite alternate ease-in-out; } diff --git a/src/app/page.js b/src/app/page.js index 10963c7..8386684 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -4,7 +4,6 @@ import {useState, useEffect} from "react"; import Image from "next/image"; import Link from "next/link"; import FadeInSection from "./components/FadeInSection"; - export default function Home() { const [showScrollPrompt, setShowScrollPrompt] = useState(false); const [title, setTitle] = useState("Fretux"); @@ -31,15 +30,12 @@ export default function Home() { const timer = setTimeout(() => { setShowScrollPrompt(true); }, 1500); - const handleScroll = () => { setShowScrollPrompt(false); - clearTimeout(timer); // Ensures the timeout is cleared if the user scrolls early + clearTimeout(timer); window.removeEventListener("scroll", handleScroll); }; - window.addEventListener("scroll", handleScroll); - return () => { clearTimeout(timer); window.removeEventListener("scroll", handleScroll); @@ -56,7 +52,7 @@ export default function Home() {

{title}

- Welcome to my portfolio. I’m a web developer passionate about building modern, responsive + Welcome to my portfolio. I’m a developer passionate about building modern and responsive applications.