Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Netlify: https://portfolio-saraenderborg.netlify.app/
Figma:https://www.figma.com/design/er7xor6mcZzPVT8ZM0tY0w/Portfolio-designs?node-id=10817-954&t=SPZgu2bO284eVn9U-0
# Portfolio
3 changes: 3 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<link href="https://fonts.googleapis.com/css2?family=Hind:wght@300;400;500;600&family=Montserrat:wght@400;600;700&display=swap" rel="stylesheet" />

<title>Portfolio</title>
</head>
<body>
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react-dom": "^19.0.0",
"styled-components": "^6.1.19",
"swiper": "^12.0.3"
},
"devDependencies": {
"@eslint/js": "^9.21.0",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.3.4",
"babel-plugin-styled-components": "^2.1.4",
"eslint": "^9.21.0",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-refresh": "^0.4.19",
Expand Down
Binary file added public/Journey.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Pet-foster.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/balloons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/github.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
<path d="M12.1094 22.6562C12.1094 22.5625 12.0156 22.4688 11.875 22.4688C11.7344 22.4688 11.6406 22.5625 11.6406 22.6562C11.6406 22.75 11.7344 22.8438 11.875 22.7969C12.0156 22.7969 12.1094 22.75 12.1094 22.6562ZM10.6562 22.4219C10.6562 22.5156 10.75 22.6562 10.8906 22.6562C10.9844 22.7031 11.125 22.6562 11.1719 22.5625C11.1719 22.4688 11.125 22.375 10.9844 22.3281C10.8438 22.2812 10.7031 22.3281 10.6562 22.4219ZM12.7656 22.375C12.625 22.375 12.5312 22.4688 12.5312 22.6094C12.5312 22.7031 12.6719 22.75 12.8125 22.7031C12.9531 22.6562 13.0469 22.6094 13 22.5156C13 22.4219 12.8594 22.3281 12.7656 22.375ZM15.8125 4.375C9.34375 4.375 4.375 9.34375 4.375 15.8125C4.375 21.0156 7.60938 25.4688 12.2969 27.0625C12.9062 27.1562 13.0938 26.7812 13.0938 26.5C13.0938 26.1719 13.0938 24.5781 13.0938 23.5938C13.0938 23.5938 9.8125 24.2969 9.10938 22.1875C9.10938 22.1875 8.59375 20.8281 7.84375 20.5C7.84375 20.5 6.76562 19.75 7.89062 19.75C7.89062 19.75 9.0625 19.8438 9.71875 20.9688C10.75 22.7969 12.4375 22.2812 13.1406 21.9531C13.2344 21.2031 13.5156 20.6875 13.8906 20.3594C11.2656 20.0781 8.59375 19.7031 8.59375 15.2031C8.59375 13.8906 8.96875 13.2812 9.71875 12.4375C9.57812 12.1094 9.20312 10.8906 9.85938 9.25C10.7969 8.96875 13.0938 10.5156 13.0938 10.5156C14.0312 10.2344 15.0156 10.1406 16 10.1406C17.0312 10.1406 18.0156 10.2344 18.9531 10.5156C18.9531 10.5156 21.2031 8.92188 22.1875 9.25C22.8438 10.8906 22.4219 12.1094 22.3281 12.4375C23.0781 13.2812 23.5469 13.8906 23.5469 15.2031C23.5469 19.7031 20.7812 20.0781 18.1562 20.3594C18.5781 20.7344 18.9531 21.4375 18.9531 22.5625C18.9531 24.1094 18.9062 26.0781 18.9062 26.4531C18.9062 26.7812 19.1406 27.1562 19.75 27.0156C24.4375 25.4688 27.625 21.0156 27.625 15.8125C27.625 9.34375 22.3281 4.375 15.8125 4.375ZM8.92188 20.5469C8.82812 20.5938 8.875 20.7344 8.92188 20.8281C9.01562 20.875 9.10938 20.9219 9.20312 20.875C9.25 20.8281 9.25 20.6875 9.15625 20.5938C9.0625 20.5469 8.96875 20.5 8.92188 20.5469ZM8.40625 20.1719C8.35938 20.2656 8.40625 20.3125 8.5 20.3594C8.59375 20.4062 8.6875 20.4062 8.73438 20.3125C8.73438 20.2656 8.6875 20.2188 8.59375 20.1719C8.5 20.125 8.45312 20.125 8.40625 20.1719ZM9.90625 21.8594C9.85938 21.9062 9.85938 22.0469 10 22.1406C10.0938 22.2344 10.2344 22.2812 10.2812 22.1875C10.3281 22.1406 10.3281 22 10.2344 21.9062C10.1406 21.8125 10 21.7656 9.90625 21.8594ZM9.39062 21.1562C9.29688 21.2031 9.29688 21.3438 9.39062 21.4375C9.48438 21.5312 9.57812 21.5781 9.67188 21.5312C9.71875 21.4844 9.71875 21.3438 9.67188 21.25C9.57812 21.1562 9.48438 21.1094 9.39062 21.1562Z" fill="#FD6F00"/>
</svg>
Binary file added public/profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/weatherApp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 17 additions & 4 deletions src/App.jsx

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really clean! A small tip is to maybe add a main-tag, and/or change some sections to to instead be header- and footer elements to improve accessibility scoring on Lighthouse :-)

Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
export const App = () => {
import Contact from "./sections/Contact/Contact";
import Hero from "./sections/Hero/Hero";
import Skills from "./sections/Skills/Skills";
import Projects from "./sections/Projects/Projects";
import Tech from "./sections/Tech/Tech";
import Journey from "./sections/Journey/Journey";

function App() {
return (
<>
<h1>Portfolio</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatem, laborum! Maxime animi nostrum facilis distinctio neque labore consectetur beatae eum ipsum excepturi voluptatum, dicta repellendus incidunt fugiat, consequatur rem aperiam.</p>
<Hero />
<Skills />
<Projects />
<Tech />
<Journey />
<Contact />
</>
)
);
}

