Updated visual look

This commit is contained in:
Plexi09 2026-02-23 00:36:21 +01:00
parent 91936e441f
commit c965168ef2
Signed by: Plexi09
GPG key ID: 20D439A69163544A
3 changed files with 471 additions and 51 deletions

View file

@ -1,34 +1,55 @@
/* Custom Styles for Plexi09 Portfolio */ /* Custom Styles for Plexi09 Portfolio */
/*
CSS CUSTOM PROPERTIES
*/
:root {
--accent-1: #6366f1;
--accent-2: #8b5cf6;
--accent-3: #a78bfa;
--gradient: linear-gradient(135deg, var(--accent-1), var(--accent-2), var(--accent-3));
--glass-bg: rgba(255, 255, 255, 0.03);
--glass-border: rgba(255, 255, 255, 0.06);
--radius: 1.25rem;
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--ease-smooth: cubic-bezier(0.76, 0, 0.24, 1);
}
/* Hide default scrollbar for a cleaner look */ /* Hide default scrollbar for a cleaner look */
::-webkit-scrollbar { ::-webkit-scrollbar {
display: none; display: none;
} }
html { html {
scrollbar-width: none; scrollbar-width: none;
} }
/* Lenis Smooth Scroll */ /* Lenis Smooth Scroll */
html.lenis { html.lenis {
height: auto; height: auto;
} }
.lenis.lenis-smooth { .lenis.lenis-smooth {
scroll-behavior: auto; scroll-behavior: auto;
} }
.lenis.lenis-smooth [data-lenis-prevent] { .lenis.lenis-smooth [data-lenis-prevent] {
overscroll-behavior: contain; overscroll-behavior: contain;
} }
.lenis.lenis-stopped { .lenis.lenis-stopped {
overflow: hidden; overflow: hidden;
} }
.lenis.lenis-scrolling iframe { .lenis.lenis-scrolling iframe {
pointer-events: none; pointer-events: none;
} }
/* Typography & Utilities */ /* Typography & Utilities */
.stroke-text { .stroke-text {
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.8); -webkit-text-stroke: 1.5px rgba(255, 255, 255, 0.6);
}
.gradient-text {
background: var(--gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
} }
/* Custom Cursor */ /* Custom Cursor */
@ -40,13 +61,14 @@ html.lenis {
/* Selection color */ /* Selection color */
::selection { ::selection {
background-color: #ffffff; background: var(--accent-2);
color: #000000; color: #ffffff;
} }
/* Preloader */ /* Preloader */
#preloader { #preloader {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
background: #050505;
} }
/* Hero entrance elements — hidden before preloader reveals them */ /* Hero entrance elements — hidden before preloader reveals them */
@ -74,10 +96,11 @@ html.lenis {
inset: 0; inset: 0;
z-index: 500; z-index: 500;
pointer-events: none; pointer-events: none;
opacity: 0.045; opacity: 0.04;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E"); background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
background-repeat: repeat; background-repeat: repeat;
background-size: 180px 180px; background-size: 180px 180px;
mix-blend-mode: overlay;
} }
/* /*
@ -89,10 +112,11 @@ html.lenis {
left: 0; left: 0;
height: 2px; height: 2px;
width: 0%; width: 0%;
background: linear-gradient(90deg, #3b82f6, #93c5fd); background: var(--gradient);
z-index: 600; z-index: 600;
pointer-events: none; pointer-events: none;
transition: width 0.05s linear; transition: width 0.05s linear;
box-shadow: 0 0 20px var(--accent-1), 0 0 60px rgba(99, 102, 241, 0.3);
} }
/* /*
@ -110,8 +134,8 @@ html.lenis {
left: 0; left: 0;
width: 0; width: 0;
height: 1px; height: 1px;
background-color: #ffffff; background: var(--gradient);
transition: width 0.4s cubic-bezier(0.76, 0, 0.24, 1); transition: width 0.4s var(--ease-smooth);
} }
.nav-link.active { .nav-link.active {
color: #ffffff; color: #ffffff;
@ -140,7 +164,7 @@ html.lenis {
#mobile-overlay .mobile-nav-link { #mobile-overlay .mobile-nav-link {
transform: translateX(-20px); transform: translateX(-20px);
opacity: 0; opacity: 0;
transition: transform 0.6s cubic-bezier(0.76, 0, 0.24, 1), opacity 0.6s ease; transition: transform 0.6s var(--ease-smooth), opacity 0.6s ease;
} }
#mobile-overlay.open .mobile-nav-link { transform: translateX(0); opacity: 1; } #mobile-overlay.open .mobile-nav-link { transform: translateX(0); opacity: 1; }
#mobile-overlay.open .mobile-nav-link:nth-child(1) { transition-delay: 0.15s; } #mobile-overlay.open .mobile-nav-link:nth-child(1) { transition-delay: 0.15s; }
@ -155,12 +179,294 @@ html.lenis {
.section-num { .section-num {
font-size: 0.68rem; font-size: 0.68rem;
letter-spacing: 0.3em; letter-spacing: 0.3em;
color: #3b82f6;
text-transform: uppercase; text-transform: uppercase;
display: block; display: block;
margin-bottom: 1.25rem; margin-bottom: 1.25rem;
font-family: 'Inter', sans-serif; font-family: 'Inter', sans-serif;
font-weight: 500; font-weight: 500;
background: var(--gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/*
MARQUEE / TICKER
*/
.marquee {
overflow: hidden;
white-space: nowrap;
border-top: 1px solid var(--glass-border);
border-bottom: 1px solid var(--glass-border);
}
.marquee-inner {
display: inline-flex;
animation: marquee-scroll 30s linear infinite;
}
.marquee:hover .marquee-inner {
animation-play-state: paused;
}
.marquee-item {
display: inline-flex;
align-items: center;
gap: 2rem;
padding: 0 2rem;
font-family: 'Clash Display', sans-serif;
font-size: clamp(1.5rem, 3vw, 3rem);
font-weight: 600;
text-transform: uppercase;
letter-spacing: -0.02em;
color: rgba(255, 255, 255, 0.08);
transition: color 0.4s ease;
}
.marquee-item .dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--gradient);
flex-shrink: 0;
opacity: 0.5;
}
@keyframes marquee-scroll {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
/*
GLASSMORPHISM CARDS
*/
.glass-card {
background: var(--glass-bg);
border: 1px solid var(--glass-border);
border-radius: var(--radius);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
transition: all 0.5s var(--ease-out-expo);
}
.glass-card:hover {
border-color: rgba(255, 255, 255, 0.12);
background: rgba(255, 255, 255, 0.05);
transform: translateY(-4px);
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4), 0 0 40px rgba(99, 102, 241, 0.06);
}
/*
PROJECT CARDS GRADIENT BORDER
*/
.project-card {
position: relative;
background: #0a0a0a;
border: 1px solid transparent;
transition: all 0.6s var(--ease-out-expo);
}
.project-card::before {
content: '';
position: absolute;
inset: -1px;
border-radius: inherit;
padding: 1px;
background: linear-gradient(135deg, transparent, transparent);
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
opacity: 0;
transition: opacity 0.6s ease, background 0.6s ease;
pointer-events: none;
}
.project-card:hover::before {
background: var(--gradient);
opacity: 1;
}
.project-card:hover {
transform: translateY(-6px);
box-shadow: 0 25px 80px rgba(99, 102, 241, 0.08);
}
/*
TECH BADGE STYLING
*/
.tech-badge {
border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(255, 255, 255, 0.02);
transition: all 0.4s ease;
}
.tech-badge:hover {
border-color: var(--accent-2);
background: rgba(139, 92, 246, 0.08);
transform: translateY(-2px);
}
/*
MAGNETIC BUTTONS
*/
.magnetic-btn {
position: relative;
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.875rem 2rem;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 999px;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.2em;
color: rgba(255, 255, 255, 0.7);
background: transparent;
overflow: hidden;
transition: all 0.5s var(--ease-out-expo);
}
.magnetic-btn::before {
content: '';
position: absolute;
inset: 0;
background: var(--gradient);
opacity: 0;
transition: opacity 0.5s ease;
border-radius: inherit;
}
.magnetic-btn:hover {
border-color: transparent;
color: #fff;
transform: scale(1.05);
}
.magnetic-btn:hover::before {
opacity: 1;
}
.magnetic-btn span,
.magnetic-btn i {
position: relative;
z-index: 1;
}
/*
FLOATING SHAPES (BG DECORATION)
*/
.floating-shape {
position: absolute;
border-radius: 50%;
filter: blur(100px);
pointer-events: none;
opacity: 0.15;
}
.floating-shape-1 {
width: 400px;
height: 400px;
background: var(--accent-1);
top: -100px;
right: -100px;
animation: float-1 15s ease-in-out infinite;
}
.floating-shape-2 {
width: 300px;
height: 300px;
background: var(--accent-2);
bottom: -50px;
left: -80px;
animation: float-2 18s ease-in-out infinite;
}
.floating-shape-3 {
width: 250px;
height: 250px;
background: var(--accent-3);
top: 50%;
left: 50%;
animation: float-3 20s ease-in-out infinite;
}
@keyframes float-1 {
0%, 100% { transform: translate(0, 0) scale(1); }
33% { transform: translate(-30px, 40px) scale(1.1); }
66% { transform: translate(20px, -20px) scale(0.9); }
}
@keyframes float-2 {
0%, 100% { transform: translate(0, 0) scale(1); }
33% { transform: translate(40px, -30px) scale(1.15); }
66% { transform: translate(-25px, 25px) scale(0.95); }
}
@keyframes float-3 {
0%, 100% { transform: translate(-50%, -50%) scale(1); }
50% { transform: translate(-50%, -50%) scale(1.2); }
}
/*
SKILLS GRID
*/
.skill-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
padding: 1.5rem 1rem;
border: 1px solid var(--glass-border);
border-radius: var(--radius);
background: var(--glass-bg);
transition: all 0.5s var(--ease-out-expo);
}
.skill-item:hover {
border-color: rgba(255, 255, 255, 0.12);
background: rgba(255, 255, 255, 0.04);
transform: translateY(-6px);
}
.skill-item i {
font-size: 2rem;
transition: transform 0.5s var(--ease-out-expo);
}
.skill-item:hover i {
transform: scale(1.2);
}
.skill-item span {
font-size: 0.65rem;
text-transform: uppercase;
letter-spacing: 0.15em;
color: rgba(255, 255, 255, 0.5);
}
/*
SECTION DIVIDER
*/
.section-divider {
height: 1px;
background: linear-gradient(90deg, transparent, var(--glass-border), transparent);
border: none;
}
/*
CONTACT SECTION GLOW
*/
.contact-glow {
position: absolute;
width: 600px;
height: 600px;
background: radial-gradient(circle, rgba(99, 102, 241, 0.12) 0%, transparent 70%);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
animation: pulse-glow 6s ease-in-out infinite;
}
@keyframes pulse-glow {
0%, 100% { opacity: 0.5; transform: translate(-50%, -50%) scale(1); }
50% { opacity: 1; transform: translate(-50%, -50%) scale(1.15); }
}
/*
SOCIAL LINKS
*/
.social-link {
display: inline-flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 50%;
transition: all 0.4s var(--ease-out-expo);
}
.social-link:hover {
border-color: var(--accent-2);
background: rgba(139, 92, 246, 0.1);
transform: translateY(-4px);
box-shadow: 0 8px 30px rgba(139, 92, 246, 0.15);
} }
/* /*
@ -175,4 +481,35 @@ html.lenis {
} }
.cv-lang-btn:hover { .cv-lang-btn:hover {
background: rgba(255, 255, 255, 0.03); background: rgba(255, 255, 255, 0.03);
border-color: var(--accent-2) !important;
}
/*
GALLERY ENHANCEMENTS
*/
.gallery-item {
transition: transform 0.6s var(--ease-out-expo);
}
.gallery-item:hover {
transform: scale(1.02);
}
/*
CV GROUP CARD GLOW
*/
.cv-column .group {
border: 1px solid transparent;
transition: all 0.5s var(--ease-out-expo);
}
.cv-column .group:hover {
background: rgba(255, 255, 255, 0.02);
border-color: var(--glass-border);
}
/*
FOOTER ACCENT LINE
*/
footer {
border-image: var(--gradient) 1;
border-top-width: 1px;
} }

