diff --git a/README.md b/README.md index 200f4282..11dc1d14 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -# Portfolio +Link netlify: https://portfoliofrida.netlify.app/ + diff --git a/index.html b/index.html index 6676fb2d..d6fe2e4b 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,41 @@ - - - - - Portfolio - - -
- - - + + + + + + + + + + + Portfolio + + + +
+ + + + \ No newline at end of file diff --git a/package.json b/package.json index 48911600..e1b01892 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,16 @@ }, "dependencies": { "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "react-markdown": "^10.1.0", + "styled-components": "^6.1.19" }, "devDependencies": { "@eslint/js": "^9.21.0", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", - "@vitejs/plugin-react": "^4.3.4", + "@vitejs/plugin-react": "^4.7.0", + "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", diff --git a/public/blogposts/post-1.md b/public/blogposts/post-1.md new file mode 100644 index 00000000..dacbb15f --- /dev/null +++ b/public/blogposts/post-1.md @@ -0,0 +1 @@ +Det här är mitt senaste blogginlägg. \ No newline at end of file diff --git a/public/blogposts/post-2.md b/public/blogposts/post-2.md new file mode 100644 index 00000000..f2c7b412 --- /dev/null +++ b/public/blogposts/post-2.md @@ -0,0 +1 @@ +Det här är mitt andra blogginlägg. \ No newline at end of file diff --git a/public/blogposts/post-3.md b/public/blogposts/post-3.md new file mode 100644 index 00000000..44edea3f --- /dev/null +++ b/public/blogposts/post-3.md @@ -0,0 +1 @@ +Det här är mitt första blogginlägg. \ No newline at end of file diff --git a/public/blogposts/post-4.md b/public/blogposts/post-4.md new file mode 100644 index 00000000..e69de29b diff --git a/src/App.jsx b/src/App.jsx index a161d8d3..944c4fb3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,8 +1,22 @@ +import React from "react"; +import "./index.css"; +import { Header } from "./components/sections/Header"; +import { Tech } from "./components/sections/Tech"; +import { Projects } from "./components/sections/Projects"; +import { Skills } from "./components/sections/Skills"; +import { Blog } from "./components/sections/Blog"; +import { Contacts } from "./components/sections/Contacts"; + + export const App = () => { return ( <> -

Portfolio

-

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.

+
+ + + + + - ) -} + ); +}; diff --git a/src/components/BlogData.js b/src/components/BlogData.js new file mode 100644 index 00000000..a53eba03 --- /dev/null +++ b/src/components/BlogData.js @@ -0,0 +1,23 @@ +import placeHolderImg from "../img/placeholderimg.png" + +export const blogData = [ + { + name: "Blog post", + framework: ["July 14th"], + description: "/blogposts/post-1.md", + image: placeHolderImg, + }, + + { + name: "Blog post", + framework: ["July 8th"], + description: "/blogposts/post-2.md", + image: placeHolderImg, + }, + { + name: "Blog post", + framework: ["July 1st"], + description: "/blogposts/post-3.md", + image: placeHolderImg, + }, +]; \ No newline at end of file diff --git a/src/components/UI/SectionTitle.jsx b/src/components/UI/SectionTitle.jsx new file mode 100644 index 00000000..b24441cd --- /dev/null +++ b/src/components/UI/SectionTitle.jsx @@ -0,0 +1,25 @@ +import styled from "styled-components"; + +// Section title h1 +export const SectionTitle = styled.h1` + margin-bottom: 24px; + font-size: 60px; + font-weight: bold; + text-align: center; + color: ${({ theme, dark }) => + dark ? theme.surface.dark.text : theme.surface.light.text}; +`; + +export const SubTitle = styled.h2` + font-size: ${({ theme }) => theme.typography.h2.fontSize}; + font-weight: ${({ theme }) => theme.typography.h2.fontWeight}; + color: ${({ theme, dark }) => + dark ? theme.surface.dark.text : theme.surface.light.text}; +`; + +export const Text = styled.p` + font-size: ${({ theme }) => theme.typography.p.fontSize}; + font-weight: ${({ theme }) => theme.typography.p.fontWeight}; + color: ${({ theme, dark }) => + dark ? theme.surface.dark.text : theme.surface.light.text}; +`; \ No newline at end of file diff --git a/src/components/items/BlogCard.jsx b/src/components/items/BlogCard.jsx new file mode 100644 index 00000000..09d1db21 --- /dev/null +++ b/src/components/items/BlogCard.jsx @@ -0,0 +1,88 @@ +import React, { useState, useEffect } from "react"; +import styled from "styled-components"; +import { SectionTitle, SubTitle, Text } from "../UI/SectionTitle"; +import { theme } from "../../theme"; +import { FrameWork } from "./frameworkbtn"; +import { DemoIcon } from "../../img/icons"; +import { ActionButton } from "../items/Buttons"; +import ReactMarkdown from "react-markdown"; + +// for styling component items +const WrapperBlog = styled.article` + display: grid; + gap: 1rem; + grid-template-columns: 1fr; + border-radius: 12px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); + padding: 1rem; + text-align: left; + + @media(min-width: ${theme.breakpoints.tablet}) { + grid-template-columns: 1fr 1fr; + padding: 3rem; + + } +`; +const BlogImage = styled.img` + width: 100%; + border-radius: 12px; + @media(min-width: ${theme.breakpoints.tablet}){ + width: 80%; + } + + +`; +const BlogInfo = styled.div` + display: flex; + flex-direction: column; +`; + +const ButtonIcon = styled.span` + display: flex; + align-items: center; + margin-left: 6px; + + svg { + width: 20px; + height: 20px; + } +`; + +export const BlogPost = ({ blog }) => { + const [content, setContent] = useState(""); + const [isOpen, setIsOpen] = useState(false); + + useEffect(() => { + if (blog.description) { + fetch(blog.description) + .then((res) => res.text()) + .then((text) => setContent(text)); + } + }, [blog.description]); + + // to open and close blog posts + const toggleOpen = () => setIsOpen(prev => !prev); + + return ( + + + + + {blog.name} + + + {isOpen && ( //get blog post from public/blogposts path + + {content} + + )} + + + {isOpen ? "Hide Article" : "Read Article"} + + + + ); +}; + + diff --git a/src/components/items/Buttons.jsx b/src/components/items/Buttons.jsx new file mode 100644 index 00000000..7e937c3b --- /dev/null +++ b/src/components/items/Buttons.jsx @@ -0,0 +1,53 @@ +import styled from "styled-components"; + + +const ButtonBase = styled.div` + background: black; + color: white; + display: flex; + align-items: center; + width: 60%; + max-width: 303px; + border-radius: 12px; + font-size: 16px; + font-family: inherit; + padding: 4px 12px; + gap: 16px; + margin-bottom: 13px; + text-decoration: none; + cursor: pointer; + + svg { + width: 20px; + height: 20px; + } + + &:hover { + transform: scale(1.1); + } +`; + +// for demo + github links +export const LinkButton = styled(ButtonBase).attrs({ as: "a" })` + text-decoration: underline; + `; + +// for read article +export const ActionButton = styled(ButtonBase).attrs({ as: "button" })` +`; + + + +//show more/less buttons: +export const ToggleButton = styled(ButtonBase).attrs({ as: "button" })` + background-color: ${({ $active }) => ($active ? "black" : "white")}; + color: ${({ $active }) => ($active ? "white" : "black")}; + border: 1px solid black; + border-radius: 12px; + padding: 4px 12px; + font-size: 16px; + width: auto; + display: flex; + margin: 30px auto 0; + cursor: pointer; + `; diff --git a/src/components/items/ProjectCard.jsx b/src/components/items/ProjectCard.jsx new file mode 100644 index 00000000..8b4594c3 --- /dev/null +++ b/src/components/items/ProjectCard.jsx @@ -0,0 +1,85 @@ +import React from "react"; +import styled from "styled-components"; +import { SectionTitle, SubTitle, Text } from "../UI/SectionTitle"; +import { theme } from "../../theme"; +import { FrameWork } from "./frameworkbtn"; +import { LinkButton } from "../items/Buttons"; +import { DemoIcon, GithubIcon } from "../../img/icons"; + +// for styling component items +const Card = styled.div` + display: grid; + grid-template-columns: 1fr; + gap: 40px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); + border-radius: 12px; + padding: 1rem; + text-align: left; + margin-bottom: 20px; + + @media (min-width: ${theme.breakpoints.tablet}){ + padding: 5rem; + } + + @media (min-width: ${theme.breakpoints.desktop}) { + grid-template-columns: 1fr 1fr; + gap: 10px; + margin-bottom: 40px; + padding: 5rem; + + &:nth-child(even) { + direction: rtl; + + img, + div { + direction: ltr; + } + } + } +`; + +//project image +const ProjectImage = styled.img` + width: 100%; + border-radius: 12px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); + + @media (min-width: ${theme.breakpoints.desktop}) { + width: 80%; + } +`; + +//project content +const ProjectInfo = styled.div``; + +//button icon +const ButtonIcon = styled.div` + display: flex; + align-items: center; + margin-left: 6px; + + svg { + width: 20px; + height: 20px; + } +`; + + +export const ProjectCard = ({ project }) => ( + + + + + {project.name} + {project.description} +
+ + Live Demo + + + Github + +
+
+
+); diff --git a/src/components/items/frameworkbtn.jsx b/src/components/items/frameworkbtn.jsx new file mode 100644 index 00000000..1165eaf7 --- /dev/null +++ b/src/components/items/frameworkbtn.jsx @@ -0,0 +1,42 @@ +import React from 'react'; +import styled from 'styled-components'; + +// for styling component items +const FrameworkContainer = styled.div` + display: flex; + justify-content: flex-start; + gap: 0.5rem; + margin-bottom: 0.5rem; +`; +const FrameworkBox = styled.div` + border: 1px solid black; + border-radius: 4px; + padding: 2px 6px; + font-size: 14px; + max-width: 142px; + width: 100%; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + text-align: center; +`; + + +export const FrameWork = ({ frameworks }) => { + if (!frameworks) return null; + + const fwArray = Array.isArray(frameworks) ? frameworks : [frameworks]; + + return ( + + {fwArray.map((fw, index) => ( + {fw} + ))} + + ); +}; + + + + diff --git a/src/components/items/skillItem.jsx b/src/components/items/skillItem.jsx new file mode 100644 index 00000000..38735e87 --- /dev/null +++ b/src/components/items/skillItem.jsx @@ -0,0 +1,9 @@ +import React from "react"; +import styled from "styled-components"; + +// for styling component items +const Item = styled.li` + margin-bottom: 6px; +`; + +export const SkillItem = ({ children }) => {children}; diff --git a/src/components/items/techItem.jsx b/src/components/items/techItem.jsx new file mode 100644 index 00000000..712598ca --- /dev/null +++ b/src/components/items/techItem.jsx @@ -0,0 +1,10 @@ +import React from "react"; +import styled from "styled-components"; + +// for styling component items +const Item = styled.div` + padding: 2px 8px; + font-size: 16px; +`; + +export const TechItem = ({ children }) => {children}; diff --git a/src/components/projectsData.js b/src/components/projectsData.js new file mode 100644 index 00000000..2e691267 --- /dev/null +++ b/src/components/projectsData.js @@ -0,0 +1,31 @@ +import projectimg1 from "../img/project-img1.png" +import projectimg2 from "../img/project-img2.png" +import projectimg3 from "../img/project-img3.png" +import placeHolderImg from "../img/placeholderimg.png"; + +export const projectsData = [ + { + name: "Weather app", + framework: ["HTML", "CSS", "Java Script"], + description: "The SMHI Weather App is an interactive web application that visualizes real-time Swedish meteorological data through an intuitive bubble-chart interface. This was my first mob-pairing project, and following a set design brief, I learned how to collaborate in real time, work with APIs, dynamically display data, and translate design specifications into a fully responsive, user-friendly web experience.", + demoLink: "https://weather-app-js-bubbles3.netlify.app/", + githubLink: "https://github.com/fridascript/js-project-weather-app", + image: projectimg3, + }, + { + name: "Project: Recipe Library", + framework: ["HTML", "CSS", "JavaScript"], + description: "Built a JavaScript-powered recipe library featuring search, categorisation and interactive filtering for a clean user experience. Designed and implemented a responsive UI with focus on usability and modular code structure for easy scalability", + demoLink: "https://js-project-recipe-library-frida.netlify.app/", + githubLink: "https://github.com/fridascript/js-project-recipe-library", + image: projectimg2, + }, + { + name: "Project: Company website", + framework: ["HTML", "CSS"], + description: "Developed a clean and responsive website for No Name Kafé, featuring their menu and an art-exhibition submission form. Designed with a minimal aesthetic to reflect the café’s brand and enhance user experience across devices.", + demoLink: "https://no-name-kafe.netlify.app/", + githubLink: "https://github.com/fridascript/js-project-business-site", + image: projectimg1 + } +]; \ No newline at end of file diff --git a/src/components/sections/Blog.jsx b/src/components/sections/Blog.jsx new file mode 100644 index 00000000..24047bdb --- /dev/null +++ b/src/components/sections/Blog.jsx @@ -0,0 +1,45 @@ +import React, { useState } from "react"; +import styled from "styled-components"; +import { SectionTitle, SubTitle, Text } from "../UI/SectionTitle"; +import { blogData } from "../BlogData"; +import { BlogPost } from "../items/BlogCard"; +import { ArrowIcon } from "../../img/icons"; +import { ToggleButton } from "../items/Buttons"; + +const BlogSection = styled.section` + background: ${({ theme }) => theme.surface.light.background}; + color: ${({ theme }) => theme.surface.light.text}; + padding: ${({ theme }) => theme.spacing.sectionY} 16px; + text-align: center; +`; + +const TogglebtnIcon = styled.div` + display: flex; + align-items: center; + margin-right: 6px; + + svg { + width: 20px; + height: 20px; + } +`; + +export const Blog = () => { + const [showAll, setShowAll] = useState(false); + const visibleCount = showAll ? blogData.length : 1; + + return ( + + My Words + + {blogData.slice(0, visibleCount).map((post, i) => ( + + ))} + + setShowAll(!showAll)}> + {!showAll && } + {showAll ? "Show fewer" : "See more articles"} + + + ); +}; diff --git a/src/components/sections/Contacts.jsx b/src/components/sections/Contacts.jsx new file mode 100644 index 00000000..a9091274 --- /dev/null +++ b/src/components/sections/Contacts.jsx @@ -0,0 +1,47 @@ +import React from "react"; +import styled from "styled-components"; +import { SectionTitle, SubTitle, Text } from "../UI/SectionTitle"; +import contactImg from "../../img/contactimg.png"; + +// for styling component +const Section = styled.section` + background: ${({ theme }) => theme.surface.dark.background}; + color: ${({ theme }) => theme.surface.dark.text}; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: ${({ theme }) => theme.spacing.sectionY} 16px; +`; +const ContactLink = styled.a` + color: ${({ theme }) => theme.surface.dark.text}; + text-decoration: none; + margin: 4px 0; +`; +const Image = styled.img` + width: 200px; + height: 200px; + border-radius: 50%; + object-fit: cover; + margin: 16px 0; +`; + +export const Contacts = () => { + return ( +
+ Let's Talk + Portrait of Frida Engman + Frida Engman + + +46 (0) 72 290 89 75 + + + + frida.r.engman@gmail.com + + +
+ ); +}; + + diff --git a/src/components/sections/Header.jsx b/src/components/sections/Header.jsx new file mode 100644 index 00000000..dbe52c4d --- /dev/null +++ b/src/components/sections/Header.jsx @@ -0,0 +1,38 @@ +import React from "react"; +import styled from "styled-components"; +import { SectionTitle, SubTitle, Text } from "../UI/SectionTitle"; +import headerImg from "../../img/headerimg.png"; + +// for styling component +const WrapperHeader = styled.header` + background: ${({ theme }) => theme.surface.light.background}; + color: ${({ theme }) => theme.surface.light.text}; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + margin-top: 40px; + padding: ${({ theme }) => theme.spacing.sectionY} 16px; +`; +const HeaderImage = styled.img` + width: 70%; + height: auto; + margin: 20px 0; +`; + +export const Header = () => { + return ( + + Hi there I am + Frida Engman + + + Creative Frontend Developer + + + Creative front-end developer with a passion for design, code, and human-centered + digital experiences. + + + ); +}; diff --git a/src/components/sections/Projects.jsx b/src/components/sections/Projects.jsx new file mode 100644 index 00000000..caaa8901 --- /dev/null +++ b/src/components/sections/Projects.jsx @@ -0,0 +1,45 @@ +import React, { useState } from "react"; +import styled from "styled-components"; +import { SectionTitle, SubTitle, Text } from "../UI/SectionTitle"; +import { projectsData } from "../projectsData"; +import { ProjectCard } from "../items/ProjectCard"; +import { ArrowIcon } from "../../img/icons"; +import { ToggleButton } from "../items/Buttons"; + +const Section = styled.section` + background: ${({ theme }) => theme.surface.light.background}; + color: ${({ theme }) => theme.surface.light.text}; + padding: ${({ theme }) => theme.spacing.sectionY} 16px; + text-align: center; +`; + +const Icon = styled.div` + display: flex; + align-items: center; + margin-right: 6px; + + svg { + width: 20px; + height: 20px; + } +`; + +export const Projects = () => { + const [showAll, setShowAll] = useState(false); + const visibleProjects = showAll ? projectsData.length : 2; + + return ( +
+ Featured Projects + + {projectsData.slice(0, visibleProjects).map((project, i) => ( + + ))} + + setShowAll(!showAll)}> + {!showAll && } + {showAll ? "Show fewer" : "See more projects"} + +
+ ); +}; diff --git a/src/components/sections/Skills.jsx b/src/components/sections/Skills.jsx new file mode 100644 index 00000000..685a26f7 --- /dev/null +++ b/src/components/sections/Skills.jsx @@ -0,0 +1,114 @@ +import React from "react"; +import styled from "styled-components"; +import { SectionTitle, SubTitle, Text } from "../UI/SectionTitle"; +import { theme } from "../../theme"; +import { SkillItem } from "../items/skillItem"; + +// for styling component +const Section = styled.section` + background: ${({ theme }) => theme.surface.dark.background}; + color: ${({ theme }) => theme.surface.dark.text}; + padding: ${({ theme }) => theme.spacing.sectionY} 16px; +`; +const SkillsContainer = styled.div` + display: flex; + flex-direction: column; + justify-content: flex-start; + gap: 40px; + margin-top: 20px; + + + /* Tablet */ + @media (min-width: ${theme.breakpoints.tablet}) and (max-width: ${theme.breakpoints.desktop}) { + flex-direction: column; + align-items: center; + } + + /*desktop*/ + @media (min-width: ${theme.breakpoints.desktop}) { + flex-direction: row; + justify-content: center; + } + +`; +const SkillColumn = styled.div` + display: flex; + flex-direction: column; + text-align: left; + align-items: flex-start; + + /* Tablet */ + @media (min-width: ${theme.breakpoints.tablet}) and (max-width: ${theme.breakpoints.desktop}) { + text-align: center; + align-items: center; + } + + /* Desktop */ + @media (min-width: ${theme.breakpoints.desktop}) { + text-align: left; + align-items: flex-start; + } +`; +const SkillHeadline = styled.h3` + border: 1px solid ${({ theme }) => theme.surface.dark.text}; + border-radius: 4px; + padding: 2px 16px; + margin-bottom: 16px; +`; +const SkillList = styled.ul` + list-style: none; + padding: 0; + margin: 0; +`; + +export const Skills = () => { + return ( +
+ Skills + + + + Code + + HTML5 + CSS3 + JavaScript ES6 + React + Styled Components + GitHub + + + + + Toolbox + + VS-code + Adobe Photoshop + Adobe Illustrator + Figma + Keynote + Slack + + + + + Upcoming + + Node.js + + + + + More + + Branding + Strategy + Process Design + Concept Development + Agile methodology + + + +
+ ); +}; diff --git a/src/components/sections/Tech.jsx b/src/components/sections/Tech.jsx new file mode 100644 index 00000000..48e8bcfa --- /dev/null +++ b/src/components/sections/Tech.jsx @@ -0,0 +1,51 @@ +import React from "react"; +import styled from "styled-components"; +import { SectionTitle, SubTitle, Text } from "../UI/SectionTitle"; +import { TechItem } from "../items/techItem"; + + +// for styling component +const Section = styled.section` + background: ${({ theme }) => theme.surface.dark.background}; + color: ${({ theme }) => theme.surface.dark.text}; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: ${({ theme }) => theme.spacing.sectionY} 16px; +`; +const List = styled.div` + display: flex; + flex-wrap: wrap; + justify-content: center; + margin-top: 16px; + max-width: 600px; +`; + +export const Tech = () => { + const techs = [ + "HTML", + "CSS", + "Flexbox", + "JavaScript", + "Web Accessibility", + "APIs", + "Mob-programming", + "Pair-programming", + "GitHub", + "ES6", + "JSX", + "React", + ]; + + return ( +
+ Tech + + {techs.map((t, i) => ( + {t} + ))} + +
+ ); +}; diff --git a/src/img/contactimg.png b/src/img/contactimg.png new file mode 100644 index 00000000..1f8eea1b Binary files /dev/null and b/src/img/contactimg.png differ diff --git a/src/img/headerimg.png b/src/img/headerimg.png new file mode 100644 index 00000000..7922b854 Binary files /dev/null and b/src/img/headerimg.png differ diff --git a/src/img/icons.jsx b/src/img/icons.jsx new file mode 100644 index 00000000..f850ea7b --- /dev/null +++ b/src/img/icons.jsx @@ -0,0 +1,35 @@ +export const GithubIcon = () => ( + + + +); + +export const DemoIcon = () => ( + + + +); + +export const ArrowIcon = () => ( + + + + +); + + diff --git a/src/img/placeholderimg.png b/src/img/placeholderimg.png new file mode 100644 index 00000000..6c390dbb Binary files /dev/null and b/src/img/placeholderimg.png differ diff --git a/src/img/project-img1.png b/src/img/project-img1.png new file mode 100644 index 00000000..07575310 Binary files /dev/null and b/src/img/project-img1.png differ diff --git a/src/img/project-img2.png b/src/img/project-img2.png new file mode 100644 index 00000000..e87bfacd Binary files /dev/null and b/src/img/project-img2.png differ diff --git a/src/img/project-img3.png b/src/img/project-img3.png new file mode 100644 index 00000000..ff3b9705 Binary files /dev/null and b/src/img/project-img3.png differ diff --git a/src/index.css b/src/index.css index 61010be6..075fd025 100644 --- a/src/index.css +++ b/src/index.css @@ -1,4 +1,16 @@ +/* global base styles */ + +/* font */ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&display=swap'); + + +/* body defaults */ body { - background: pink; - color: hotpink; + font-family: "Poppins", system-ui, -apple-system, BlinkMacSystemFont, + 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + margin: 0px; +} + +html { + scroll-behavior: smooth; } \ No newline at end of file diff --git a/src/main.jsx b/src/main.jsx index ed109d76..64ea52eb 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,12 +1,15 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' - +import React from "react"; +import { ThemeProvider } from "styled-components" import { App } from './App.jsx' - +import { theme } from "./theme" import './index.css' createRoot(document.getElementById('root')).render( - + + + , ) diff --git a/src/theme.js b/src/theme.js new file mode 100644 index 00000000..c3527100 --- /dev/null +++ b/src/theme.js @@ -0,0 +1,40 @@ +export const theme = { + surface: { + light: { + background: "#FFFFFF", + text: "#000000", + }, + dark: { + background: "#000000", + text: "#FFFFFF", + }, + }, + spacing: { + sectionY: "70px", + }, + + breakpoints: { + mobile: "320px", + tablet: "768px", + desktop: "1025px", + }, + + typography: { + h1: { + fontSize: "60px", + fontWeight: "bold", + textAlign: "center", + }, + h2: { + fontSize: "30px", + fontWeight: "500", + }, + p: { + fontSize: "16px", + fontWeight: "400", + }, + }, +}; + + + diff --git a/vite.config.js b/vite.config.js index 8b0f57b9..d133d633 100644 --- a/vite.config.js +++ b/vite.config.js @@ -3,5 +3,11 @@ import react from '@vitejs/plugin-react' // https://vite.dev/config/ export default defineConfig({ - plugins: [react()], + plugins: [ + react({ + babel: { + plugins: [['babel-plugin-styled-components', { displayName: true }]] + } + }) + ] })