export default App;
14 changes: 14 additions & 0 deletions src/assets/icons/Github.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const Github = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
>
<path
d="M12.1094 22.6562C12.1094 22.5625 12.0156 22.4688 11.875 22.4688C11.7344 22.4688 11.6406 22.5625 11.6406 22.6562C11.6406 22.75 11.7344 22.8438 11.875 22.7969C12.0156 22.7969 12.1094 22.75 12.1094 22.6562ZM10.6562 22.4219C10.6562 22.5156 10.75 22.6562 10.8906 22.6562C10.9844 22.7031 11.125 22.6562 11.1719 22.5625C11.1719 22.4688 11.125 22.375 10.9844 22.3281C10.8438 22.2812 10.7031 22.3281 10.6562 22.4219ZM12.7656 22.375C12.625 22.375 12.5312 22.4688 12.5312 22.6094C12.5312 22.7031 12.6719 22.75 12.8125 22.7031C12.9531 22.6562 13.0469 22.6094 13 22.5156C13 22.4219 12.8594 22.3281 12.7656 22.375ZM15.8125 4.375C9.34375 4.375 4.375 9.34375 4.375 15.8125C4.375 21.0156 7.60938 25.4688 12.2969 27.0625C12.9062 27.1562 13.0938 26.7812 13.0938 26.5C13.0938 26.1719 13.0938 24.5781 13.0938 23.5938C13.0938 23.5938 9.8125 24.2969 9.10938 22.1875C9.10938 22.1875 8.59375 20.8281 7.84375 20.5C7.84375 20.5 6.76562 19.75 7.89062 19.75C7.89062 19.75 9.0625 19.8438 9.71875 20.9688C10.75 22.7969 12.4375 22.2812 13.1406 21.9531C13.2344 21.2031 13.5156 20.6875 13.8906 20.3594C11.2656 20.0781 8.59375 19.7031 8.59375 15.2031C8.59375 13.8906 8.96875 13.2812 9.71875 12.4375C9.57812 12.1094 9.20312 10.8906 9.85938 9.25C10.7969 8.96875 13.0938 10.5156 13.0938 10.5156C14.0312 10.2344 15.0156 10.1406 16 10.1406C17.0312 10.1406 18.0156 10.2344 18.9531 10.5156C18.9531 10.5156 21.2031 8.92188 22.1875 9.25C22.8438 10.8906 22.4219 12.1094 22.3281 12.4375C23.0781 13.2812 23.5469 13.8906 23.5469 15.2031C23.5469 19.7031 20.7812 20.0781 18.1562 20.3594C18.5781 20.7344 18.9531 21.4375 18.9531 22.5625C18.9531 24.1094 18.9062 26.0781 18.9062 26.4531C18.9062 26.7812 19.1406 27.1562 19.75 27.0156C24.4375 25.4688 27.625 21.0156 27.625 15.8125C27.625 9.34375 22.3281 4.375 15.8125 4.375ZM8.92188 20.5469C8.82812 20.5938 8.875 20.7344 8.92188 20.8281C9.01562 20.875 9.10938 20.9219 9.20312 20.875C9.25 20.8281 9.25 20.6875 9.15625 20.5938C9.0625 20.5469 8.96875 20.5 8.92188 20.5469ZM8.40625 20.1719C8.35938 20.2656 8.40625 20.3125 8.5 20.3594C8.59375 20.4062 8.6875 20.4062 8.73438 20.3125C8.73438 20.2656 8.6875 20.2188 8.59375 20.1719C8.5 20.125 8.45312 20.125 8.40625 20.1719ZM9.90625 21.8594C9.85938 21.9062 9.85938 22.0469 10 22.1406C10.0938 22.2344 10.2344 22.2812 10.2812 22.1875C10.3281 22.1406 10.3281 22 10.2344 21.9062C10.1406 21.8125 10 21.7656 9.90625 21.8594ZM9.39062 21.1562C9.29688 21.2031 9.29688 21.3438 9.39062 21.4375C9.48438 21.5312 9.57812 21.5781 9.67188 21.5312C9.71875 21.4844 9.71875 21.3438 9.67188 21.25C9.57812 21.1562 9.48438 21.1094 9.39062 21.1562Z"
fill="#FD6F00"
/>
</svg>
);
14 changes: 14 additions & 0 deletions src/assets/icons/Linkedin.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const Linkedin = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
>
<path
d="M10.1875 25V10.9844H5.82812V25H10.1875ZM7.98438 9.10938C9.39062 9.10938 10.5156 7.9375 10.5156 6.53125C10.5156 5.17188 9.39062 4.04688 7.98438 4.04688C6.625 4.04688 5.5 5.17188 5.5 6.53125C5.5 7.9375 6.625 9.10938 7.98438 9.10938ZM26.4531 25H26.5V17.3125C26.5 13.5625 25.6562 10.6562 21.25 10.6562C19.1406 10.6562 17.7344 11.8281 17.125 12.9062H17.0781V10.9844H12.9062V25H17.2656V18.0625C17.2656 16.2344 17.5938 14.5 19.8438 14.5C22.0938 14.5 22.1406 16.5625 22.1406 18.2031V25H26.4531Z"
fill="#FD6F00"
/>
</svg>
);
60 changes: 60 additions & 0 deletions src/components/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import styled from "styled-components";

