BIN
public/portfolio/work_profile.png
Normal file
BIN
public/portfolio/work_profile.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
@@ -1,7 +1,7 @@
|
||||
import Intro from "@/src/portfolio/sections/Intro";
|
||||
import Projects from "@/src/portfolio/sections/Projects";
|
||||
import Experience from "@/src/portfolio/sections/Experience";
|
||||
import Achievements from "@/src/portfolio/sections/Achievements";
|
||||
import CurrentWork from "@/src/portfolio/sections/CurrentWork";
|
||||
import Footer from "@/src/portfolio/sections/Footer";
|
||||
import SkillsAndLinks from "@/src/portfolio/sections/SkillsAndLinks";
|
||||
|
||||
@@ -9,7 +9,7 @@ const MainPage = (): JSX.Element => {
|
||||
return (
|
||||
<div>
|
||||
<Intro/>
|
||||
<Achievements/>
|
||||
<CurrentWork/>
|
||||
<Experience/>
|
||||
<Projects/>
|
||||
<SkillsAndLinks/>
|
||||
|
||||
26
src/portfolio/data/currentWorkData.ts
Normal file
26
src/portfolio/data/currentWorkData.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export interface ICurrentWorkData {
|
||||
role: string;
|
||||
company: string;
|
||||
companyUrl: string;
|
||||
specialization: string;
|
||||
location: string;
|
||||
imagePath: string;
|
||||
paragraphs: string[];
|
||||
}
|
||||
|
||||
const currentWorkData: ICurrentWorkData = {
|
||||
role: "Technical Consultant",
|
||||
company: "Softwire",
|
||||
companyUrl: "https://www.softwire.com/",
|
||||
specialization: "AI Engineering",
|
||||
location: "Manchester, United Kingdom",
|
||||
imagePath: "/portfolio/work_profile.png",
|
||||
paragraphs: [
|
||||
"I spend much of my time <strong>designing and evaluating AI systems</strong>, or systems where AI plays a central role. My work involves the full lifecycle of AI implementation, from initial concept through to production deployment.",
|
||||
"I have <strong>delivered training and adoption materials</strong> that have significantly improved AI usage within Softwire, helping teams understand both the capabilities and limitations of AI technologies. I've also created <strong>autonomous AI pipelines</strong> that have reduced developer burden by automating tasks that were previously time-consuming manual processes.",
|
||||
"Working with <strong>diverse clients</strong> (from the highly skeptical to the enthusiastically optimistic), I've developed expertise in <strong>communicating AI benefits</strong> while respecting organizational constraints. This involves not just technical implementation, but also the human and ethical dimensions of AI adoption.",
|
||||
"A particular area of passion for me is <strong>Ethical AI and Sustainable AI</strong>. I've spent considerable time advocating for sustainability considerations in AI systems, conducting <strong>environmental assessments for embedded AI</strong>, and building adoption systems that leverage <strong>local open-source AI</strong> instead of relying on large providers whose ethical standards can be questionable."
|
||||
]
|
||||
};
|
||||
|
||||
export default currentWorkData;
|
||||
@@ -26,20 +26,6 @@ const educationData : EducationArgs[] = [
|
||||
"Recipient of the Westfield Trust Academic Prize",
|
||||
"Graduated with overall average at 90%"
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "High-school Education",
|
||||
subtitle: "advanced IT, Maths and Physics",
|
||||
institution: "Zamoyski High-school",
|
||||
city: "Warsaw",
|
||||
startDate: "Sep 2017",
|
||||
endDate: "Jul 2020",
|
||||
notes: [
|
||||
"Final exam in Computer Science: 98% percentile",
|
||||
"Final exam in Physics: 97% percentile",
|
||||
"Final exam in Mathematics: 92% percentile"
|
||||
],
|
||||
useWith: true //todo fix this (i.e. this does nothing)
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ const projectData : IProjectArguments[] = [
|
||||
],
|
||||
github: "https://github.com/KuchtaVR6/Multi-LLM-Agent",
|
||||
document: "/multiAgent.pdf",
|
||||
title: "Research Review of Neural Techniques for low-resource language translation",
|
||||
title: "Multi-LLM Tool Use – Modular Pipeline with Expert Adapters",
|
||||
text: "In this work, I explore a practical and cost-effective approach to improving how AI models interact with external tools and APIs. Instead of relying on large, expensive models or complex zero-shot learning methods, I utilize a modular pipeline using smaller, specialized components (Planner, Caller, Summariser) trained separately. I introduce to it a hard routing agent system that assigns tasks to expert adapters based on API categories, the system achieves performance that surpasses much larger closed-source models on a key benchmark. This approach enables more efficient, decentralized training and has potential applications beyond the tool-use QA task."
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
import { WorkExperienceArgs } from "@/src/portfolio/helpers/WorkExperience";
|
||||
|
||||
const workExperienceData : WorkExperienceArgs[] = [
|
||||
{
|
||||
industry: "Software & AI",
|
||||
title: "Technical Consultant",
|
||||
company: "Softwire",
|
||||
city: "Manchester",
|
||||
country: "United Kingdom",
|
||||
startDate: "November 2025"
|
||||
},
|
||||
{
|
||||
industry: "Software & AI",
|
||||
title: "Software Developer",
|
||||
company: "Softwire",
|
||||
city: "Manchester",
|
||||
country: "United Kingdom",
|
||||
startDate: "November 2024"
|
||||
startDate: "November 2024",
|
||||
endDate: "November 2025"
|
||||
},
|
||||
{
|
||||
industry: "Artificial Intelligence",
|
||||
@@ -109,8 +118,8 @@ export const workExperienceParagraph =
|
||||
"Mentor at Queen Mary University, where I later became a Laboratory Demonstrator. In the software industry, " +
|
||||
"I gained experience as a Software Developer Intern at Softwire. During my master's degree, I contributed to " +
|
||||
"the Artificial Intelligence industry as a Programming Data Annotator at DataAnnotation Tech. Upon graduation, " +
|
||||
"I accepted a full-time offer to join Softwire as a Software Developer in their North West office in Manchester, " +
|
||||
"known for its focus on innovation in the AI and Data sector. At Softwire, I have gained valuable experience " +
|
||||
"I accepted a full-time offer to join Softwire as a Software Developer in their North West office in Manchester. " +
|
||||
"In November 2025, I transitioned to Technical Consultant, AI Specialist. At Softwire, I have gained valuable experience " +
|
||||
"working on several AI projects, applying my theoretical machine learning knowledge to real-world problems. " +
|
||||
"Across these diverse roles, I have developed a strong work ethic and a broad set of transferable skills.";
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { FC, useState } from "react";
|
||||
import { CSSTransition } from "react-transition-group";
|
||||
import { FaChevronDown, FaChevronUp } from "react-icons/fa";
|
||||
|
||||
type AccordionArgs = {
|
||||
title : string,
|
||||
@@ -16,8 +17,10 @@ const Accordion : FC<AccordionArgs> = ({ title, children }): JSX.Element => {
|
||||
return (
|
||||
<div className="accordion">
|
||||
<div className="accordion-header" onClick={toggleAccordion}>
|
||||
<h2>{title} {isOpen ? "-" : "+"}</h2>
|
||||
<span></span>
|
||||
<h2>{title}</h2>
|
||||
<span className="accordion-icon">
|
||||
{isOpen ? <FaChevronUp /> : <FaChevronDown />}
|
||||
</span>
|
||||
</div>
|
||||
<CSSTransition in={isOpen} timeout={0} classNames="accordion-content" unmountOnExit>
|
||||
<div className="accordion-content">{children}</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { FC } from "react";
|
||||
import styles from "../styling/achievements.module.scss";
|
||||
import styles from "../styling/currentWork.module.scss";
|
||||
import Location from "./Location";
|
||||
|
||||
export type EducationArgs = {
|
||||
institution : string,
|
||||
@@ -14,48 +15,42 @@ export type EducationArgs = {
|
||||
|
||||
const Education : FC<EducationArgs> = (props) => {
|
||||
|
||||
const getCountryEmoji = (): string => {
|
||||
const getLocationString = (): string => {
|
||||
switch (props.city) {
|
||||
case "Warsaw":
|
||||
return ", Poland";
|
||||
return "Warsaw, Poland";
|
||||
case "London":
|
||||
return ", UK";
|
||||
return "London, UK";
|
||||
case "Edinburgh":
|
||||
return ", UK";
|
||||
return "Edinburgh, UK";
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ fontSize: "1.1em" }} className={styles.education} data-aos={"fade-right"}>
|
||||
<div>
|
||||
<span className={styles.title}>{props.title}</span> in <b>{props.subtitle}</b>
|
||||
<br/>
|
||||
at <i>{props.institution}</i>
|
||||
{props.notes?
|
||||
<ul className={styles.notes}>
|
||||
{props.notes.map((note, index) =>
|
||||
<li key={index}>
|
||||
{note}
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
: ""
|
||||
}
|
||||
<div className={styles.educationEntry} data-aos={"fade-up"}>
|
||||
<div className={styles.degree}>
|
||||
{props.title} in {props.subtitle}
|
||||
</div>
|
||||
<div className={styles.institution}>
|
||||
at {props.institution}
|
||||
</div>
|
||||
{props.notes && (
|
||||
<ul className={styles.notes}>
|
||||
{props.notes.map((note, index) => (
|
||||
<li key={index}>{note}</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
<div className={styles.details}>
|
||||
<Location city={getLocationString()} className={styles.location} />
|
||||
<div className={styles.dates}>
|
||||
{props.endDate ? (
|
||||
<span>{props.startDate} - {props.endDate}</span>
|
||||
) : (
|
||||
<span>Since {props.startDate}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<span className={styles.otherDetails}>
|
||||
<div className={styles.location}>{props.city}{getCountryEmoji()}</div>
|
||||
<hr/>
|
||||
{props.endDate ?
|
||||
<>
|
||||
<i>From: </i>
|
||||
<span style={{ float:"right" }}>{props.startDate}</span>
|
||||
<br/>
|
||||
<i>To: </i>
|
||||
<span style={{ float:"right" }}>{props.endDate}</span>
|
||||
</>:
|
||||
"Since " + props.startDate
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
18
src/portfolio/helpers/Location.tsx
Normal file
18
src/portfolio/helpers/Location.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { FC } from "react";
|
||||
import { FaMapMarkerAlt } from "react-icons/fa";
|
||||
|
||||
interface ILocationProps {
|
||||
city: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const Location: FC<ILocationProps> = ({ city, className }) => {
|
||||
return (
|
||||
<span className={className} style={{ display: "flex", alignItems: "center", gap: "0.3rem" }}>
|
||||
<FaMapMarkerAlt style={{ fontSize: "0.7em" }} />
|
||||
{city}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default Location;
|
||||
69
src/portfolio/sections/CurrentWork.tsx
Normal file
69
src/portfolio/sections/CurrentWork.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import Image from "next/image";
|
||||
import styles from "../styling/currentWork.module.scss";
|
||||
import currentWorkData from "@/src/portfolio/data/currentWorkData";
|
||||
import educationData from "@/src/portfolio/data/educationData";
|
||||
import Education from "@/src/portfolio/helpers/Education";
|
||||
import Location from "@/src/portfolio/helpers/Location";
|
||||
|
||||
const RoleInfo = (): JSX.Element => {
|
||||
return (
|
||||
<div className={styles.roleInfo}>
|
||||
<h3>{currentWorkData.role}</h3>
|
||||
<p className={styles.specialization}>
|
||||
Specializing in <strong>{currentWorkData.specialization}</strong>
|
||||
</p>
|
||||
<p className={styles.company}>
|
||||
at{" "}
|
||||
<a
|
||||
href={currentWorkData.companyUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={styles.companyLink}
|
||||
>
|
||||
{currentWorkData.company}
|
||||
</a>
|
||||
</p>
|
||||
<div className={styles.locationWrapper}>
|
||||
<Location city={currentWorkData.location} className={styles.location} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const CurrentWork = (): JSX.Element => {
|
||||
return (
|
||||
<div className={styles.section} id={"current-work"}>
|
||||
<div className={styles.mainContent}>
|
||||
<div className={styles.currentWorkSection}>
|
||||
<h2>What I'm Up To</h2>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.imageContainer} data-aos={"fade-right"}>
|
||||
<div className={styles.imageWrapper}>
|
||||
<Image
|
||||
src={currentWorkData.imagePath}
|
||||
alt="Patryk Kuchta at work"
|
||||
fill={true}
|
||||
className={styles.profileImage}
|
||||
/>
|
||||
</div>
|
||||
<RoleInfo />
|
||||
</div>
|
||||
<div className={styles.description} data-aos={"fade-left"}>
|
||||
{currentWorkData.paragraphs.map((paragraph, index) => (
|
||||
<p key={index} dangerouslySetInnerHTML={{ __html: paragraph }} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.educationSection}>
|
||||
<h2>Education</h2>
|
||||
{educationData.map((entry, index) => (
|
||||
<Education {...entry} key={index} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CurrentWork;
|
||||
@@ -1,9 +1,18 @@
|
||||
import Image from "next/image";
|
||||
import styles from "../styling/footer.module.scss";
|
||||
|
||||
const Footer = (): JSX.Element => {
|
||||
return (
|
||||
<footer className={styles.section}>
|
||||
Copyright © Patryk Kuchta {new Date().getFullYear()}
|
||||
<div className={styles.logoWrapper}>
|
||||
<Image
|
||||
src="/portfolio/white_logo.png"
|
||||
alt="Patryk Kuchta Logo"
|
||||
fill={true}
|
||||
className={styles.logo}
|
||||
/>
|
||||
</div>
|
||||
<p>Copyright © Patryk Kuchta {new Date().getFullYear()}</p>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -30,6 +30,8 @@ const IntroContent = ({ greeting }: IIntroContentProps): JSX.Element => {
|
||||
src={profilePic}
|
||||
alt={"Frontal image showing Patryk Kuchta"}
|
||||
fill={true}
|
||||
priority={true}
|
||||
placeholder="blur"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,68 +1,67 @@
|
||||
import styles from "../../styling/skillsLinks.module.scss";
|
||||
import { FaGithub, FaLinkedin, FaFilePdf, FaEnvelope } from "react-icons/fa";
|
||||
|
||||
interface ILink {
|
||||
title: string;
|
||||
link: string;
|
||||
icon: JSX.Element;
|
||||
}
|
||||
|
||||
const moreInfoLinks: ILink[] = [
|
||||
{
|
||||
title: "Github",
|
||||
link: "https://github.com/KuchtaVR6/"
|
||||
link: "https://github.com/KuchtaVR6/",
|
||||
icon: <FaGithub />
|
||||
},
|
||||
{
|
||||
title: "LinkedIn",
|
||||
link: "https://linkedin.com/in/kuchtap"
|
||||
link: "https://linkedin.com/in/kuchtap",
|
||||
icon: <FaLinkedin />
|
||||
},
|
||||
{
|
||||
title: "Curriculum Vitae",
|
||||
link: "/PatrykKuchta_CV.pdf"
|
||||
link: "/PatrykKuchta_CV.pdf",
|
||||
icon: <FaFilePdf />
|
||||
}
|
||||
];
|
||||
|
||||
const contactLinks: ILink[] = [
|
||||
{
|
||||
title: "Email",
|
||||
link: "mailto:patryk@kuchta.uk"
|
||||
link: "mailto:patryk@kuchta.uk",
|
||||
icon: <FaEnvelope />
|
||||
},
|
||||
{
|
||||
title: "LinkedIn",
|
||||
link: "https://linkedin.com/in/kuchtap"
|
||||
link: "https://linkedin.com/in/kuchtap",
|
||||
icon: <FaLinkedin />
|
||||
}
|
||||
];
|
||||
|
||||
const LinksSection = (): JSX.Element => {
|
||||
return (
|
||||
<div data-aos = {"fade-right"} className={styles.otherLinks}>
|
||||
<div data-aos={"fade-right"} className={styles.otherLinks}>
|
||||
<h2>Find out more about me:</h2>
|
||||
<ul>
|
||||
{
|
||||
moreInfoLinks.map(({ title, link }, key) => {
|
||||
return (
|
||||
<li key = {key}>
|
||||
<a href={link}>
|
||||
{title}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
{moreInfoLinks.map(({ title, link, icon }, key) => (
|
||||
<li key={key}>
|
||||
<a href={link} className={styles.linkWithIcon}>
|
||||
<span className={styles.icon}>{icon}</span>
|
||||
{title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<h2>Contact me through:</h2>
|
||||
<ul>
|
||||
{
|
||||
contactLinks.map(({ title, link }, key) => {
|
||||
return (
|
||||
<li key = {key}>
|
||||
<a href={link}>
|
||||
{title}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
{contactLinks.map(({ title, link, icon }, key) => (
|
||||
<li key={key}>
|
||||
<a href={link} className={styles.linkWithIcon}>
|
||||
<span className={styles.icon}>{icon}</span>
|
||||
{title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,41 +1,58 @@
|
||||
import styles from "../../styling/skillsLinks.module.scss";
|
||||
import SkillDisplay from "@/src/portfolio/helpers/SkillDisplay";
|
||||
import Accordion from "@/src/portfolio/helpers/Accordion";
|
||||
import { skillsInCategories } from "@/src/portfolio/data/skillsData";
|
||||
import { modulesTaken } from "@/src/portfolio/data/modulesTaken";
|
||||
import certificateData from "@/src/portfolio/data/certificateData";
|
||||
|
||||
const renderSkillItem = (name: string, level: string): JSX.Element => (
|
||||
<div className={styles.technology} key={name}>
|
||||
<b>{name}</b>
|
||||
<span style={{ float: "right", fontSize: "0.8em" }}>
|
||||
<i>{level}</i>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
const SkillsSection = (): JSX.Element => {
|
||||
return (
|
||||
<div data-aos = {"fade-left"} className={styles.skills}>
|
||||
<div>
|
||||
<i>Press the "+" to expand a section</i> 👀
|
||||
</div>
|
||||
<div data-aos={"fade-left"} className={styles.skills}>
|
||||
<div className={styles.innerskills}>
|
||||
{
|
||||
Object.entries(skillsInCategories).map(([category, skills]) => {
|
||||
return <Accordion title={category} key={category}>
|
||||
{
|
||||
skills.map((skill) => {
|
||||
return <SkillDisplay {...skill} key={skill.name} />;
|
||||
})
|
||||
}
|
||||
</Accordion>;
|
||||
})
|
||||
}
|
||||
<Accordion title={"Certificates and Awards"}>
|
||||
{certificateData.map(({ title, institution, awardDate }, index) => (
|
||||
<div className={styles.technology} key={index}>
|
||||
<b>{title}</b>
|
||||
<span style={{ float: "right", fontSize: "0.8em" }}>
|
||||
<i>{institution}</i> - {awardDate}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</Accordion>
|
||||
|
||||
<Accordion title={"Modules Taken"}>
|
||||
{
|
||||
modulesTaken.map(({ name, level, score }) => {
|
||||
return <div id={name.toLowerCase()}
|
||||
className={styles.technology}
|
||||
key={name}>
|
||||
<b>{name} </b>
|
||||
<span style={{ float: "right", fontSize: "0.8em" }}>
|
||||
{score>=0? score + "%" : "🔮"} <i>{level}</i>
|
||||
</span>
|
||||
</div>;
|
||||
})
|
||||
}
|
||||
{modulesTaken.map(({ name, level, score }) => (
|
||||
<div id={name.toLowerCase()} className={styles.technology} key={name}>
|
||||
<b>{name}</b>
|
||||
<span style={{ float: "right", fontSize: "0.8em" }}>
|
||||
{score >= 0 ? score + "%" : "N/A"} <i>{level}</i>
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</Accordion>
|
||||
|
||||
<Accordion title={"Human languages"}>
|
||||
{skillsInCategories["Human languages"].map((skill) => renderSkillItem(skill.name, skill.level))}
|
||||
</Accordion>
|
||||
|
||||
<Accordion title={"Programming Languages"}>
|
||||
{skillsInCategories["Programming Languages"].map((skill) => renderSkillItem(skill.name, skill.level))}
|
||||
</Accordion>
|
||||
|
||||
<Accordion title={"Frameworks/Libraries"}>
|
||||
{skillsInCategories["Frameworks/Libraries"].map((skill) => renderSkillItem(skill.name, skill.level))}
|
||||
</Accordion>
|
||||
|
||||
<Accordion title={"Miscellaneous"}>
|
||||
{skillsInCategories["Miscellaneous"].map((skill) => renderSkillItem(skill.name, skill.level))}
|
||||
</Accordion>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,39 +16,4 @@
|
||||
& > div {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.education {
|
||||
text-align: left;
|
||||
background-color: transparentize($gray, 0.5);
|
||||
padding: 1em;
|
||||
margin: 1em;
|
||||
border-radius: $smallGap;
|
||||
box-shadow: 0.5em 0.5em transparentize($black, 0.5);
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
column-gap: $mediumGap;
|
||||
row-gap: $smallGap;
|
||||
|
||||
|
||||
.title {
|
||||
color: $accent_colour;
|
||||
}
|
||||
|
||||
.notes {
|
||||
font-size: 0.9em;
|
||||
margin-top: 0.4em;
|
||||
}
|
||||
|
||||
.otherDetails {
|
||||
margin: auto 0 auto auto;
|
||||
|
||||
.location {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
}
|
||||
}
|
||||
223
src/portfolio/styling/currentWork.module.scss
Normal file
223
src/portfolio/styling/currentWork.module.scss
Normal file
@@ -0,0 +1,223 @@
|
||||
@import "/src/styles/helpers";
|
||||
|
||||
.section {
|
||||
@include lightSection;
|
||||
@include regularFont;
|
||||
|
||||
padding: 3rem 1rem;
|
||||
overflow-x: hidden;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 3rem;
|
||||
color: $accent_colour;
|
||||
}
|
||||
}
|
||||
|
||||
.mainContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3rem;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
flex-direction: row;
|
||||
gap: 2rem;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
.currentWorkSection {
|
||||
@media (min-width: 1280px) {
|
||||
flex: 1 1 54%;
|
||||
padding-right: 2rem;
|
||||
border-right: 2px solid $accent_colour;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
color: $accent_colour;
|
||||
}
|
||||
}
|
||||
|
||||
.educationSection {
|
||||
@media (min-width: 1280px) {
|
||||
flex: 1 1 42%;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
@media (max-width: 1279px) {
|
||||
padding-top: 2rem;
|
||||
border-top: 2px solid $accent_colour;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
font-size: 1.75rem;
|
||||
margin-bottom: 1.5rem;
|
||||
color: $accent_colour;
|
||||
}
|
||||
}
|
||||
|
||||
.educationEntry {
|
||||
background-color: transparentize($gray, 0.85);
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid $accent_colour;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.degree {
|
||||
font-weight: bold;
|
||||
color: $accent_colour;
|
||||
font-size: 1rem;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.institution {
|
||||
font-style: italic;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.notes {
|
||||
font-size: 0.85rem;
|
||||
margin: 0.5rem 0;
|
||||
padding-left: 1rem;
|
||||
|
||||
li {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 0.8rem;
|
||||
color: #999;
|
||||
margin-top: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
|
||||
@media (min-width: 900px) {
|
||||
flex-direction: row;
|
||||
gap: 2rem;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
@media (max-width: 899px) {
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.imageContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
flex-shrink: 0;
|
||||
|
||||
@media (min-width: 900px) {
|
||||
flex: 0 0 25%;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.imageWrapper {
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.profileImage {
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
border: 4px solid $accent_colour;
|
||||
}
|
||||
|
||||
.roleInfo {
|
||||
text-align: center;
|
||||
|
||||
h3 {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: $accent_colour;
|
||||
}
|
||||
|
||||
.company {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.specialization {
|
||||
font-style: italic;
|
||||
color: #666;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.locationWrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.location {
|
||||
font-size: 0.75rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.companyLink {
|
||||
color: rgb(0, 214, 254);
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.8rem;
|
||||
|
||||
@media (min-width: 900px) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.7;
|
||||
text-align: justify;
|
||||
font-size: 0.9rem;
|
||||
margin: 0;
|
||||
|
||||
@media (max-width: 899px) {
|
||||
text-align: left;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
width: 42em;
|
||||
max-width: 70vw;
|
||||
line-height: 1.7;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,35 @@
|
||||
@import "@/src/styles/helpers.scss";
|
||||
|
||||
.section {
|
||||
@include darkSection;
|
||||
@include regularFont;
|
||||
@include darkSection;
|
||||
@include regularFont;
|
||||
|
||||
padding: 0.4em;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem 2rem;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
.logoWrapper {
|
||||
position: relative;
|
||||
width: 3rem;
|
||||
height: 1.5rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
object-fit: contain;
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -46,11 +46,17 @@
|
||||
|
||||
.left{
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
a {
|
||||
font-size: 1em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.logoContainer {
|
||||
|
||||
@@ -1,53 +1,103 @@
|
||||
@import "@/src/styles/helpers.scss";
|
||||
|
||||
.section {
|
||||
@include lightSection;
|
||||
@include regularFont;
|
||||
@include lightSection;
|
||||
@include regularFont;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
flex-wrap: wrap;
|
||||
gap: 3rem;
|
||||
|
||||
padding: 0 6em 3em;
|
||||
padding: 3rem 2rem;
|
||||
|
||||
.skills {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
.innerskills {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
gap: $mediumGap;
|
||||
flex-wrap: wrap;
|
||||
flex-basis: 60%;
|
||||
}
|
||||
flex-wrap: wrap;
|
||||
flex-basis: 60%;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
|
||||
.otherLinks{
|
||||
margin: auto 1em;
|
||||
padding: 1em 2em;
|
||||
background-color: $black;
|
||||
color: $white;
|
||||
.skills {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
flex-basis: 60%;
|
||||
min-width: 300px;
|
||||
|
||||
h2{
|
||||
font-size: 115%;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $white;
|
||||
text-decoration: none;
|
||||
.innerskills {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $accent_colour;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
.otherLinks {
|
||||
margin: auto 1em;
|
||||
padding: 1.5em 2.5em;
|
||||
background-color: $black;
|
||||
color: $white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
|
||||
h2 {
|
||||
font-size: 1.3rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $white;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1rem;
|
||||
|
||||
&:hover {
|
||||
color: $accent_colour;
|
||||
transform: translateX(5px);
|
||||
|
||||
.icon {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.linkWithIcon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 1.2rem;
|
||||
transition: transform 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.technology {
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid transparentize($gray, 0.5);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -43,30 +43,74 @@ body {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
border: 1px solid transparentize($gray, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background-color: $white;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
transition: box-shadow 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
padding: 1rem 1.5rem;
|
||||
cursor: pointer;
|
||||
background-color: transparentize($gray, 0.7);
|
||||
transition: background-color 0.2s ease;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
background-color: transparentize($gray, 0.5);
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: 1.2rem;
|
||||
color: $black;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.accordion-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1rem;
|
||||
color: $accent_colour;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.accordion-content {
|
||||
padding: 1.5rem;
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.accordion-content-enter {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.accordion-content-enter-active {
|
||||
opacity: 1;
|
||||
height: auto;
|
||||
transition: opacity 300ms, height 300ms;
|
||||
max-height: 2000px;
|
||||
transition: opacity 300ms ease-in-out, max-height 300ms ease-in-out;
|
||||
}
|
||||
|
||||
.accordion-content-exit {
|
||||
opacity: 1;
|
||||
height: auto;
|
||||
max-height: 2000px;
|
||||
}
|
||||
|
||||
.accordion-content-exit-active {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
transition: opacity 300ms, height 300ms;
|
||||
max-height: 0;
|
||||
transition: opacity 300ms ease-in-out, max-height 300ms ease-in-out;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
text-align: center;
|
||||
}
|
||||
Reference in New Issue
Block a user