diff --git a/package.json b/package.json
index c328055..12f1c3e 100644
--- a/package.json
+++ b/package.json
@@ -70,7 +70,7 @@
"typescript": "^4.6.3"
},
"engines": {
- "node": "14.x",
+ "node": ">=14.x",
"yarn": "1.x"
},
"browserslist": [
diff --git a/public/images/community/events/card01.png b/public/images/community/events/card01.png
new file mode 100644
index 0000000..7e483f6
Binary files /dev/null and b/public/images/community/events/card01.png differ
diff --git a/public/images/community/events/card02.png b/public/images/community/events/card02.png
new file mode 100644
index 0000000..cbecb58
Binary files /dev/null and b/public/images/community/events/card02.png differ
diff --git a/public/images/community/events/card03.png b/public/images/community/events/card03.png
new file mode 100644
index 0000000..c89b9bb
Binary files /dev/null and b/public/images/community/events/card03.png differ
diff --git a/public/images/community/events/card04.png b/public/images/community/events/card04.png
new file mode 100644
index 0000000..e94c603
Binary files /dev/null and b/public/images/community/events/card04.png differ
diff --git a/public/images/community/hero/arrow.svg b/public/images/community/hero/arrow.svg
new file mode 100644
index 0000000..ff75bfa
--- /dev/null
+++ b/public/images/community/hero/arrow.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/images/community/hero/hero.png b/public/images/community/hero/hero.png
new file mode 100644
index 0000000..af427d8
Binary files /dev/null and b/public/images/community/hero/hero.png differ
diff --git a/public/images/community/hero/hero2.png b/public/images/community/hero/hero2.png
new file mode 100644
index 0000000..b1e28ea
Binary files /dev/null and b/public/images/community/hero/hero2.png differ
diff --git a/public/images/community/socials/planet.png b/public/images/community/socials/planet.png
new file mode 100644
index 0000000..38ac11a
Binary files /dev/null and b/public/images/community/socials/planet.png differ
diff --git a/src/components/common/card/card.module.scss b/src/components/common/card/card.module.scss
new file mode 100644
index 0000000..b3e6b32
--- /dev/null
+++ b/src/components/common/card/card.module.scss
@@ -0,0 +1,72 @@
+@import '~/css/helpers';
+
+.cardContainer {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+
+ .eventHeader {
+ display: flex;
+ flex-direction: column;
+ gap: tovw(14px, 'default', 8px);
+ font-size: tovw(18px, 'default', 12px);
+ font-family: var(--font-dm-mono), sans-serif;
+ font-weight: 400;
+ line-height: 1.2;
+ letter-spacing: -0.02rem;
+
+ .date,
+ .hour {
+ display: flex;
+ align-items: center;
+ gap: tovw(10px, 'default', 6px);
+
+ svg {
+ height: tovw(18px, 'default', 12px);
+ margin-bottom: tovw(1px, 'default', 1px);
+ }
+ }
+
+ div {
+ display: flex;
+ gap: tovw(30px, 'default', 25px);
+ color: var(--color-grey-light);
+ }
+ }
+
+ .imageContainer {
+ margin: tovw(25px, 'default', 16px) 0;
+ width: 100%;
+ height: tovw(232px, 'default', 200px);
+ border-top: tovw(1px, 'default', 1px) solid var(--color-white);
+ border-bottom: tovw(1px, 'default', 1px) solid var(--color-white);
+
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+ }
+
+ .body {
+ display: flex;
+ flex-direction: column;
+ gap: tovw(24px, 'default', 18px);
+
+ a {
+ padding-top: tovw(20px, 'default', 12px);
+ width: fit-content;
+ }
+
+ p {
+ margin: 0;
+ font-weight: 400;
+ line-height: 1.4;
+ font-size: tovw(18px, 'default', 15px);
+
+ @media screen and (max-width: 800px) {
+ line-height: 1.6;
+ }
+ }
+ }
+}
diff --git a/src/components/common/card/index.tsx b/src/components/common/card/index.tsx
new file mode 100644
index 0000000..cf4a837
--- /dev/null
+++ b/src/components/common/card/index.tsx
@@ -0,0 +1,42 @@
+import { Calendar, Clock } from '~/components/icons/events'
+import Heading from '~/components/primitives/heading'
+import Link from '~/components/primitives/link'
+
+import s from './card.module.scss'
+
+interface Props {
+ className?: string
+ data?: any
+}
+
+function Card({ className, data }: Props) {
+ return (
+
+
+
{data?.location?.toUpperCase()}
+
+
+
+ {data?.date}
+
+
+
+ {data?.time} HS
+
+
+
+
+

+
+
+
+ {data?.title}
+
+
{data?.preview}
+
LEARN MORE
+
+
+ )
+}
+
+export default Card
diff --git a/src/components/icons/arrow.tsx b/src/components/icons/arrow.tsx
index 6c184b8..15b5917 100644
--- a/src/components/icons/arrow.tsx
+++ b/src/components/icons/arrow.tsx
@@ -65,4 +65,37 @@ const ArrowLink = ({
)
}
-export { Arrow, ArrowDotted, ArrowLink }
+const ArrowSlider = ({
+ className,
+ fill,
+ onClick,
+ disabled
+}: {
+ className?: string
+ fill?: string
+ onClick?: any
+ disabled?: any
+}) => {
+ return (
+
+ )
+}
+
+export { Arrow, ArrowDotted, ArrowLink, ArrowSlider }
diff --git a/src/components/icons/events.tsx b/src/components/icons/events.tsx
new file mode 100644
index 0000000..34b4d71
--- /dev/null
+++ b/src/components/icons/events.tsx
@@ -0,0 +1,28 @@
+const Calendar = ({ className }: { className?: string }) => {
+ return (
+
+ )
+}
+
+const Clock = ({ className }: { className?: string }) => {
+ return (
+
+ )
+}
+
+export { Calendar, Clock }
diff --git a/src/components/icons/socials.tsx b/src/components/icons/socials.tsx
index d748489..447bbc3 100644
--- a/src/components/icons/socials.tsx
+++ b/src/components/icons/socials.tsx
@@ -225,4 +225,28 @@ const Instagram = ({
)
}
-export { Facebook, Instagram, Linkedin, Reddit, Telegram, Twitter }
+const Discourse = ({
+ className,
+ fill
+}: {
+ className?: string
+ fill?: string
+}) => {
+ return (
+
+ )
+}
+
+export { Discourse, Facebook, Instagram, Linkedin, Reddit, Telegram, Twitter }
diff --git a/src/components/sections/community/events/events.module.scss b/src/components/sections/community/events/events.module.scss
new file mode 100644
index 0000000..425bc8a
--- /dev/null
+++ b/src/components/sections/community/events/events.module.scss
@@ -0,0 +1,123 @@
+@import '~/css/helpers';
+
+.section {
+ display: flex;
+ place-content: center;
+ align-items: center;
+ margin-top: tovw(55px, 'default', 20px);
+ padding: tovw(220px, 'default', 72px) 0;
+
+ .heading {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ border-bottom: tovw(1px, 'default', 1px) solid #fbfbfb;
+ padding-bottom: tovw(60px, 'default', 30px);
+ margin-bottom: tovw(80px, 'default', 64px);
+
+ @media screen and (max-width: 800px) {
+ flex-direction: column;
+ align-items: flex-start;
+ border-bottom: unset;
+ padding-bottom: unset;
+ gap: tovw(16px, 'mobile');
+ }
+
+ h2 {
+ text-shadow: 0px 0px tovw(20px, 'default', 20px) rgb(255 255 255 / 0.4);
+ }
+
+ span {
+ line-height: 1.32;
+ font-size: tovw(24px, 'default', 18px);
+ font-family: var(--font-tt-hoves), sans-serif;
+ width: tovw(350px, 'default', 265px);
+ }
+
+ .gradient {
+ position: absolute;
+ z-index: -1;
+ left: 0;
+ right: 0;
+ width: 100vw;
+ margin-left: 0;
+ height: tovw(500px, 'default', 250px);
+ content: '';
+ user-select: none;
+ pointer-events: none;
+ opacity: 0.4;
+ background: linear-gradient(
+ 180deg,
+ rgb(229 229 229 / 0) 0%,
+ rgb(241 241 241 / 0.4) 48.91%,
+ rgb(241 241 241 / 0) 89.23%
+ );
+
+ @media screen and (max-width: 800px) {
+ display: none;
+ }
+ }
+ }
+
+ .eventsContainer {
+ display: grid;
+ grid-auto-flow: column;
+
+ &::after,
+ &::before {
+ position: absolute;
+ content: '';
+ height: 100%;
+ width: tovw(280px, 'default', 150px);
+ right: 0;
+ background: linear-gradient(
+ 90deg,
+ rgb(3 3 3 / 0) 0%,
+ rgb(3 3 3 / 0.95) 35%,
+ rgb(3 3 3 / 1) 65%
+ );
+
+ @media screen and (max-width: 800px) {
+ background: linear-gradient(
+ 90deg,
+ rgb(3 3 3 / 0) 0%,
+ rgb(3 3 3 / 0.55) 35%,
+ rgb(3 3 3 / 1) 95%
+ );
+ width: tovw(20px, 'default', 20px);
+ }
+ }
+
+ &::before {
+ left: 0;
+ z-index: 1;
+ background: linear-gradient(
+ 270deg,
+ rgb(3 3 3 / 0) 0%,
+ rgb(3 3 3 / 0.95) 35%,
+ rgb(3 3 3 / 1) 65%
+ );
+ }
+ }
+
+ .navigation {
+ display: flex;
+ place-content: center;
+ width: 100%;
+ gap: tovw(25px, 'default', 15px);
+ padding-top: tovw(75px, 'default', 45px);
+
+ @media screen and (max-width: 800px) {
+ display: none;
+ }
+
+ .arrow {
+ cursor: pointer;
+ width: tovw(50px, 'default', 30px);
+
+ &:first-child {
+ transform: rotate(180deg);
+ }
+ }
+ }
+}
diff --git a/src/components/sections/community/events/events.ts b/src/components/sections/community/events/events.ts
new file mode 100644
index 0000000..cca0644
--- /dev/null
+++ b/src/components/sections/community/events/events.ts
@@ -0,0 +1,42 @@
+export const events = [
+ {
+ location: 'California, US',
+ date: '01.31.22',
+ time: '20:30',
+ imgSrc: '/images/community/events/card01.png',
+ title: 'ETH Denver',
+ preview:
+ 'Sit sed dolor felis quis. Porttitor semper enim placerat luctus purus aliquam. Diam eu varius donec sit urna feugiat libero diam augue.',
+ link: 'https://google.com'
+ },
+ {
+ location: 'San Francisco, US',
+ date: '04.25.22',
+ time: '19:30',
+ imgSrc: '/images/community/events/card02.png',
+ title: 'Devconnect',
+ preview:
+ 'Sit sed dolor felis quis. Porttitor semper enim placerat luctus purus aliquam. Diam eu varius donec sit urna feugiat libero diam augue.',
+ link: 'https://google.com'
+ },
+ {
+ location: 'Paris, FR',
+ date: '06.25.22',
+ time: '19:30',
+ imgSrc: '/images/community/events/card03.png',
+ title: 'Paris Blockchain Week',
+ preview:
+ 'Sit sed dolor felis quis. Porttitor semper enim placerat luctus purus aliquam. Diam eu varius donec sit urna feugiat libero diam augue.',
+ link: 'https://google.com'
+ },
+ {
+ location: 'Amsterdam, NL',
+ date: '08.25.22',
+ time: '19:30',
+ imgSrc: '/images/community/events/card04.png',
+ title: 'ETHCC',
+ preview:
+ 'Sit sed dolor felis quis. Porttitor semper enim placerat luctus purus aliquam. Diam eu varius donec sit urna feugiat libero diam augue.',
+ link: 'https://google.com'
+ }
+]
diff --git a/src/components/sections/community/events/index.tsx b/src/components/sections/community/events/index.tsx
new file mode 100644
index 0000000..e1bdb24
--- /dev/null
+++ b/src/components/sections/community/events/index.tsx
@@ -0,0 +1,83 @@
+import { useKeenSlider } from 'keen-slider/react'
+import { useState } from 'react'
+
+import Card from '~/components/common/card'
+import { ArrowSlider } from '~/components/icons/arrow'
+import { Container } from '~/components/layout/container'
+import Section from '~/components/layout/section'
+import Heading from '~/components/primitives/heading'
+
+import { events } from './events'
+import s from './events.module.scss'
+
+const Events = () => {
+ const [currentSlide, setCurrentSlide] = useState(0)
+ const [loaded, setLoaded] = useState(false)
+ const [slideHasEnded, setSlideHasEnded] = useState(false)
+
+ const [sliderRef, slider] = useKeenSlider({
+ initial: 0,
+ loop: false,
+ slideChanged(slider) {
+ setCurrentSlide(slider.track.details.rel)
+ },
+ detailsChanged: (slider) => {
+ setSlideHasEnded(slider.track.details.progress >= 1 ? true : false)
+ },
+ created() {
+ setLoaded(true)
+ },
+ breakpoints: {
+ '(max-width: 1050px)': {
+ slides: { perView: 1, spacing: 12 }
+ },
+ '(min-width: 1050px)': {
+ slides: { perView: 2, spacing: 22 }
+ },
+ '(min-width: 1600px)': {
+ slides: { perView: 3, spacing: 26 }
+ }
+ }
+ })
+
+ return (
+
+
+
+
+ Events
+
+
+ We’d love to meet you in person. Find us at a conference near you:
+
+
+
+
+ {events.map((event, i) => (
+
+ ))}
+
+ {loaded && slider.current && (
+
+
+ e.stopPropagation() || slider.current?.prev()
+ }
+ disabled={currentSlide === 0}
+ className={s['arrow']}
+ />
+
+ e.stopPropagation() || slider.current?.next()
+ }
+ disabled={slideHasEnded}
+ className={s['arrow']}
+ />
+
+ )}
+
+
+ )
+}
+
+export default Events
diff --git a/src/components/sections/community/hero/hero.module.scss b/src/components/sections/community/hero/hero.module.scss
new file mode 100644
index 0000000..2978d6d
--- /dev/null
+++ b/src/components/sections/community/hero/hero.module.scss
@@ -0,0 +1,135 @@
+@import '~/css/helpers';
+
+.section {
+ display: grid;
+ align-items: center;
+ gap: tovw(140px, 'default', 80px) tovw(130px, 'default', 30px);
+ justify-content: center;
+ grid-template-columns: repeat(2, 1fr);
+ grid-template-rows: repeat(2, 1fr);
+ min-height: calc(var(--vh) * 100);
+ max-width: 100%;
+
+ @media screen and (max-width: 800px) {
+ display: flex;
+ flex-direction: column;
+ width: 100vw;
+ padding: 0 tovw(27px, 'tablet', 27px);
+ padding-bottom: tovw(18px, 'mobile');
+ min-height: 100vh;
+ }
+
+ img {
+ position: absolute;
+ z-index: -2;
+ width: tovw(1050px, 'default', 400px);
+ padding-top: tovw(150px, 'default', 90px);
+
+ @media screen and (max-width: 800px) {
+ position: unset;
+ width: 110vw;
+ padding-top: tovw(55px, 'mobile');
+ margin-bottom: tovw(-85px, 'mobile');
+ }
+ }
+
+ .headingContainer {
+ justify-self: end;
+ align-self: end;
+ width: tovw(580px, 'default', 80px);
+
+ @media screen and (max-width: 800px) {
+ display: flex;
+ align-self: flex-start;
+ align-items: flex-end;
+ justify-content: space-between;
+ width: 100%;
+ }
+
+ h1 {
+ margin: 0;
+ text-shadow: 0px 0px tovw(20px, 'default', 20px) rgb(255 255 255 / 0.4);
+
+ @media screen and (max-width: 800px) {
+ font-size: tovw(50px, 'mobile');
+ }
+ }
+ }
+
+ .textContainer {
+ display: flex;
+ flex-direction: column;
+ gap: tovw(60px, 'default', 20px);
+ align-self: start;
+ grid-area: 2 / 2 / 3 / 3;
+
+ @media screen and (max-width: 800px) {
+ width: 100%;
+ gap: tovw(120px, 'default', 30px);
+ }
+
+ p {
+ margin: 0;
+ width: tovw(500px, 'default', 370px);
+ line-height: 1.3;
+
+ @media screen and (max-width: 800px) {
+ width: tovw(150px, 'mobile', 320px);
+ }
+ }
+
+ a {
+ width: fit-content;
+ }
+ }
+
+ .buttonsContainer {
+ display: flex;
+ gap: tovw(24px, 'default', 20px);
+
+ @media screen and (max-width: 800px) {
+ width: 100%;
+ flex-direction: column;
+ gap: tovw(20px, 'mobile');
+ }
+ }
+
+ .gradient {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 55%;
+ background: linear-gradient(
+ 180deg,
+ rgb(0 0 244 / 0.9) 1.63%,
+ rgb(0 0 244 / 0) 99.89%
+ );
+ z-index: -1;
+
+ @media screen and (max-width: 800px) {
+ height: 75%;
+ mix-blend-mode: screen;
+ }
+ }
+
+ .arrow {
+ position: absolute;
+ margin-left: tovw(-58px, 'default', -58px);
+ width: tovw(22px, 'default', 15px);
+ height: tovw(22px, 'default', 15px);
+
+ @media screen and (max-width: 800px) {
+ display: none;
+ }
+ }
+
+ .arrowMobile {
+ width: tovw(25px, 'default', 25px);
+ height: tovw(25px, 'default', 25px);
+ margin-bottom: tovw(8px, 'default', 7px);
+
+ @media screen and (min-width: 801px) {
+ display: none;
+ }
+ }
+}
diff --git a/src/components/sections/community/hero/index.tsx b/src/components/sections/community/hero/index.tsx
new file mode 100644
index 0000000..2bdcd82
--- /dev/null
+++ b/src/components/sections/community/hero/index.tsx
@@ -0,0 +1,38 @@
+import { Arrow } from '~/components/icons/arrow'
+import Section from '~/components/layout/section'
+import { Button } from '~/components/primitives/button'
+import Heading from '~/components/primitives/heading'
+import Link from '~/components/primitives/link'
+
+import s from './hero.module.scss'
+
+const Hero = () => {
+ return (
+
+
+
+
+
+ Laconic Community
+
+
+
+
+
+
+ Join us as we accelerate blockchain development and interoperability
+ by expanding access to verifiable data.
+
+
LEARN MORE
+
+
+
+
+
+
+ )
+}
+
+export default Hero
diff --git a/src/components/sections/community/socials/index.tsx b/src/components/sections/community/socials/index.tsx
new file mode 100644
index 0000000..0e0af78
--- /dev/null
+++ b/src/components/sections/community/socials/index.tsx
@@ -0,0 +1,68 @@
+import Line from '~/components/icons/line'
+import {
+ Discourse,
+ Facebook,
+ Instagram,
+ Linkedin,
+ Reddit,
+ Telegram,
+ Twitter
+} from '~/components/icons/socials'
+import { Container } from '~/components/layout/container'
+import Section from '~/components/layout/section'
+import Heading from '~/components/primitives/heading'
+
+import s from './socials.module.scss'
+
+const Socials = () => {
+ return (
+
+
+
+
+
+
+ Socials
+
+
+ Connect With Us
+
+
+
+
+
+
GET IN TOUCH
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default Socials
diff --git a/src/components/sections/community/socials/socials.module.scss b/src/components/sections/community/socials/socials.module.scss
new file mode 100644
index 0000000..25234b3
--- /dev/null
+++ b/src/components/sections/community/socials/socials.module.scss
@@ -0,0 +1,157 @@
+@import '~/css/helpers';
+
+.section {
+ position: relative;
+ padding: tovw(124px, 'default', 100px) 0;
+
+ @media screen and (max-width: 800px) {
+ margin-top: 0;
+ }
+
+ .container {
+ display: grid;
+ grid-template-columns: 1.7fr 1fr;
+ grid-template-rows: repeat(2, 1fr);
+ gap: tovw(70px, 'default', 20px) 0;
+
+ @media screen and (max-width: 800px) {
+ display: flex;
+ flex-direction: column;
+ gap: tovw(5px, 'mobile', 15px);
+ }
+ }
+
+ .headingContainer {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+
+ @media screen and (max-width: 800px) {
+ margin-top: tovw(-135px, 'mobile', -150px);
+ }
+
+ h2 {
+ margin: 0;
+ text-shadow: 0px 0px tovw(20px, 'default', 20px) rgb(255 255 255 / 0.4);
+
+ @media screen and (max-width: 800px) {
+ font-size: tovw(42px, 'default', 36px);
+ text-align: center;
+ }
+
+ &:nth-child(1) {
+ padding-left: tovw(125px, 'default', 60px);
+
+ @media screen and (max-width: 800px) {
+ padding-left: unset;
+ }
+ }
+
+ &:nth-child(2) {
+ align-self: end;
+ width: tovw(465px, 'default', 80px);
+
+ @media screen and (max-width: 800px) {
+ width: 100%;
+ }
+ }
+ }
+ }
+
+ .line {
+ position: absolute;
+ left: tovw(770px, 'default', 300px);
+ top: tovw(170px, 'default', 120px);
+ transform: rotate(270deg) scale(1.6);
+ width: tovw(173px, 'default', 120px);
+ height: tovw(72px, 'default', 40px);
+
+ @media screen and (max-width: 800px) {
+ transform: rotate(0deg) translateY(35%) scaleX(1.6);
+ height: tovw(80px, 'default', 38px);
+ left: 0;
+ right: 0;
+ margin: auto;
+ top: unset;
+ }
+ }
+
+ .socialIconsContainer {
+ grid-area: 2 / 2 / 3 / 3;
+
+ @media screen and (max-width: 800px) {
+ display: flex;
+ flex-direction: column;
+ }
+
+ span {
+ font-family: var(--font-dm-mono), sans-serif;
+ font-size: tovw(18px, 'default', 12px);
+ letter-spacing: -0.02rem;
+
+ &::before {
+ position: absolute;
+ transform: translate(-220%, -50%);
+ display: block;
+ content: '';
+ width: tovw(24px, 'default', 15px);
+ height: tovw(18px, 'default', 15px);
+ border-bottom: tovw(2px, 'default', 2px) solid blue;
+
+ @media screen and (max-width: 800px) {
+ display: none;
+ }
+ }
+
+ @media screen and (max-width: 800px) {
+ text-align: center;
+ }
+ }
+
+ .iconsGrid {
+ width: tovw(400px, 'default', 255px);
+ padding-top: tovw(30px, 'default', 15px);
+ display: flex;
+ flex-wrap: wrap;
+ gap: tovw(20px, 'default', 12px);
+
+ @media screen and (max-width: 800px) {
+ place-self: center;
+ place-content: center;
+ }
+
+ button {
+ cursor: pointer;
+ display: flex;
+ place-content: center;
+ padding: tovw(13px, 'default', 8px);
+ height: tovw(55px, 'default', 38px);
+ width: tovw(72px, 'default', 54px);
+ border: tovw(1px, 'default', 1px) solid #fff;
+ border-radius: tovw(30px, 'default', 20px);
+ background-color: var(--color-black);
+ transition: filter 200ms;
+
+ &:hover {
+ filter: invert(1);
+ }
+ }
+
+ svg {
+ width: tovw(27px, 'default', 20px);
+ }
+ }
+ }
+
+ .planetImage {
+ position: absolute;
+ padding-top: tovw(160px, 'default', 80px);
+ width: tovw(725px, 'default', 320px);
+
+ @media screen and (max-width: 800px) {
+ padding-top: unset;
+ width: 100%;
+ position: relative;
+ }
+ }
+}
diff --git a/src/pages/community.tsx b/src/pages/community.tsx
new file mode 100644
index 0000000..89c8b30
--- /dev/null
+++ b/src/pages/community.tsx
@@ -0,0 +1,20 @@
+import { Meta } from '~/components/common/meta'
+import { PageLayout } from '~/components/layout/page'
+import Events from '~/components/sections/community/events'
+import Hero from '~/components/sections/community/hero'
+import Socials from '~/components/sections/community/socials'
+
+import { Page } from './_app'
+
+const Community: Page = () => {
+ return (
+
+
+
+
+
+
+ )
+}
+
+export default Community