const StyledButton = styled.a`
display: inline-flex;
align-items: center;
justify-content: center;

font-size: ${({ theme }) => theme.typography.button.size};
font-weight: ${({ theme }) => theme.typography.button.weight};
line-height: ${({ theme }) => theme.typography.button.lineHeight};

height: ${({ theme }) => theme.buttons.height};
border-radius: ${({ theme }) => theme.buttons.radius};
padding: 0 ${({ theme }) => theme.buttons.paddingX};
gap: ${({ theme }) => theme.buttons.gap};

background-color: ${({ theme, $variant }) =>
theme.colors.button[$variant].bg};
color: ${({ theme, $variant }) => theme.colors.button[$variant].text};

border: ${({ theme, $variant }) =>
$variant === "secondary"
? `2px solid ${theme.colors.button.secondary.border}`
: "none"};

transition: all 0.2s ease;
cursor: pointer;

&:hover {
opacity: 0.9;
transform: translateY(-2px);
}

&:active {
transform: translateY(0);
}
`;

export default function Button({
href,
children,
variant = "primary",
ariaLabel,
title,
}) {
const label =
ariaLabel || (typeof children === "string" ? children : "Open link");
return (
<StyledButton
href={href}
target="_blank"
rel="noreferrer"
$variant={variant}
aria-label={label}
title={title || label}
>
{children}
</StyledButton>
);
}
56 changes: 56 additions & 0 deletions src/components/Card.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Button from "./Button";
import { Card as StyledCard } from "./Card.styles";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment in Card.styles.jsx


