diff --git a/src/components/common/footer/index.tsx b/src/components/common/footer/index.tsx index bd50d0b..a5185ef 100644 --- a/src/components/common/footer/index.tsx +++ b/src/components/common/footer/index.tsx @@ -21,12 +21,14 @@ import s from './footer.module.scss' export const Footer = () => { const [show, setShow] = useState(true) + const [is404, setIs404] = useState(false) const router = useRouter() useEffect(() => { if ( router?.pathname === '/terms-of-use' || - router?.pathname === '/privacy-policy' + router?.pathname === '/privacy-policy' || + router?.pathname === '/404' ) { setShow(false) } else { @@ -34,6 +36,14 @@ export const Footer = () => { } }, [router?.pathname]) + useEffect(() => { + if (router?.pathname === '/404') { + setIs404(true) + } else { + setIs404(false) + } + }, [router?.pathname]) + return ( <> {show && ( @@ -73,113 +83,116 @@ export const Footer = () => { )} - + {!is404 && ( + + )} ) } diff --git a/src/components/sections/404/hero/hero.module.scss b/src/components/sections/404/hero/hero.module.scss new file mode 100644 index 0000000..5d3d3b3 --- /dev/null +++ b/src/components/sections/404/hero/hero.module.scss @@ -0,0 +1,184 @@ +@import '~/css/helpers'; + +.section { + position: fixed; + right: 0; + bottom: 0; + left: 0; + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + width: 100%; + height: calc(var(--vh) * 100); + text-align: center; + + *:not(.gradient) { + z-index: 1; + } + + @media screen and (max-width: 800px) { + background-image: url('/images/hero-mobile.png'); + background-repeat: no-repeat; + background-position: 50% 15%; + background-size: 100%; + } + + @supports (aspect-ratio: 16 / 9) { + aspect-ratio: 16 / 9; + } + + &::after, + &::before { + position: absolute; + z-index: -1; + top: 50%; + left: 50%; + width: 100%; + height: 101%; + content: ''; + transform: translate(-50%, -50%); + pointer-events: none; + background: linear-gradient( + 0deg, + var(--color-black) 15%, + rgb(9 9 121 / 0) 50%, + var(--color-black) 100% + ); + @supports (aspect-ratio: 16 / 9) { + aspect-ratio: 16 / 9; + } + @media screen and (max-width: 800px) { + content: initial; + } + } + + &::before { + width: 120%; + height: 115%; + background: radial-gradient( + ellipse farthest-corner at center center, + rgb(4 4 4 / 0.25) 55%, + var(--color-black) 0 + ); + filter: blur(tovw(80px, 'default', 40px)); + } + + .line { + width: tovw(3px, 'default', 2px); + height: tovw(72px, 'default', 56px); + margin: tovw(37px, 'default', 20px) auto tovw(23px, 'default', 20px) auto; + } + + .flag { + width: tovw(36px, 'default', 22px); + height: tovw(20px, 'default', 20px); + margin: 0 auto 0 tovw(8px, 'default', 6px); + } + + h1 { + @media screen and (max-width: 800px) { + font-size: tovw(50px, 'mobile', 71px); + margin-top: auto; + } + } + + p { + font-family: var(--font-dm-mono), sans-serif; + font-size: tovw(18px, 'default', 18px); + margin: 0 auto; + } + + a { + margin-top: tovw(32px, 'default', 32px); + text-decoration: none; + + @media screen and (max-width: 800px) { + width: 100%; + margin-top: auto; + margin-bottom: tovw(25px, 'mobile'); + } + } + + .scroll { + position: absolute; + bottom: 5%; + left: tovw(56px, 'default', 16px); + display: grid; + align-items: flex-end; + width: calc(100% - (tovw(56px, 'default', 16px) * 2)); + grid-template-columns: repeat(2, 1fr); + grid-template-rows: 1fr; + + @media screen and (max-width: 800px) { + display: none; + } + + ul { + margin: 0; + padding: 0; + list-style-type: none; + } + + p, + li { + font-family: var(--font-dm-mono); + font-size: tovw(12px, 'default', 11px); + line-height: 1.7; + width: 100%; + text-align: right; + text-transform: uppercase; + font-variant-numeric: tabular-nums; + } + + > div { + &:first-of-type { + display: flex; + align-items: flex-end; + justify-self: flex-start; + + @media screen and (max-width: 800px) { + display: none; + } + } + + &:last-of-type { + text-align: right; + justify-self: flex-end; + + span { + display: inline-block; + width: tovw(60px, 'default', 55px); + } + } + } + } + + .gradient { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: tovw(740px, 'default', 740px); + background: linear-gradient( + 180deg, + rgb(0 0 244 / 0) 1.63%, + rgb(0 0 244 / 0.9) 63.96% + ); + + @media screen and (max-width: 800px) { + height: 70%; + } + } + + .video { + position: absolute; + z-index: -2; + top: 0; + left: 0; + width: 100%; + height: 100%; + user-select: none; + pointer-events: none; + } +} diff --git a/src/components/sections/404/hero/index.tsx b/src/components/sections/404/hero/index.tsx new file mode 100644 index 0000000..ab4e3e3 --- /dev/null +++ b/src/components/sections/404/hero/index.tsx @@ -0,0 +1,69 @@ +import clsx from 'clsx' +import { useEffect, useState } from 'react' + +import Flag from '~/components/icons/flag' +import Line from '~/components/icons/line' +import Section from '~/components/layout/section' +import { ButtonLink } from '~/components/primitives/button' +import Heading from '~/components/primitives/heading' + +import s from './hero.module.scss' + +const Hero = () => { + const [position, setPosition] = useState({ x: 0, y: 0 }) + + useEffect(() => { + const setFromEvent = (e: { clientX: any; clientY: any }) => + setPosition({ x: e.clientX, y: e.clientY }) + window.addEventListener('mousemove', setFromEvent) + + return () => { + window.removeEventListener('mousemove', setFromEvent) + } + }, []) + + return ( +
+ + + Page not found + + +

ERROR 404

+ + Bring me back home + +
+
+

C:

+ +
+
+

404

+
    +
  • + H: + {position.x} PX +
  • +
  • + V: + {position.y} PX +
  • +
+
+
+
+
+ ) +} + +export default Hero diff --git a/src/pages/404.tsx b/src/pages/404.tsx new file mode 100644 index 0000000..814c262 --- /dev/null +++ b/src/pages/404.tsx @@ -0,0 +1,16 @@ +import { Meta } from '~/components/common/meta' +import { PageLayout } from '~/components/layout/page' +import Hero from '~/components/sections/404/hero' + +import { Page } from './_app' + +const NotFoundPage: Page = () => { + return ( + + + + + ) +} + +export default NotFoundPage