- Enhanced About page layout with improved styles and typography.
- Added `getSkillEmoji` function for dynamic skill badge icons. - Refactored timeline sections with new animations and responsive styling. - Replaced inline styles with CSS classes for cleaner separation. - Added "Learn More" button linking to the About page on the home section.
This commit is contained in:
+42
-66
@@ -31,6 +31,17 @@ export default function About() {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function getSkillEmoji(name) {
|
||||||
|
switch (name) {
|
||||||
|
case "JavaScript": return "🟨";
|
||||||
|
case "Python": return "🐍";
|
||||||
|
case "Java": return "☕";
|
||||||
|
case "SQL": return "💾";
|
||||||
|
case "HTML & CSS": return "🎨";
|
||||||
|
default: return "💡";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const skills = [
|
const skills = [
|
||||||
{
|
{
|
||||||
name: "JavaScript",
|
name: "JavaScript",
|
||||||
@@ -163,8 +174,8 @@ export default function About() {
|
|||||||
boxSizing: "border-box",
|
boxSizing: "border-box",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h1 style={{fontSize: "2.5rem", marginBottom: "1rem"}}>About Me</h1>
|
<h1 style={{fontSize: "3.5rem", marginBottom: "1rem"}}>About Me</h1>
|
||||||
<p style={{maxWidth: "600px", textAlign: "center"}}>
|
<p style={{maxWidth: "600px", textAlign: "center", fontWeight: "300", fontSize: "1.5rem"}}>
|
||||||
I’m a passionate developer always excited about new challenges.
|
I’m a passionate developer always excited about new challenges.
|
||||||
Scroll down to learn more about me!
|
Scroll down to learn more about me!
|
||||||
</p>
|
</p>
|
||||||
@@ -195,81 +206,46 @@ export default function About() {
|
|||||||
<section
|
<section
|
||||||
key={index}
|
key={index}
|
||||||
ref={(el) => (sectionRefs.current[index] = el)}
|
ref={(el) => (sectionRefs.current[index] = el)}
|
||||||
style={{
|
className="timeline-page"
|
||||||
flex: "0 0 100%",
|
|
||||||
scrollSnapAlign: "center",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
padding: "2rem",
|
|
||||||
boxSizing: "border-box",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<h2>{item.title}</h2>
|
<div className="timeline-card">
|
||||||
<h3>{item.date}</h3>
|
<div className="timeline-card-header">
|
||||||
<p>{item.content}</p>
|
<span className="timeline-date">{item.date}</span>
|
||||||
<div style={{display: "flex", gap: "2rem", flexWrap: "wrap", justifyContent: "center"}}>
|
<h2>{item.title}</h2>
|
||||||
{adjustedSkills.filter((s) => s.level > 0).map((skill, sIndex) => (
|
</div>
|
||||||
<div
|
<p className="timeline-content">{item.content}</p>
|
||||||
key={`${skill.name}-${index}`}
|
<div className="timeline-skills">
|
||||||
className={currentSection === index ? "skill-card animate-skill" : "skill-card"}
|
{adjustedSkills.filter((s) => s.level > 0).map((skill, sIndex) => (
|
||||||
style={{
|
<span
|
||||||
textAlign: "center",
|
key={`${skill.name}-${index}`}
|
||||||
width: "120px",
|
className={`skill-badge skill-${getSkillLabel(skill.level).toLowerCase()}`}
|
||||||
animationDelay: `${sIndex * 100}ms`,
|
style={{ animationDelay: `${sIndex * 80}ms` }}
|
||||||
animationFillMode: "both"
|
>
|
||||||
}}
|
{getSkillEmoji(skill.name)} {skill.name}
|
||||||
>
|
<span className="skill-level">{getSkillLabel(skill.level)}</span>
|
||||||
<p style={{fontWeight: "bold"}}>{skill.name}</p>
|
</span>
|
||||||
<div style={{
|
))}
|
||||||
padding: "0.5rem 1rem",
|
</div>
|
||||||
backgroundColor: "#1a001a",
|
|
||||||
border: "2px solid #3d003d",
|
|
||||||
borderRadius: "10px",
|
|
||||||
color: "#fff"
|
|
||||||
}}>
|
|
||||||
{getSkillLabel(skill.level)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{currentSection > 0 && (
|
{currentSection > 0 && (
|
||||||
<button onClick={() => handleButtonClick(-1)} style={{
|
<button
|
||||||
position: "absolute",
|
onClick={() => handleButtonClick(-1)}
|
||||||
top: "50%",
|
className="timeline-arrow-btn left"
|
||||||
left: "1rem",
|
aria-label="Previous"
|
||||||
transform: "translateY(-50%)",
|
>
|
||||||
zIndex: 10,
|
|
||||||
backgroundColor: "#333",
|
|
||||||
color: "#fff",
|
|
||||||
border: "none",
|
|
||||||
padding: "0.75rem 1rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
borderRadius: "4px"
|
|
||||||
}}>
|
|
||||||
←
|
←
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{currentSection < timelineData.length - 1 && (
|
{currentSection < timelineData.length - 1 && (
|
||||||
<button onClick={() => handleButtonClick(1)} style={{
|
<button
|
||||||
position: "absolute",
|
onClick={() => handleButtonClick(1)}
|
||||||
top: "50%",
|
className="timeline-arrow-btn right"
|
||||||
right: "1rem",
|
aria-label="Next"
|
||||||
transform: "translateY(-50%)",
|
>
|
||||||
zIndex: 10,
|
|
||||||
backgroundColor: "#333",
|
|
||||||
color: "#fff",
|
|
||||||
border: "none",
|
|
||||||
padding: "0.75rem 1rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
borderRadius: "4px"
|
|
||||||
}}>
|
|
||||||
→
|
→
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
+242
-14
@@ -24,7 +24,9 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.textLeft {
|
.textLeft {
|
||||||
font-size: 2rem;
|
font-size: 1.5rem;
|
||||||
|
font-weight: 300;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
@@ -33,7 +35,7 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 2.5rem;
|
font-size: 3.5rem;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
@@ -70,7 +72,9 @@ html {
|
|||||||
|
|
||||||
.intro {
|
.intro {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
|
font-weight: 300;
|
||||||
color: #cccccc;
|
color: #cccccc;
|
||||||
|
max-width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-in-section {
|
.fade-in-section {
|
||||||
@@ -107,13 +111,6 @@ html {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttonLeft {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.learnMoreButton {
|
.learnMoreButton {
|
||||||
padding: 1rem 2rem;
|
padding: 1rem 2rem;
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
@@ -130,9 +127,18 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes pulsePrompt {
|
@keyframes pulsePrompt {
|
||||||
0% { opacity: 0.6; transform: translateY(0); }
|
0% {
|
||||||
50% { opacity: 1; transform: translateY(-5px); }
|
opacity: 0.6;
|
||||||
100% { opacity: 0.6; transform: translateY(0); }
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0.6;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -300,6 +306,182 @@ body {
|
|||||||
transition: opacity 0.3s ease-out, transform 0.3s ease-out;
|
transition: opacity 0.3s ease-out, transform 0.3s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-page {
|
||||||
|
flex: 0 0 100%;
|
||||||
|
scroll-snap-align: center;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 2rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-card {
|
||||||
|
background: rgba(30, 0, 40, 0.93);
|
||||||
|
border-radius: 2rem;
|
||||||
|
border-left: 6px solid #a832a8;
|
||||||
|
box-shadow: 0 8px 36px #2d004666, 0 1.5px 6px #0002;
|
||||||
|
padding: 2.5rem 2.5rem 2rem 2rem;
|
||||||
|
max-width: 520px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.5rem;
|
||||||
|
position: relative;
|
||||||
|
animation: timelineCardIn 0.7s cubic-bezier(.39, .58, .57, 1.01);
|
||||||
|
/* Optional: subtle fade-in effect */
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes timelineCardIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px) scale(0.98);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-card-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-date {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
background: linear-gradient(90deg, #a832a8, #d57fff);
|
||||||
|
padding: 0.4rem 1.1rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
box-shadow: 0 2px 10px #90009055;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-card h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-content {
|
||||||
|
color: #e5c4fa;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-skills {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.8rem;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
background: #1a001a;
|
||||||
|
border: 1.5px solid #3d003d;
|
||||||
|
border-radius: 999px;
|
||||||
|
color: #fff;
|
||||||
|
padding: 0.5rem 1.2rem 0.5rem 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
position: relative;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(12px) scale(0.95);
|
||||||
|
animation: skillBadgeIn 0.35s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes skillBadgeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(16px) scale(0.90);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-level {
|
||||||
|
margin-left: 0.7rem;
|
||||||
|
padding: 0.2rem 0.7rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #fff;
|
||||||
|
background: #350035;
|
||||||
|
opacity: 0.88;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-badge.skill-beginner .skill-level {
|
||||||
|
background: #455cad;
|
||||||
|
color: #c6dcff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-badge.skill-intermediate .skill-level {
|
||||||
|
background: #289672;
|
||||||
|
color: #e0ffe9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-badge.skill-advanced .skill-level {
|
||||||
|
background: #ffaa00;
|
||||||
|
color: #fffbe6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-badge.skill-expert .skill-level {
|
||||||
|
background: #a832a8;
|
||||||
|
color: #ffe0fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-badge:hover, .skill-badge:focus {
|
||||||
|
box-shadow: 0 2px 18px #a832a860;
|
||||||
|
transform: scale(1.06);
|
||||||
|
background: #2d0046;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.timeline-card {
|
||||||
|
max-width: 95vw;
|
||||||
|
padding: 1.2rem 0.8rem 1rem 0.8rem;
|
||||||
|
border-radius: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-card h2 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-content {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-date {
|
||||||
|
font-size: 0.93rem;
|
||||||
|
padding: 0.3rem 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-skills {
|
||||||
|
gap: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skill-badge {
|
||||||
|
font-size: 0.87rem;
|
||||||
|
padding: 0.36rem 0.75rem 0.36rem 0.66rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.animate-skill {
|
.animate-skill {
|
||||||
animation: fadeInSkill 0.6s ease-out forwards;
|
animation: fadeInSkill 0.6s ease-out forwards;
|
||||||
}
|
}
|
||||||
@@ -319,7 +501,6 @@ body {
|
|||||||
animation: fadeInButton 0.5s ease-out;
|
animation: fadeInButton 0.5s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === Navigation Styles === */
|
|
||||||
nav.navbar {
|
nav.navbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -374,7 +555,6 @@ nav.navbar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === Contact Page === */
|
|
||||||
.contact-list {
|
.contact-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -537,3 +717,51 @@ main {
|
|||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-arrow-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 1.5rem;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
z-index: 20;
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: linear-gradient(135deg, #a832a8 60%, #1a001a 100%);
|
||||||
|
box-shadow: 0 4px 20px #90009066;
|
||||||
|
border: none;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
line-height: 1;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s,
|
||||||
|
transform 0.18s cubic-bezier(.4, 2, .4, 1),
|
||||||
|
box-shadow 0.2s;
|
||||||
|
user-select: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-arrow-btn.right {
|
||||||
|
right: 1.5rem;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-arrow-btn:hover,
|
||||||
|
.timeline-arrow-btn:focus-visible {
|
||||||
|
background: linear-gradient(135deg, #d57fff 80%, #a832a8 100%);
|
||||||
|
transform: translateY(-50%) scale(1.08);
|
||||||
|
box-shadow: 0 0 30px #ff99ff99, 0 4px 20px #90009088;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.timeline-arrow-btn {
|
||||||
|
width: 46px;
|
||||||
|
height: 46px;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
left: 0.5rem;
|
||||||
|
right: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+7
-19
@@ -63,10 +63,15 @@ export default function Home() {
|
|||||||
<FadeInSection>
|
<FadeInSection>
|
||||||
<section className="section">
|
<section className="section">
|
||||||
<div className="textLeft">
|
<div className="textLeft">
|
||||||
<p>
|
<div>
|
||||||
I'm a passionate developer exploring web, game, and backend technologies with a focus on
|
I'm a passionate developer exploring web, game, and backend technologies with a focus on
|
||||||
innovation and creativity.
|
innovation and creativity.
|
||||||
</p>
|
<div className="buttonLeft">
|
||||||
|
<Link href="/about">
|
||||||
|
<button className="learnMoreButton">Learn More</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="imageRight">
|
<div className="imageRight">
|
||||||
<Image
|
<Image
|
||||||
@@ -78,23 +83,6 @@ export default function Home() {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</FadeInSection>
|
</FadeInSection>
|
||||||
<FadeInSection>
|
|
||||||
<section className="section">
|
|
||||||
<div className="imageLeft">
|
|
||||||
<Image
|
|
||||||
src="/images/portfolio2.jpg"
|
|
||||||
alt="Another project snapshot"
|
|
||||||
width={500}
|
|
||||||
height={300}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="buttonLeft">
|
|
||||||
<Link href="/about">
|
|
||||||
<button className="learnMoreButton">Learn More</button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</FadeInSection>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user