export default function Card({
image,
title,
description,
date,
text,
demo,
code,
link,
buttonText = "Read more",
}) {
return (
<StyledCard>
<img src={image} alt={title} />

{date && <p style={{ fontSize: "0.8rem", opacity: 0.6 }}>{date}</p>}
<h3>{title}</h3>
<p>{description || text}</p>

<div style={{ display: "flex", gap: "1rem", flexWrap: "wrap" }}>
{demo && (
<Button
href={demo}
variant="primary"
ariaLabel={`Open live demo for ${title}`}
>
Live demo
</Button>
)}

{code && (
<Button
href={code}
variant="secondary"
ariaLabel={`${buttonText} about ${title}`}
>
View Code
</Button>
)}

{link && (
<Button
href={link}
variant="secondary"
ariaLabel={`${buttonText} about ${title}`}
>
{buttonText}
</Button>
)}
</div>
</StyledCard>
);
}
40 changes: 40 additions & 0 deletions src/components/Card.styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import styled from "styled-components";

export const Card = styled.article`
Copy link

@gabriellaberko gabriellaberko Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be easier to name is StyledCard directly here so you don't have to rename it in the import in Card.jsx :)

display: flex;
flex-direction: column;
height: 100%;
max-height: 520px;
background: white;
padding: 1.5rem;
border-radius: 16px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
transition: 0.2s ease;

&:hover {
transform: translateY(-3px);
}

img {
width: 100%;
height: 300px;
object-fit: cover;
border-radius: 12px;
margin-bottom: 16px;
}

h3 {
margin-bottom: 0.5rem;
font-family: ${({ theme }) => theme.fonts.heading};
}

p {
margin-bottom: 16px;
line-height: 1.5;
font-size: 15px;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
`;
79 changes: 79 additions & 0 deletions src/components/Carousel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import styled from "styled-components";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
import "swiper/css/scrollbar";
import { Scrollbar, Mousewheel } from "swiper/modules";

export const Carousel = ({ data, renderItem }) => {
return (
<CarouselWrapper>
<Swiper
modules={[Scrollbar, Mousewheel]}
scrollbar={{ draggable: true, hide: false }}
grabCursor={true}
mousewheel={{ forceToAxis: true, sensitivity: 1 }}
spaceBetween={64}
slidesPerView="auto"
speed={700}
freeMode={true}
watchOverflow={false}
>
{data.map((item, index) => (
<SwiperSlide key={index} className="slide" tabIndex={0}>
{renderItem(item, index)}
</SwiperSlide>
))}
</Swiper>
</CarouselWrapper>
);
};

const CarouselWrapper = styled.div`
margin-top: 64px;
padding: 0 64px;
width: 100%;
overflow: visible;

.swiper {
width: 100%;
padding-bottom: 80px;
}

.swiper-wrapper {
align-items: stretch;
}

.swiper-slide {
width: 400px !important;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using !important is a last resort. I guess you, in this case, want to override the css from swiper?
Duplicating the classname increases the specificity enough to overwrite it:

.swiper-slide.swiper-slide {
    width: 400px;
    ...
}

height: auto;
display: flex;
}

.swiper-scrollbar {
height: 12px;
background: #e5e5e5;
border-radius: 20px;
margin: 32px auto 0;
width: 80%;
cursor: pointer;
}

.swiper-scrollbar-drag {
background: ${({ theme }) => theme.colors.primary};
border-radius: 20px;
height: 100%;
cursor: grab;
}

.swiper-scrollbar-drag:active {
cursor: grabbing;
}

@media (max-width: 768px) {
padding: 0 20px;

.swiper-slide {
width: 300px !important;
}
}
`;
36 changes: 36 additions & 0 deletions src/components/SkillColumn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import styled from "styled-components";

const Column = styled.div`
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
text-align: center;
`;

const Title = styled.h3`
font-family: "Poppins", sans-serif;
font-weight: 500;
color: #202020;
margin: 0;
font-size: clamp(18px, 2vw, 22px);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! using clamp for font sizes is a really nice way of making it smooth.

`;

const Item = styled.p`
font-family: "Poppins", sans-serif;
color: #202020;
margin: 0;
font-size: clamp(13px, 1.5vw, 15px);
line-height: 1.6;
`;

export default function SkillColumn({ title, items }) {
return (
<Column>
<Title>{title}</Title>
{items.map((item) => (
<Item key={item}>{item}</Item>
))}
</Column>
);
}
Loading