View file

@ -19,7 +19,8 @@
colors: { colors: {
primary: '#ffffff', primary: '#ffffff',
dark: '#0a0a0a', dark: '#0a0a0a',
accent: '#3b82f6' accent: '#6366f1',
'accent-2': '#8b5cf6'
}, },
fontFamily: { fontFamily: {
sans: ['Inter', 'sans-serif'], sans: ['Inter', 'sans-serif'],
@ -83,11 +84,28 @@
Crafting digital experiences & capturing light. Crafting digital experiences & capturing light.
</p> </p>
</div> </div>
<div class="absolute bottom-10 left-1/2 -translate-x-1/2 text-sm uppercase tracking-widest opacity-50 animate-pulse"> <div class="absolute bottom-10 left-1/2 -translate-x-1/2 flex flex-col items-center gap-3 opacity-50">
Scroll to explore <span class="text-xs uppercase tracking-[0.3em]">Scroll to explore</span>
<div class="w-px h-8 bg-gradient-to-b from-white/60 to-transparent animate-pulse"></div>
</div> </div>
</section> </section>
<!-- Marquee / Ticker -->
<div class="marquee py-6 bg-dark relative z-10">
<div class="marquee-inner">
<span class="marquee-item">Developer <span class="dot"></span></span>
<span class="marquee-item">Photographer <span class="dot"></span></span>
<span class="marquee-item">Open Source <span class="dot"></span></span>
<span class="marquee-item">Self-Hosted <span class="dot"></span></span>
<span class="marquee-item">Creative <span class="dot"></span></span>
<span class="marquee-item">Developer <span class="dot"></span></span>
<span class="marquee-item">Photographer <span class="dot"></span></span>
<span class="marquee-item">Open Source <span class="dot"></span></span>
<span class="marquee-item">Self-Hosted <span class="dot"></span></span>
<span class="marquee-item">Creative <span class="dot"></span></span>
</div>
</div>
<!-- Mobile Menu Overlay --> <!-- Mobile Menu Overlay -->
<div id="mobile-overlay" class="fixed inset-0 z-[90] bg-[#0a0a0a] flex flex-col justify-center px-10 translate-x-full transition-transform duration-700 ease-in-out"> <div id="mobile-overlay" class="fixed inset-0 z-[90] bg-[#0a0a0a] flex flex-col justify-center px-10 translate-x-full transition-transform duration-700 ease-in-out">
<a href="#about" class="mobile-nav-link hover-target text-5xl sm:text-6xl font-display font-bold uppercase tracking-tighter mb-5 text-gray-700 hover:text-white transition-colors duration-300">01 — About</a> <a href="#about" class="mobile-nav-link hover-target text-5xl sm:text-6xl font-display font-bold uppercase tracking-tighter mb-5 text-gray-700 hover:text-white transition-colors duration-300">01 — About</a>
@ -102,17 +120,17 @@
<div class="max-w-3xl mx-auto"> <div class="max-w-3xl mx-auto">
<div class="space-y-8"> <div class="space-y-8">
<span class="section-num hero-title">01 / About</span> <span class="section-num hero-title">01 / About</span>
<h2 class="hero-title text-5xl md:text-7xl font-display font-bold uppercase tracking-tighter">The Mind <br>Behind <span class="text-transparent stroke-text">Plexi09</span></h2> <h2 class="hero-title text-5xl md:text-7xl font-display font-bold uppercase tracking-tighter">The Mind <br>Behind <span class="gradient-text">Plexi09</span></h2>
<p class="hero-subtitle text-xl text-gray-400 leading-relaxed font-light"> <p class="hero-subtitle text-xl text-gray-400 leading-relaxed font-light">
Hey 🖐️! <br>I am self-taught developer and passionate photographer. I believe in the power of open-source, self-hosting, and writing code that feels like poetry. Hey 🖐️! <br>I am self-taught developer and passionate photographer. I believe in the power of open-source, self-hosting, and writing code that feels like poetry.
</p> </p>
<p class="hero-subtitle text-xl text-gray-400 leading-relaxed font-light"> <p class="hero-subtitle text-xl text-gray-400 leading-relaxed font-light">
When I'm not architecting systems or deploying containers, I'm out in the world, freezing moments in time through my lens. When I'm not architecting systems or deploying containers, I'm out in the world, freezing moments in time through my lens.
</p> </p>
<div class="hero-subtitle pt-8 border-t border-gray-800 flex gap-12"> <div class="hero-subtitle pt-8 border-t border-gray-800 flex flex-wrap gap-12">
<div> <div>
<h4 class="text-sm uppercase tracking-widest text-gray-500 mb-2">Software stack</h4> <h4 class="text-sm uppercase tracking-widest text-gray-500 mb-2">Software stack</h4>
<p class="font-medium">TS, React, Tailwin, Python, Java, Docker</p> <p class="font-medium">TS, React, Tailwind, Python, Java, Docker</p>
</div> </div>
<div> <div>
<h4 class="text-sm uppercase tracking-widest text-gray-500 mb-2">Photography gear</h4> <h4 class="text-sm uppercase tracking-widest text-gray-500 mb-2">Photography gear</h4>
@ -128,9 +146,9 @@
<div class="max-w-7xl mx-auto"> <div class="max-w-7xl mx-auto">
<div class="mb-20 reveal-text"> <div class="mb-20 reveal-text">
<span class="section-num">02 / Experience</span> <span class="section-num">02 / Experience</span>
<h2 class="text-5xl md:text-7xl font-display font-bold uppercase tracking-tighter">Experience <br>& <span class="text-transparent stroke-text">Journey</span></h2> <h2 class="text-5xl md:text-7xl font-display font-bold uppercase tracking-tighter">Experience <br>& <span class="gradient-text">Journey</span></h2>
<a href="#" class="cv-download-btn text-xs border border-gray-800 hover:border-white text-gray-500 hover:text-white transition-all px-5 py-2.5 rounded-full uppercase tracking-widest hover-target mt-8 inline-block"> <a href="#" class="cv-download-btn magnetic-btn hover-target mt-8 inline-block">
<i class="fas fa-download mr-2"></i> Download CV <i class="fas fa-download"></i> <span>Download CV</span>
</a> </a>
</div> </div>
@ -200,20 +218,21 @@
<span class="section-num">03 / Creations</span> <span class="section-num">03 / Creations</span>
<h2 class="text-5xl md:text-7xl font-display font-bold uppercase tracking-tighter">Creations</h2> <h2 class="text-5xl md:text-7xl font-display font-bold uppercase tracking-tighter">Creations</h2>
</div> </div>
<a href="https://git.plexi09.me" class="hidden md:inline-block text-sm uppercase tracking-widest border-b border-white pb-1 hover-target">View Forgejo</a> <a href="https://git.plexi09.me" class="hidden md:inline-block magnetic-btn hover-target"><span>View Forgejo</span> <i class="fas fa-arrow-up-right-from-square text-xs"></i></a>
</div> </div>
<div class="grid md:grid-cols-2 gap-10"> <div class="grid md:grid-cols-2 gap-10">
<!-- Project Card --> <!-- Project Card -->
<a href="https://git.plexi09.me/plexi09/cinematch" target="_blank" rel="noopener noreferrer" class="project-card group relative overflow-hidden rounded-2xl bg-dark border border-gray-800 p-10 hover-target cursor-none block"> <a href="https://git.plexi09.me/plexi09/cinematch" target="_blank" rel="noopener noreferrer" class="project-card group relative overflow-hidden rounded-2xl p-10 hover-target cursor-none block">
<div class="absolute top-0 right-0 p-8 opacity-0 group-hover:opacity-100 transition-opacity duration-500 translate-x-4 group-hover:translate-x-0"> <div class="absolute top-0 right-0 p-8 opacity-0 group-hover:opacity-100 transition-all duration-500 translate-x-4 group-hover:translate-x-0">
<i class="fas fa-arrow-right text-2xl"></i> <i class="fas fa-arrow-right text-2xl gradient-text"></i>
</div> </div>
<h3 class="text-3xl font-display font-bold mb-4">Movie Match</h3> <span class="text-xs uppercase tracking-[0.2em] text-gray-600 mb-3 block">Featured Project</span>
<p class="text-gray-400 mb-8 font-light">An application that helps couples and friends discover compatible movies to watch together.</p> <h3 class="text-3xl font-display font-bold mb-4 group-hover:gradient-text transition-colors duration-500">Movie Match</h3>
<p class="text-gray-400 mb-8 font-light leading-relaxed">An application that helps couples and friends discover compatible movies to watch together.</p>
<div class="flex gap-3 flex-wrap"> <div class="flex gap-3 flex-wrap">
<span class="flex items-center gap-2 px-4 py-1 rounded-full border border-gray-700 text-xs uppercase tracking-wider"><i class="devicon-typescript-plain text-blue-400 text-base"></i> Typescript</span> <span class="tech-badge flex items-center gap-2 px-4 py-1.5 rounded-full text-xs uppercase tracking-wider"><i class="devicon-typescript-plain text-blue-400 text-base"></i> Typescript</span>
<span class="flex items-center gap-2 px-4 py-1 rounded-full border border-gray-700 text-xs uppercase tracking-wider"><i class="devicon-docker-plain text-base" style="color:#2496ed"></i> Docker</span> <span class="tech-badge flex items-center gap-2 px-4 py-1.5 rounded-full text-xs uppercase tracking-wider"><i class="devicon-docker-plain text-base" style="color:#2496ed"></i> Docker</span>
</div> </div>
</a> </a>
</div> </div>
@ -269,22 +288,31 @@
<!-- Contact Section --> <!-- Contact Section -->
<section id="contact" class="py-32 px-6 md:px-20 bg-[#0f0f0f] relative overflow-hidden"> <section id="contact" class="py-32 px-6 md:px-20 bg-[#0f0f0f] relative overflow-hidden">
<!-- Floating background shapes -->
<div class="floating-shape floating-shape-1"></div>
<div class="floating-shape floating-shape-2"></div>
<div class="contact-glow"></div>
<div class="max-w-4xl mx-auto text-center relative z-10"> <div class="max-w-4xl mx-auto text-center relative z-10">
<span class="section-num inline-block mb-6">05 / Contact</span> <span class="section-num inline-block mb-6">05 / Contact</span>
<h2 class="text-[10vw] leading-none font-display font-bold uppercase tracking-tighter mb-12 hover-target"> <h2 class="text-[10vw] leading-none font-display font-bold uppercase tracking-tighter mb-6 hover-target">
<a href="mailto:hello@plexi09.me" class="inline-block hover:scale-110 hover:stroke-text transition-all duration-300">Let's Talk</a> <a href="mailto:hello@plexi09.me" class="inline-block hover:scale-105 transition-transform duration-500">Let's Talk</a>
</h2> </h2>
<div class="flex justify-center gap-8 text-xl"> <p class="text-gray-500 text-lg font-light mb-12 max-w-md mx-auto">Have a project in mind or just want to say hello? I'd love to hear from you.</p>
<a href="https://git.plexi09.me/plexi09" target="_blank" rel="noopener noreferrer" class="hover-target hover:text-gray-400 transition"><i class="fab fa-git-alt"></i></a> <div class="flex justify-center gap-5 mb-16">
<a href="https://linkedin.com/in/pierre-emmanuel-gobillard-04933a305" target="_blank" rel="noopener noreferrer" class="hover-target hover:text-gray-400 transition"><i class="fab fa-linkedin"></i></a> <a href="https://git.plexi09.me/plexi09" target="_blank" rel="noopener noreferrer" class="social-link hover-target"><i class="fab fa-git-alt text-lg"></i></a>
<a href="https://instagram.com/plexi09_" target="_blank" rel="noopener noreferrer" class="hover-target hover:text-gray-400 transition"><i class="fab fa-instagram"></i></a> <a href="https://linkedin.com/in/pierre-emmanuel-gobillard-04933a305" target="_blank" rel="noopener noreferrer" class="social-link hover-target"><i class="fab fa-linkedin text-lg"></i></a>
<a href="https://instagram.com/plexi09_" target="_blank" rel="noopener noreferrer" class="social-link hover-target"><i class="fab fa-instagram text-lg"></i></a>
</div> </div>
<a href="mailto:hello@plexi09.me" class="magnetic-btn hover-target">
<i class="fas fa-envelope"></i> <span>hello@plexi09.me</span>
</a>
<p class="mt-20 text-gray-600 text-sm uppercase tracking-widest"> <p class="mt-20 text-gray-600 text-sm uppercase tracking-widest">
© 2026 Plexi09. All rights reserved. © 2026 Plexi09. All rights reserved.
</p> </p>
</div> </div>
<!-- Huge background text --> <!-- Huge background text -->
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-[20vw] font-display font-bold uppercase tracking-tighter text-white/[0.02] whitespace-nowrap pointer-events-none"> <div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-[20vw] font-display font-bold uppercase tracking-tighter text-white/[0.02] whitespace-nowrap pointer-events-none select-none">
PLEXI09 PLEXI09
</div> </div>
</section> </section>
@ -310,10 +338,10 @@
</div> </div>
<!-- Footer --> <!-- Footer -->
<footer class="bg-dark border-t border-gray-900 py-10 px-6 md:px-20"> <footer class="bg-dark py-10 px-6 md:px-20">
<div class="max-w-7xl mx-auto flex flex-col md:flex-row justify-between items-center gap-6"> <div class="max-w-7xl mx-auto flex flex-col md:flex-row justify-between items-center gap-6">
<div> <div>
<span class="font-display font-bold text-xl tracking-tighter uppercase text-white">PLEXI09</span> <span class="font-display font-bold text-xl tracking-tighter uppercase gradient-text">PLEXI09</span>
<p class="text-gray-600 text-sm mt-1 uppercase tracking-[0.2em]">Developer & Photographer</p> <p class="text-gray-600 text-sm mt-1 uppercase tracking-[0.2em]">Developer & Photographer</p>
</div> </div>
<div class="hidden md:flex gap-10 text-xs uppercase tracking-widest text-gray-500"> <div class="hidden md:flex gap-10 text-xs uppercase tracking-widest text-gray-500">
@ -322,8 +350,8 @@
<a href="#projects" class="hover:text-white transition hover-target">Projects</a> <a href="#projects" class="hover:text-white transition hover-target">Projects</a>
<a href="#photography" class="hover:text-white transition hover-target">Photography</a> <a href="#photography" class="hover:text-white transition hover-target">Photography</a>
</div> </div>
<a href="#" class="cv-download-btn text-xs border border-gray-800 hover:border-white text-gray-500 hover:text-white transition-all px-5 py-2.5 rounded-full uppercase tracking-widest hover-target"> <a href="#" class="cv-download-btn magnetic-btn hover-target">
<i class="fas fa-download mr-2"></i> Download CV <i class="fas fa-download"></i> <span>Download CV</span>
</a> </a>
</div> </div>
</footer> </footer>

View file

@ -210,14 +210,17 @@ document.addEventListener('DOMContentLoaded', () => {
gsap.utils.toArray('.cv-column').forEach(col => { gsap.utils.toArray('.cv-column').forEach(col => {
const items = col.querySelectorAll('.group'); const items = col.querySelectorAll('.group');
if (!items.length) return; if (!items.length) return;
gsap.from(items, { gsap.fromTo(items,
scrollTrigger: { trigger: col, start: 'top 82%' }, { y: 40, opacity: 0 },
y: 40, {
opacity: 0, scrollTrigger: { trigger: col, start: 'top 90%', toggleActions: 'play none none none' },
duration: 0.85, y: 0,
stagger: 0.18, opacity: 1,
ease: 'power3.out', duration: 0.85,
}); stagger: 0.18,
ease: 'power3.out',
}
);
}); });
// ── 11. PARALLAX IMAGES ─────────────────────────────────────────── // ── 11. PARALLAX IMAGES ───────────────────────────────────────────
@ -273,4 +276,56 @@ document.addEventListener('DOMContentLoaded', () => {
}); });
} }
// ── 14. MAGNETIC BUTTON EFFECT ─────────────────────────────────────
if (window.innerWidth >= 768) {
document.querySelectorAll('.magnetic-btn').forEach(btn => {
btn.addEventListener('mousemove', (e) => {
const rect = btn.getBoundingClientRect();
const x = e.clientX - rect.left - rect.width / 2;
const y = e.clientY - rect.top - rect.height / 2;
gsap.to(btn, { x: x * 0.3, y: y * 0.3, duration: 0.4, ease: 'power2.out' });
});
btn.addEventListener('mouseleave', () => {
gsap.to(btn, { x: 0, y: 0, duration: 0.7, ease: 'elastic.out(1, 0.3)' });
});
});
}
// ── 15. SKILL ITEMS STAGGER ANIMATION ──────────────────────────────
const skillItems = document.querySelectorAll('.skill-item');
if (skillItems.length) {
gsap.from(skillItems, {
scrollTrigger: { trigger: skillItems[0].parentElement, start: 'top 85%' },
scale: 0.8,
opacity: 0,
duration: 0.6,
stagger: 0.06,
ease: 'back.out(1.7)',
});
}
// ── 16. PROJECT CARDS ANIMATION ────────────────────────────────────
gsap.utils.toArray('.project-card').forEach(card => {
gsap.from(card, {
scrollTrigger: { trigger: card, start: 'top 85%' },
y: 60,
opacity: 0,
duration: 1,
ease: 'power3.out',
});
});
// ── 17. CONTACT SECTION ANIMATION ──────────────────────────────────
const contactSection = document.getElementById('contact');
if (contactSection) {
gsap.from(contactSection.querySelectorAll('.social-link'), {
scrollTrigger: { trigger: contactSection, start: 'top 70%' },
scale: 0,
opacity: 0,
duration: 0.6,
stagger: 0.1,
ease: 'back.out(1.7)',
});
}
}); });