diff --git a/next.config.mjs b/next.config.mjs index 4678774..5b436b6 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,6 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + devIndicators: false, +}; export default nextConfig; diff --git a/src/app/globals.css b/src/app/globals.css index e98ae2d..fc7e717 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,147 +1,170 @@ /* Global Styles */ body { - background: linear-gradient(135deg, #000000, #1a001a); - font-size: 1.125rem; - font-family: 'Helvetica', sans-serif; - color: #ffffff; - margin: 0; - padding: 0; + background: linear-gradient(135deg, #000000, #1a001a); + font-size: 1.125rem; + font-family: 'Helvetica', sans-serif; + color: #ffffff; + margin: 0; + padding: 0; + overflow-x: hidden; + overscroll-behavior: none; +} + +html { + height: 100%; + min-height: 100vh; + background: linear-gradient(135deg, #000000, #1a001a); + overflow-x: hidden; + overscroll-behavior: none; /* Prevents scrolling past the boundaries */ } .container { - max-width: 1200px; - margin: 0 auto; - padding: 2rem; + max-width: 1200px; + margin: 0 auto; + padding: 2rem; } .header { - text-align: center; - margin-bottom: 2rem; + text-align: center; + margin-bottom: 2rem; } .title { - font-size: 2.5rem; - margin-bottom: 0.5rem; - color: #ffffff; + font-size: 2.5rem; + margin-bottom: 0.5rem; + color: #ffffff; } /* Title animation classes */ .title.normal { - opacity: 1; + opacity: 1; } + .title.fadeOut { - animation: fadeOutAnimation 0.5s forwards; + animation: fadeOutAnimation 0.5s forwards; } + .title.fadeIn { - animation: fadeInAnimation 0.5s forwards; + animation: fadeInAnimation 0.5s forwards; } @keyframes fadeOutAnimation { - from { opacity: 1; } - to { opacity: 0; } + from { + opacity: 1; + } + to { + opacity: 0; + } } + @keyframes fadeInAnimation { - from { opacity: 0; } - to { opacity: 1; } + from { + opacity: 0; + } + to { + opacity: 1; + } } .intro { - font-size: 1.5rem; - color: #cccccc; + font-size: 1.5rem; + color: #cccccc; } /* Default fade-in section: occupies at least one full viewport */ .fade-in-section { - min-height: 100vh; - display: flex; - align-items: center; - justify-content: center; - opacity: 0; - transform: translateY(20px); - transition: opacity 0.3s ease-out, transform 0.3s ease-out; - will-change: opacity, transform; + min-height: 90vh; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transform: translateY(20px); + transition: opacity 0.3s ease-out, transform 0.3s ease-out; + 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; /* Remove full viewport height requirement */ + padding: 2rem 0; /* Add vertical padding if needed */ } .section { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; } .textLeft, .imageRight, .imageLeft, .buttonLeft { - padding: 1rem; - flex: 1; + padding: 1rem; + flex: 1; } /* Button container aligned to the left */ .buttonLeft { - display: flex; - justify-content: flex-start; + display: flex; + justify-content: center; /* Centers the button horizontally */ + align-items: center; /* Centers vertically */ + width: 100%; /* Ensures it takes full width */ } /* Slightly smaller images */ .imageRight img, .imageLeft img { - width: 90%; - height: auto; - border-radius: 8px; + width: 90%; + height: auto; + border-radius: 8px; } /* Enlarged Learn More button with dark purple tones */ .learnMoreButton { - padding: 1rem 2rem; - font-size: 1.25rem; - background-color: #3d003d; - border: none; - border-radius: 5px; - color: #fff; - cursor: pointer; - transition: background-color 0.3s ease; + padding: 1rem 2rem; + font-size: 1.25rem; + background-color: #3d003d; + border: none; + border-radius: 5px; + color: #fff; + cursor: pointer; + transition: background-color 0.3s ease; } .learnMoreButton:hover { - background-color: #2e002e; + background-color: #2e002e; } /* Scroll Prompt styling with no background */ .scrollPrompt { - position: fixed; - bottom: 20px; - left: 50%; - transform: translateX(-50%); - padding: 0.5rem 1rem; - border-radius: 5px; - color: #fff; - font-size: 1rem; - z-index: 1000; - background: none; + position: fixed; + bottom: 20px; + left: 50%; + transform: translateX(-50%); + padding: 0.5rem 1rem; + border-radius: 5px; + color: #fff; + font-size: 1rem; + z-index: 1000; + background: none; } /* When section is fully visible */ .fade-in-section.is-visible { - opacity: 1; - transform: none; + opacity: 1; + transform: none; } /* Hide scrollbar for Chrome, Safari, Opera */ ::-webkit-scrollbar { - display: none; + 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; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ } diff --git a/src/app/page.js b/src/app/page.js index f7af429..10963c7 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -1,101 +1,101 @@ "use client"; -import { useState, useEffect } from "react"; +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"); - const [phase, setPhase] = useState("normal"); + const [showScrollPrompt, setShowScrollPrompt] = useState(false); + const [title, setTitle] = useState("Fretux"); + const [phase, setPhase] = useState("normal"); + useEffect(() => { + const interval = setInterval(() => { + setPhase("fadeOut"); + setTimeout(() => { + setTitle((prev) => (prev === "Fretux" ? "Frederik Spirgi" : "Fretux")); + setPhase("fadeIn"); + setTimeout(() => { + setPhase("normal"); + }, 500); + }, 500); + }, 3000); + return () => clearInterval(interval); + }, []); + useEffect(() => { + if (typeof window !== "undefined") { + window.scrollTo(0, 0); + } + }, []); + useEffect(() => { + const timer = setTimeout(() => { + setShowScrollPrompt(true); + }, 1500); - // Title flicker effect: every 3 seconds, fade out, toggle title, then fade in. - useEffect(() => { - const interval = setInterval(() => { - setPhase("fadeOut"); - setTimeout(() => { - setTitle((prev) => (prev === "Fretux" ? "Frederik Spirgi" : "Fretux")); - setPhase("fadeIn"); - setTimeout(() => { - setPhase("normal"); - }, 500); - }, 500); - }, 3000); - return () => clearInterval(interval); - }, []); + const handleScroll = () => { + setShowScrollPrompt(false); + clearTimeout(timer); // Ensures the timeout is cleared if the user scrolls early + window.removeEventListener("scroll", handleScroll); + }; - // Show scroll prompt after a delay (once the title has loaded in). - useEffect(() => { - const timer = setTimeout(() => { - setShowScrollPrompt(true); - }, 1500); // Adjust the delay as needed - return () => clearTimeout(timer); - }, []); + window.addEventListener("scroll", handleScroll); - // Remove the scroll prompt permanently upon first scroll. - useEffect(() => { - const handleScroll = () => { - setShowScrollPrompt(false); - window.removeEventListener("scroll", handleScroll); - }; - - window.addEventListener("scroll", handleScroll); - return () => window.removeEventListener("scroll", handleScroll); - }, []); - - return ( -
- {showScrollPrompt && ( -
-

Scroll subtly

+ return () => { + clearTimeout(timer); + window.removeEventListener("scroll", handleScroll); + }; + }, []); + return ( +
+ {showScrollPrompt && ( +
+

Scroll subtly

+
+ )} + +
+

{title}

+

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

+
+
+ +
+
+

+ I specialize in creating intuitive user experiences and dynamic web solutions using Next.js, + React, and modern design principles. +

+
+
+ Screenshot of a portfolio project +
+
+
+ +
+
+ Another project snapshot +
+
+ + + +
+
+
- )} - - -
-

{title}

-

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

-
-
- - -
-
-

- I specialize in creating intuitive user experiences and dynamic web solutions using Next.js, React, and modern design principles. -

-
-
- Screenshot of a portfolio project -
-
-
- - -
-
- Another project snapshot -
-
- - - -
-
-
-
- ); + ); } \ No newline at end of file