diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..7c28b83 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": false +} diff --git a/app/favicon.ico b/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/app/favicon.ico and /dev/null differ diff --git a/app/globals.css b/app/globals.css deleted file mode 100644 index f4bd77c..0000000 --- a/app/globals.css +++ /dev/null @@ -1,107 +0,0 @@ -:root { - --max-width: 1100px; - --border-radius: 12px; - --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", - "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", - "Fira Mono", "Droid Sans Mono", "Courier New", monospace; - - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; - - --primary-glow: conic-gradient( - from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg - ); - --secondary-glow: radial-gradient( - rgba(255, 255, 255, 1), - rgba(255, 255, 255, 0) - ); - - --tile-start-rgb: 239, 245, 249; - --tile-end-rgb: 228, 232, 233; - --tile-border: conic-gradient( - #00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080 - ); - - --callout-rgb: 238, 240, 241; - --callout-border-rgb: 172, 175, 176; - --card-rgb: 180, 185, 188; - --card-border-rgb: 131, 134, 135; -} - -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - - --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); - --secondary-glow: linear-gradient( - to bottom right, - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0.3) - ); - - --tile-start-rgb: 2, 13, 46; - --tile-end-rgb: 2, 5, 19; - --tile-border: conic-gradient( - #ffffff80, - #ffffff40, - #ffffff30, - #ffffff20, - #ffffff10, - #ffffff10, - #ffffff80 - ); - - --callout-rgb: 20, 20, 20; - --callout-border-rgb: 108, 108, 108; - --card-rgb: 100, 100, 100; - --card-border-rgb: 200, 200, 200; - } -} - -* { - box-sizing: border-box; - padding: 0; - margin: 0; -} - -html, -body { - max-width: 100vw; - overflow-x: hidden; -} - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} - -a { - color: inherit; - text-decoration: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } -} diff --git a/app/layout.tsx b/app/layout.tsx index 3314e47..36405a5 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,22 +1,36 @@ -import type { Metadata } from "next"; -import { Inter } from "next/font/google"; -import "./globals.css"; - -const inter = Inter({ subsets: ["latin"] }); +import type { Metadata } from "next" +import { GlobalStyle } from "@/styles/globalStyle" +import StyledComponentsRegistry from "@/lib/registry" +import Navbar from "@/components/navbar" export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", -}; + title: "HangerThem", + description: "Personal portfolio of HangerThem (Frank Borisjuk)", + authors: [ + { + name: "Frank Borisjuk", + url: "https://hangerthem.com", + }, + ], + creator: "Frank Borisjuk", + publisher: "Frank Borisjuk", + keywords: ["Portfolio", "Personal", "Frank Borisjuk", "HangerThem"], +} export default function RootLayout({ children, }: Readonly<{ - children: React.ReactNode; + children: React.ReactNode }>) { return ( - - {children} - - ); + + + + + + {children} + + + + ) } diff --git a/app/page.module.css b/app/page.module.css deleted file mode 100644 index 5c4b1e6..0000000 --- a/app/page.module.css +++ /dev/null @@ -1,230 +0,0 @@ -.main { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 6rem; - min-height: 100vh; -} - -.description { - display: inherit; - justify-content: inherit; - align-items: inherit; - font-size: 0.85rem; - max-width: var(--max-width); - width: 100%; - z-index: 2; - font-family: var(--font-mono); -} - -.description a { - display: flex; - justify-content: center; - align-items: center; - gap: 0.5rem; -} - -.description p { - position: relative; - margin: 0; - padding: 1rem; - background-color: rgba(var(--callout-rgb), 0.5); - border: 1px solid rgba(var(--callout-border-rgb), 0.3); - border-radius: var(--border-radius); -} - -.code { - font-weight: 700; - font-family: var(--font-mono); -} - -.grid { - display: grid; - grid-template-columns: repeat(4, minmax(25%, auto)); - max-width: 100%; - width: var(--max-width); -} - -.card { - padding: 1rem 1.2rem; - border-radius: var(--border-radius); - background: rgba(var(--card-rgb), 0); - border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; -} - -.card span { - display: inline-block; - transition: transform 200ms; -} - -.card h2 { - font-weight: 600; - margin-bottom: 0.7rem; -} - -.card p { - margin: 0; - opacity: 0.6; - font-size: 0.9rem; - line-height: 1.5; - max-width: 30ch; - text-wrap: balance; -} - -.center { - display: flex; - justify-content: center; - align-items: center; - position: relative; - padding: 4rem 0; -} - -.center::before { - background: var(--secondary-glow); - border-radius: 50%; - width: 480px; - height: 360px; - margin-left: -400px; -} - -.center::after { - background: var(--primary-glow); - width: 240px; - height: 180px; - z-index: -1; -} - -.center::before, -.center::after { - content: ""; - left: 50%; - position: absolute; - filter: blur(45px); - transform: translateZ(0); -} - -.logo { - position: relative; -} -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - .card:hover { - background: rgba(var(--card-rgb), 0.1); - border: 1px solid rgba(var(--card-border-rgb), 0.15); - } - - .card:hover span { - transform: translateX(4px); - } -} - -@media (prefers-reduced-motion) { - .card:hover span { - transform: none; - } -} - -/* Mobile */ -@media (max-width: 700px) { - .content { - padding: 4rem; - } - - .grid { - grid-template-columns: 1fr; - margin-bottom: 120px; - max-width: 320px; - text-align: center; - } - - .card { - padding: 1rem 2.5rem; - } - - .card h2 { - margin-bottom: 0.5rem; - } - - .center { - padding: 8rem 0 6rem; - } - - .center::before { - transform: none; - height: 300px; - } - - .description { - font-size: 0.8rem; - } - - .description a { - padding: 1rem; - } - - .description p, - .description div { - display: flex; - justify-content: center; - position: fixed; - width: 100%; - } - - .description p { - align-items: center; - inset: 0 0 auto; - padding: 2rem 1rem 1.4rem; - border-radius: 0; - border: none; - border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); - background: linear-gradient( - to bottom, - rgba(var(--background-start-rgb), 1), - rgba(var(--callout-rgb), 0.5) - ); - background-clip: padding-box; - backdrop-filter: blur(24px); - } - - .description div { - align-items: flex-end; - pointer-events: none; - inset: auto 0 0; - padding: 2rem; - height: 200px; - background: linear-gradient( - to bottom, - transparent 0%, - rgb(var(--background-end-rgb)) 40% - ); - z-index: 1; - } -} - -/* Tablet and Smaller Desktop */ -@media (min-width: 701px) and (max-width: 1120px) { - .grid { - grid-template-columns: repeat(2, 50%); - } -} - -@media (prefers-color-scheme: dark) { - .vercelLogo { - filter: invert(1); - } - - .logo { - filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); - } -} - -@keyframes rotate { - from { - transform: rotate(360deg); - } - to { - transform: rotate(0deg); - } -} diff --git a/app/page.tsx b/app/page.tsx index 8107090..a1ba88f 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,95 +1,19 @@ -import Image from "next/image"; -import styles from "./page.module.css"; +import HeroBanner from "@/components/heroBanner" +import About from "@/components/about" +import Divider from "@/components/divider" +import Techstack from "@/components/techstack" +import Projects from "@/components/projects" export default function Home() { return ( -
-
-

- Get started by editing  - app/page.tsx -

-
- - By{" "} - Vercel Logo - -
-
- -
- Next.js Logo -
- -
- -

- Docs -> -

-

Find in-depth information about Next.js features and API.

-
- - -

- Learn -> -

-

Learn about Next.js in an interactive course with quizzes!

-
- - -

- Templates -> -

-

Explore starter templates for Next.js.

-
- - -

- Deploy -> -

-

- Instantly deploy your Next.js site to a shareable URL with Vercel. -

-
-
-
- ); + <> + + + + + + + + + ) } diff --git a/components/about.tsx b/components/about.tsx new file mode 100644 index 0000000..1d05f2e --- /dev/null +++ b/components/about.tsx @@ -0,0 +1,81 @@ +"use client" + +import styled, { keyframes } from "styled-components" +import Image from "next/image" + +const AboutContainer = styled.section` + width: 100%; + height: 100vh; + padding: 2rem 0; + display: flex; + align-items: center; + justify-content: center; + gap: 2rem; +` + +const wave = keyframes` + 0% { + transform: rotate(-15deg); + } + 50% { + transform: rotate(15deg); + } + 100% { + transform: rotate(-15deg); + } +` + +const AboutContent = styled.div` + width: 50%; + display: flex; + flex-direction: column; + gap: 2rem; + + h2 { + font-size: 3rem; + font-weight: 600; + position: relative; + + &::before { + content: "👋"; + position: absolute; + left: -4rem; + transform-origin: 70% 70%; + animation: ${wave} 1s ease-in-out infinite; + } + } + + p { + font-size: 1.2rem; + font-weight: 400; + max-width: 600px; + } +` + +const AboutImage = styled.div` + img { + object-fit: cover; + object-position: center; + border-radius: 1rem; + } +` + +export default function About() { + return ( + + +

Hi! My name is Frank!

+

+ I am a passionate and innovative web developer based in Czech + Republic. Ever since I laid hands on my first line of code, I've been + captivated by the boundless possibilities of the web. With a curious + mind and a desire to stay on the cutting edge of technology, I + constantly seek new challenges that push my skills to the next level. +

+
+ + About us + +
+ ) +} diff --git a/components/divider.tsx b/components/divider.tsx new file mode 100644 index 0000000..4a6d077 --- /dev/null +++ b/components/divider.tsx @@ -0,0 +1,36 @@ +"use client" + +import styled from "styled-components" + +const DividerLine = styled.div` + width: 45%; + height: 1px; + background-color: rgba(var(--white), 0.5); + border: none; +` + +const DividerSquare = styled.div` + width: 1rem; + height: 1rem; + transform: rotate(45deg); + background-color: rgba(var(--white), 0.5); +` + +const DividerContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; +` + +const Divider = () => { + return ( + + + + + + ) +} + +export default Divider diff --git a/components/heroBanner.tsx b/components/heroBanner.tsx new file mode 100644 index 0000000..90ec4e3 --- /dev/null +++ b/components/heroBanner.tsx @@ -0,0 +1,82 @@ +"use client" + +import Image from "next/image" +import styled from "styled-components" + +const HeroContainer = styled.div` + position: relative; + width: 100%; + height: 100vh; + overflow: hidden; + + img { + object-fit: cover; + object-position: center; + width: 100%; + height: 100%; + } + + &::after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(var(--black), 0.5); + } +` + +const ScrollIndicator = styled.div` + position: absolute; + bottom: 5%; + left: 50%; + transform: translateX(-50%); + width: 2rem; + height: 4rem; + border: 2px solid rgb(var(--white)); + border-radius: 2rem; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + z-index: 100; + cursor: pointer; + + &::before { + content: ""; + width: 0.5rem; + height: 0.5rem; + background-color: rgb(var(--white)); + border-radius: 50%; + animation: scroll 2s infinite; + } + + @keyframes scroll { + 0% { + transform: translateY(1rem); + } + 100% { + opacity: 0; + transform: translateY(3rem); + } + } +` + +export default function HeroBanner() { + return ( + + Hero banner + + window.scrollTo({ top: window.innerHeight, behavior: "smooth" }) + } + /> + + ) +} diff --git a/components/navbar.tsx b/components/navbar.tsx new file mode 100644 index 0000000..25329ad --- /dev/null +++ b/components/navbar.tsx @@ -0,0 +1,93 @@ +"use client" + +import styled, { keyframes } from "styled-components" +import Logo from "@/icons/logo" +import Link from "next/link" + +const NavbarContainer = styled.nav` + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 2rem; + background-color: rgba(var(--background), 0.5); + backdrop-filter: blur(10px); + position: absolute; + width: calc(100% - 4rem); + margin: 2rem; + border-radius: 1rem; + z-index: 100; + + ul { + display: flex; + gap: 2rem; + li { + list-style: none; + font-size: 1.5rem; + font-weight: 600; + cursor: pointer; + + a { + text-decoration: none; + color: rgba(var(--black), 0.7); + transition: color 0.2s; + font-weight: 400; + &:hover { + color: rgba(var(--black), 1); + } + + &.active { + color: rgba(var(--white), 1); + font-weight: 600; + text-shadow: 0 4px 5px rgba(var(--black), 0.5); + } + } + } + } + + svg { + width: 4rem; + height: 4rem; + } +` + +const LogoWrapper = styled.div` + display: flex; + align-items: center; + gap: 1rem; + + h1 { + font-size: 2.5rem; + font-weight: 600; + color: rgb(var(--white)); + text-shadow: 0 4px 5px rgba(var(--black), 0.5); + } +` + +const Navbar = () => { + return ( + + + +

HangerThem

+
+
    +
  • + + Home + +
  • +
  • + About +
  • +
  • + Projects +
  • +
  • + Contact me +
  • +
+
+ ) +} + +export default Navbar diff --git a/components/projects.tsx b/components/projects.tsx new file mode 100644 index 0000000..52c4405 --- /dev/null +++ b/components/projects.tsx @@ -0,0 +1,45 @@ +"use client" + +import styled from "styled-components" +import UnderConstruction from "@/icons/underConstruction" + +const ProjectsContainer = styled.section` + width: 100%; + height: 100vh; + padding: 2rem 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2rem; + + svg { + width: 15rem; + height: 15rem; + } +` + +const ProjectsContent = styled.div` + width: 50%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 2rem; + + h2 { + font-size: 3rem; + font-weight: 600; + } +` + +export default function Projects() { + return ( + + +

Projects

+
+ +
+ ) +} diff --git a/components/techstack.tsx b/components/techstack.tsx new file mode 100644 index 0000000..b426cd1 --- /dev/null +++ b/components/techstack.tsx @@ -0,0 +1,45 @@ +"use client" + +import styled from "styled-components" +import UnderConstruction from "@/icons/underConstruction" + +const TechstackContainer = styled.section` + width: 100%; + height: 100vh; + padding: 2rem 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2rem; + + svg { + width: 15rem; + height: 15rem; + } +` + +const TechstackContent = styled.div` + width: 50%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 2rem; + + h2 { + font-size: 3rem; + font-weight: 600; + } +` + +export default function Techstack() { + return ( + + +

Tech Stack

+
+ +
+ ) +} diff --git a/icons/logo.tsx b/icons/logo.tsx new file mode 100644 index 0000000..4fc18ff --- /dev/null +++ b/icons/logo.tsx @@ -0,0 +1,100 @@ +const Logo = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +) + +export default Logo diff --git a/icons/underConstruction.tsx b/icons/underConstruction.tsx new file mode 100644 index 0000000..9fa7150 --- /dev/null +++ b/icons/underConstruction.tsx @@ -0,0 +1,22 @@ +const UnderConstruction = () => ( + + + + +) + +export default UnderConstruction diff --git a/lib/registry.tsx b/lib/registry.tsx new file mode 100644 index 0000000..31e0505 --- /dev/null +++ b/lib/registry.tsx @@ -0,0 +1,27 @@ +"use client" + +import React, { useState } from "react" +import { useServerInsertedHTML } from "next/navigation" +import { ServerStyleSheet, StyleSheetManager } from "styled-components" + +export default function StyledComponentsRegistry({ + children, +}: { + children: React.ReactNode +}) { + const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet()) + + useServerInsertedHTML(() => { + const styles = styledComponentsStyleSheet.getStyleElement() + styledComponentsStyleSheet.instance.clearTag() + return <>{styles} + }) + + if (typeof window !== "undefined") return <>{children} + + return ( + + {children} + + ) +} diff --git a/package-lock.json b/package-lock.json index 2d153e5..ef495d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,10 @@ "version": "0.1.0", "dependencies": { "next": "14.1.0", + "nodemailer": "^6.9.9", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "styled-components": "^6.1.8" }, "devDependencies": { "@types/node": "^20", @@ -42,6 +44,24 @@ "node": ">=6.9.0" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -430,6 +450,11 @@ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", "dev": true }, + "node_modules/@types/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" + }, "node_modules/@typescript-eslint/parser": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", @@ -903,6 +928,14 @@ "node": ">=6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001584", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001584.tgz", @@ -981,6 +1014,24 @@ "node": ">= 8" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -2800,6 +2851,14 @@ } } }, + "node_modules/nodemailer": { + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.9.tgz", + "integrity": "sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3089,6 +3148,11 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3414,6 +3478,11 @@ "node": ">= 0.4" } }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3662,6 +3731,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/styled-components": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.8.tgz", + "integrity": "sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==", + "dependencies": { + "@emotion/is-prop-valid": "1.2.1", + "@emotion/unitless": "0.8.0", + "@types/stylis": "4.2.0", + "css-to-react-native": "3.2.0", + "csstype": "3.1.2", + "postcss": "8.4.31", + "shallowequal": "1.1.0", + "stylis": "4.3.1", + "tslib": "2.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -3684,6 +3790,11 @@ } } }, + "node_modules/stylis": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/package.json b/package.json index 5756c7c..aed35b6 100644 --- a/package.json +++ b/package.json @@ -9,16 +9,18 @@ "lint": "next lint" }, "dependencies": { + "next": "14.1.0", + "nodemailer": "^6.9.9", "react": "^18", "react-dom": "^18", - "next": "14.1.0" + "styled-components": "^6.1.8" }, "devDependencies": { - "typescript": "^5", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "eslint": "^8", - "eslint-config-next": "14.1.0" + "eslint-config-next": "14.1.0", + "typescript": "^5" } } diff --git a/public/borisjuk_01.png b/public/borisjuk_01.png new file mode 100644 index 0000000..c26ee06 Binary files /dev/null and b/public/borisjuk_01.png differ diff --git a/public/hero-banner.jpg b/public/hero-banner.jpg new file mode 100644 index 0000000..5d00657 Binary files /dev/null and b/public/hero-banner.jpg differ diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index d2f8422..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/styles/globalStyle.ts b/styles/globalStyle.ts new file mode 100644 index 0000000..7af4a1f --- /dev/null +++ b/styles/globalStyle.ts @@ -0,0 +1,50 @@ +"use client" + +import { createGlobalStyle } from "styled-components" + +export const GlobalStyle = createGlobalStyle` + :root { + --primary: 201, 14, 14; + --white: 255, 255, 255; + --black: 0, 0, 0; + --background: 217, 217, 217; + --accent: 104, 104, 104; + } + + ::selection { + background-color: rgba(var(--primary), 0.5); + } + + *, + *::before, + *::after { + box-sizing: border-box; + margin: 0; + padding: 0; + + scrollbar-width: thin; + scrollbar-color: rgba(var(--primary), 0.5) rgba(var(--black), 0.5); + + &::-moz-selection { + background-color: rgba(var(--primary), 0.5); + } + + &::-webkit-scrollbar { + width: 0.5rem; + } + + &::-webkit-scrollbar-thumb { + background-color: rgba(var(--primary), 0.5); + } + + &::-webkit-scrollbar-track { + background-color: rgba(var(--black), 0.5); + } + } + + body { + font-family: 'K2D', sans-serif; + background-color: rgb(var(--black)); + color: rgb(var(--white)); + } +`