aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/assets/images/icon-articles.svg154
-rw-r--r--src/assets/images/icon-contact.svg66
-rw-r--r--src/assets/images/icon-cv.svg71
-rw-r--r--src/assets/images/icon-home.svg76
-rw-r--r--src/components/Header/Header.module.scss18
-rw-r--r--src/components/Header/Header.tsx9
-rw-r--r--src/components/Icons/Hamburger/Hamburger.module.scss54
-rw-r--r--src/components/Icons/Hamburger/Hamburger.tsx13
-rw-r--r--src/components/Icons/index.tsx3
-rw-r--r--src/components/MainNav/MainNav.module.scss148
-rw-r--r--src/components/MainNav/MainNav.tsx71
-rw-r--r--src/config/nav.ts9
-rw-r--r--src/services/graphql/client.ts1
-rw-r--r--src/styles/globals.scss1
-rw-r--r--src/ts/types/nav.ts5
15 files changed, 696 insertions, 3 deletions
diff --git a/src/assets/images/icon-articles.svg b/src/assets/images/icon-articles.svg
new file mode 100644
index 0000000..e8141d6
--- /dev/null
+++ b/src/assets/images/icon-articles.svg
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 100 100"
+ xml:space="preserve"
+ sodipodi:docname="icon-articles.svg"
+ width="100"
+ height="100"
+ inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs81" /><sodipodi:namedview
+ id="namedview79"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="10.100958"
+ inkscape:cx="53.757279"
+ inkscape:cy="56.826295"
+ inkscape:window-width="1920"
+ inkscape:window-height="1019"
+ inkscape:window-x="0"
+ inkscape:window-y="33"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<g
+ id="g48"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g50"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g52"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g54"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g56"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g58"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g60"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g62"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g64"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g66"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g68"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g70"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g72"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g74"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<g
+ id="g76"
+ transform="matrix(0.19762846,0,0,0.19762846,-140.17831,-7.1525574e-7)">
+</g>
+<path
+ id="rect920-3-6"
+ style="fill:#f6f8f8;stroke:#000000;stroke-width:2.96443;fill-opacity:1"
+ d="M 28.992096,1.4822128 H 90.770752 V 82.312253 H 28.992096 Z" /><path
+ id="rect920-3"
+ style="fill:#f6f8f8;stroke:#000000;stroke-width:2.96443;fill-opacity:1"
+ d="m 19.110672,8.992094 h 61.778656 v 80.83004 H 19.110672 Z" /><path
+ id="rect920"
+ style="fill:#f6f8f8;stroke:#000000;stroke-width:2.96443;fill-opacity:1"
+ d="m 9.229248,17.687748 h 61.778656 v 80.83004 H 9.229248 Z" /><path
+ id="rect1194"
+ style="fill:#1d8fc9;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1"
+ d="M 18.149242,74.65544 H 33.375246 V 90.194215 H 18.149242 Z" /><path
+ id="rect1194-7"
+ style="fill:#1d8fc9;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1"
+ d="M 18.142653,24.858688 H 62.094499 V 35.908926 H 18.142653 Z" /><path
+ id="rect1338"
+ style="fill:#00080c;stroke-width:1.56766"
+ d="m 17.618576,41.908926 h 45 v 2 h -45 z" /><path
+ id="rect1338-5"
+ style="fill:#00080c;stroke-width:1.56766"
+ d="m 17.618576,49.908926 h 45 v 2 h -45 z" /><path
+ id="rect1338-5-3"
+ style="fill:#00080c;stroke-width:1.56766"
+ d="m 17.618576,57.908926 h 45 v 2 h -45 z" /><path
+ id="rect1338-5-3-5"
+ style="fill:#00080c;stroke-width:1.56766"
+ d="m 17.618576,65.908926 h 45 v 2 h -45 z" /><path
+ id="rect1338-5-3-5-6"
+ style="fill:#00080c;stroke-width:1.06543"
+ d="m 41.833105,73.424828 h 20.785471 v 2 H 41.833105 Z" /><path
+ id="rect1338-5-3-5-6-2"
+ style="fill:#00080c;stroke-width:1.06543"
+ d="m 41.833105,81.424828 h 20.785471 v 2 H 41.833105 Z" /><path
+ id="rect1338-5-3-5-6-2-9"
+ style="fill:#00080c;stroke-width:1.06543"
+ d="m 41.833105,89.424828 h 20.785471 v 2 H 41.833105 Z" /></svg>
diff --git a/src/assets/images/icon-contact.svg b/src/assets/images/icon-contact.svg
new file mode 100644
index 0000000..462a299
--- /dev/null
+++ b/src/assets/images/icon-contact.svg
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="100"
+ height="100"
+ viewBox="0 0 100 100"
+ version="1.1"
+ xml:space="preserve"
+ inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
+ sodipodi:docname="icon-contact.svg"
+ id="svg1161"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs1148" /><sodipodi:namedview
+ id="namedview37"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="8.1225513"
+ inkscape:cx="53.923944"
+ inkscape:cy="50.230523"
+ inkscape:window-width="1920"
+ inkscape:window-height="1019"
+ inkscape:window-x="0"
+ inkscape:window-y="33"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg1161" /><path
+ id="rect1309"
+ style="fill:#00445e;stroke:#000000;stroke-width:3.0525;stroke-linejoin:round"
+ d="M 1.5262527,42.535416 H 98.473747 V 98.371662 H 1.5262527 Z" /><path
+ id="rect1309-6"
+ style="fill:#1d8fc9;fill-opacity:1;stroke:#000000;stroke-width:3.0525;stroke-linejoin:round"
+ d="m 49.999985,1.6283075 c 2.855148,0 48.473753,40.8563885 48.473753,40.8563885 H 1.5262359 c 0,0 45.6186001,-40.8563885 48.4737491,-40.8563885 z"
+ sodipodi:nodetypes="zccz" /><path
+ id="rect3678"
+ style="fill:#f6f8f8;stroke:#000000;stroke-width:3.0525;stroke-linejoin:round;fill-opacity:1"
+ d="M 8.3434839,28.463842 H 91.656465 V 97.348661 H 8.3434839 Z" /><path
+ id="rect1309-6-0"
+ style="fill:#1d8fc9;fill-opacity:1;stroke:#000000;stroke-width:3.0525;stroke-linejoin:round"
+ d="M 49.999985,63.571925 98.473738,98.371692 H 1.5262359 Z"
+ sodipodi:nodetypes="cccc" /><path
+ id="rect3836"
+ style="fill:#00070d;stroke-width:3.0525;stroke-linejoin:round"
+ d="m 24.562439,37.640923 h 50.875053 v 1.5 H 24.562439 Z" /><path
+ id="rect3836-3"
+ style="fill:#00070d;stroke-width:3.0525;stroke-linejoin:round"
+ d="m 24.562439,45.140923 h 50.875053 v 1.5 H 24.562439 Z" /><path
+ id="rect3836-3-6"
+ style="fill:#00070d;stroke-width:3.0525;stroke-linejoin:round"
+ d="m 24.562443,52.640923 h 50.875053 v 1.5 H 24.562443 Z" /><path
+ id="rect3836-3-6-7"
+ style="fill:#00070d;stroke-width:3.0525;stroke-linejoin:round"
+ d="M 24.562447,60.140923 H 75.4375 v 1.5 H 24.562447 Z" /><path
+ id="rect1309-6-0-6-2"
+ style="fill:#1d8fc9;fill-opacity:1;stroke:#000000;stroke-width:3.0525;stroke-linejoin:round"
+ d="M 39.93749,70.965004 1.5262559,43.55838 v 54.813242 z"
+ sodipodi:nodetypes="cccc" /><path
+ id="rect1309-6-0-6"
+ style="fill:#1d8fc9;fill-opacity:1;stroke:#000000;stroke-width:3.0525;stroke-linejoin:round"
+ d="M 60.0625,70.965004 98.473738,43.55838 v 54.813242 z"
+ sodipodi:nodetypes="cccc" /></svg>
diff --git a/src/assets/images/icon-cv.svg b/src/assets/images/icon-cv.svg
new file mode 100644
index 0000000..691443a
--- /dev/null
+++ b/src/assets/images/icon-cv.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ version="1.1"
+ x="0px"
+ y="0px"
+ width="100"
+ height="100"
+ viewBox="0 0 99.999999 99.999999"
+ xml:space="preserve"
+ sodipodi:docname="icon-cv.svg"
+ id="svg3545"
+ inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs823" /><sodipodi:namedview
+ id="namedview43"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1019"
+ inkscape:window-x="0"
+ inkscape:window-y="33"
+ inkscape:window-maximized="1"
+ inkscape:zoom="1.0013052"
+ inkscape:cx="-186.75625"
+ inkscape:cy="19.973931"
+ inkscape:current-layer="svg3545"
+ showgrid="false" /><path
+ id="rect4387"
+ style="fill:#14578a;stroke:#000000;stroke-width:1.45341;stroke-linejoin:round"
+ d="M 0.72670447,42.521138 H 77.467597 v 54.36591 H 0.72670447 Z" /><path
+ id="rect6223"
+ style="fill:#14578a;fill-opacity:1;stroke:#000000;stroke-width:0.968939;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 22.263958,32.886587 c 12.6493,-1.81512 21.613185,-1.732794 33.666442,0 l 1.683339,10.99517 h -5.891624 v -5.474639 c -7.949741,-2.722434 -16.311959,-2.706359 -25.249837,0 v 5.474639 h -5.891625 z"
+ sodipodi:nodetypes="ccccccccc" /><path
+ id="rect4387-1"
+ style="fill:#1d8fc9;stroke:#000000;stroke-width:1.45341;stroke-linejoin:round"
+ d="M 0.72670447,42.521138 H 77.467597 V 73.884317 H 0.72670447 Z" /><path
+ id="rect3084"
+ style="fill:#f6f8f8;stroke:#000000;stroke-width:2.21241;stroke-linejoin:round"
+ d="M 44.217117,1.106205 H 98.921356 V 36.610421 H 44.217117 Z" /><path
+ id="rect3401"
+ style="fill:#1d8fc9;fill-opacity:1;stroke:#000000;stroke-width:1.28635;stroke-linejoin:round"
+ d="m 84.933665,34.721635 h 6.957554 v 10.216808 l -3.478793,-3.767744 -3.478761,3.767744 z"
+ sodipodi:nodetypes="cccccc" /><path
+ id="path2524-93"
+ style="fill:#1d8fc9;fill-opacity:1;stroke:#000000;stroke-width:1.23103;stroke-linejoin:round"
+ d="m 93.326919,30.779639 a 4.914472,4.9188584 0 0 1 -4.914493,4.918858 4.914472,4.9188584 0 0 1 -4.914461,-4.918858 4.914472,4.9188584 0 0 1 4.914461,-4.918858 4.914472,4.9188584 0 0 1 4.914493,4.918858 z" /><path
+ id="rect1515-3-7"
+ style="stroke-width:1.10619;stroke-linejoin:round"
+ d="m 54.53557,14.438273 h 34.067282 v 1.515453 H 54.53557 Z" /><path
+ id="rect1515-3-7-3"
+ style="stroke-width:1.10619;stroke-linejoin:round"
+ d="m 54.53557,21.384062 h 34.067282 v 1.515453 H 54.53557 Z" /><path
+ id="rect1515-3-7-3-6"
+ style="stroke-width:1.10619;stroke-linejoin:round"
+ d="m 54.53557,28.329927 h 17.563315 v 1.515454 H 54.53557 Z" /><path
+ id="rect1515-3-7-3-1"
+ style="stroke-width:1.10619;stroke-linejoin:round"
+ d="m 63.495911,7.4924218 h 16.146628 v 1.515452 H 63.495911 Z" /><path
+ id="rect5089"
+ style="fill:#f6f8f8;fill-opacity:1;stroke:#000000;stroke-width:1.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 34.048314,65.601104 H 44.145988 V 80.557785 H 34.048314 Z" /></svg>
diff --git a/src/assets/images/icon-home.svg b/src/assets/images/icon-home.svg
new file mode 100644
index 0000000..11b4f0a
--- /dev/null
+++ b/src/assets/images/icon-home.svg
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 100 100"
+ xml:space="preserve"
+ sodipodi:docname="icon-home.svg"
+ inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
+ width="100"
+ height="100"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs71" /><sodipodi:namedview
+ id="namedview69"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="2.9150813"
+ inkscape:cx="7.2039157"
+ inkscape:cy="87.133076"
+ inkscape:window-width="1920"
+ inkscape:window-height="1019"
+ inkscape:window-x="0"
+ inkscape:window-y="33"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" /><rect
+ style="fill:#f6f8f8;fill-opacity:1;stroke:#000000;stroke-width:3.25598;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="wall"
+ width="81.442894"
+ height="82.338066"
+ x="9.2669392"
+ y="15.413749" /><rect
+ style="fill:#000203;fill-opacity:1;stroke:#000000;stroke-width:3.25598;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="indoor"
+ width="21.594872"
+ height="31.91539"
+ x="39.190941"
+ y="65.836418" /><rect
+ style="fill:#1d8fc9;fill-opacity:1;stroke:#000000;stroke-width:3.25598;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="door"
+ width="21.594872"
+ height="31.91539"
+ x="39.190941"
+ y="65.836418" /><path
+ id="roof"
+ style="fill:#1d8fc9;fill-opacity:1;stroke:#000000;stroke-width:3.25598"
+ d="M 4.8219096,11.719266 H 94.720716 l 3.47304,33.365604 H 1.7830046 Z"
+ sodipodi:nodetypes="ccccc" /><rect
+ style="fill:#f6f8f8;fill-opacity:1;stroke:#000000;stroke-width:3.25598;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="chimney"
+ width="12.538733"
+ height="20.388027"
+ x="70.41848"
+ y="2.2481852" /><rect
+ style="fill:#080808;fill-opacity:1;stroke:none;stroke-width:3.25598;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="line1"
+ width="57.049389"
+ height="3.2935634"
+ x="3.9536645"
+ y="19.342648" /><rect
+ style="fill:#080808;fill-opacity:1;stroke:none;stroke-width:3.25598;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="line2"
+ width="57.049389"
+ height="3.2935634"
+ x="38.973709"
+ y="32.057171" /></svg>
diff --git a/src/components/Header/Header.module.scss b/src/components/Header/Header.module.scss
new file mode 100644
index 0000000..b6bd15d
--- /dev/null
+++ b/src/components/Header/Header.module.scss
@@ -0,0 +1,18 @@
+.wrapper {
+ display: grid;
+ grid-template-columns:
+ minmax(0, 1fr) min(calc(100vw - var(--spacing-md) * 2), 100ch)
+ minmax(0, 1fr);
+ align-items: center;
+ padding: var(--spacing-sm) 0 var(--spacing-md);
+ position: relative;
+}
+
+.body {
+ grid-column: 2;
+ display: flex;
+ flex-flow: row wrap;
+ align-items: center;
+ justify-content: space-between;
+ gap: var(--spacing-md);
+}
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx
index 599fdc0..52da2e8 100644
--- a/src/components/Header/Header.tsx
+++ b/src/components/Header/Header.tsx
@@ -1,9 +1,14 @@
import Branding from '@components/Branding/Branding';
+import MainNav from '@components/MainNav/MainNav';
+import styles from './Header.module.scss';
const Header = () => {
return (
- <header>
- <Branding />
+ <header className={styles.wrapper}>
+ <div className={styles.body}>
+ <Branding />
+ <MainNav />
+ </div>
</header>
);
};
diff --git a/src/components/Icons/Hamburger/Hamburger.module.scss b/src/components/Icons/Hamburger/Hamburger.module.scss
new file mode 100644
index 0000000..1ae01bb
--- /dev/null
+++ b/src/components/Icons/Hamburger/Hamburger.module.scss
@@ -0,0 +1,54 @@
+@use "@styles/abstracts/functions" as fun;
+
+.icon {
+ position: relative;
+
+ &,
+ &::before,
+ &::after {
+ background: var(--color-primary);
+ background-image: linear-gradient(
+ to right,
+ var(--color-primary-light) 0%,
+ var(--color-highlight) 100%
+ );
+ border: fun.convert-px(1) solid var(--color-border);
+ border-radius: fun.convert-px(3);
+ display: block;
+ width: var(--btn-size, fun.convert-px(50));
+ height: fun.convert-px(6);
+ margin: auto;
+ transition: all 0.25s ease-in-out 0s, transform 0.4s ease-in 0s;
+ }
+
+ &::before,
+ &::after {
+ content: "";
+ position: absolute;
+ }
+
+ &::before {
+ bottom: fun.convert-px(15);
+ }
+
+ &::after {
+ top: fun.convert-px(15);
+ }
+
+ &--active {
+ background: transparent;
+ border: transparent;
+
+ &::before {
+ transform-origin: 50% 50%;
+ transform: rotate(45deg);
+ bottom: 0;
+ }
+
+ &::after {
+ transform-origin: 50% 50%;
+ transform: rotate(-45deg);
+ top: 0;
+ }
+ }
+}
diff --git a/src/components/Icons/Hamburger/Hamburger.tsx b/src/components/Icons/Hamburger/Hamburger.tsx
new file mode 100644
index 0000000..3b9e609
--- /dev/null
+++ b/src/components/Icons/Hamburger/Hamburger.tsx
@@ -0,0 +1,13 @@
+import styles from './Hamburger.module.scss';
+
+const HamburgerIcon = ({ isActive }: { isActive: boolean }) => {
+ return (
+ <span
+ className={`${styles.icon}${
+ isActive ? ` ${styles['icon--active']}` : ''
+ }`}
+ ></span>
+ );
+};
+
+export default HamburgerIcon;
diff --git a/src/components/Icons/index.tsx b/src/components/Icons/index.tsx
new file mode 100644
index 0000000..da4e029
--- /dev/null
+++ b/src/components/Icons/index.tsx
@@ -0,0 +1,3 @@
+import HamburgerIcon from './Hamburger/Hamburger';
+
+export { HamburgerIcon };
diff --git a/src/components/MainNav/MainNav.module.scss b/src/components/MainNav/MainNav.module.scss
new file mode 100644
index 0000000..cc4b45b
--- /dev/null
+++ b/src/components/MainNav/MainNav.module.scss
@@ -0,0 +1,148 @@
+@use "@styles/abstracts/functions" as fun;
+@use "@styles/abstracts/mixins" as mix;
+@use "@styles/abstracts/placeholders";
+
+.wrapper {
+ --btn-size: #{fun.convert-px(50)};
+
+ display: flex;
+ flex-flow: column nowrap;
+ place-items: center;
+ height: var(--btn-size);
+ width: var(--btn-size);
+ background: var(--color-bg);
+ position: relative;
+ z-index: 5;
+
+ @include mix.media("screen") {
+ @include mix.dimensions("sm") {
+ background: inherit;
+ }
+
+ @include mix.dimensions("md") {
+ width: unset;
+ height: unset;
+ }
+ }
+}
+
+.label {
+ display: flex;
+ flex-flow: column nowrap;
+ width: 100%;
+ height: 100%;
+
+ @include mix.media("screen") {
+ @include mix.dimensions("md") {
+ display: none;
+ }
+ }
+}
+
+.checkbox {
+ position: absolute;
+ top: calc((var(--btn-size) - #{fun.convert-px(14)}) / 2);
+ left: calc((var(--btn-size) - #{fun.convert-px(14)}) / 2);
+ opacity: 0;
+ cursor: pointer;
+
+ @include mix.media("screen") {
+ @include mix.dimensions("md") {
+ display: none;
+ }
+ }
+}
+
+.nav {
+ display: flex;
+ flex-flow: column nowrap;
+ place-content: center;
+ padding-bottom: var(--toolbar-size);
+ position: absolute;
+ bottom: auto;
+ left: auto;
+ right: auto;
+ top: var(--btn-size);
+ background: var(--color-bg-opacity);
+ box-shadow: 0 0 3px 0 var(--color-shadow);
+ text-align: center;
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+ transition: all 0.8s ease-in-out 0s;
+
+ @include mix.media("screen") {
+ @include mix.dimensions("sm") {
+ border-bottom-width: fun.convert-px(5);
+ transform-origin: 50% -100%;
+ }
+
+ @include mix.dimensions("md") {
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ position: relative;
+ top: 0;
+ }
+ }
+}
+
+.list {
+ @extend %reset-list;
+
+ @include mix.media("screen") {
+ @include mix.dimensions("md") {
+ display: flex;
+ flex-flow: row wrap;
+ align-items: center;
+ }
+ }
+}
+
+.link {
+ display: block;
+ padding: var(--spacing-xs) var(--spacing-sm);
+ background: var(--color-bg);
+ font-size: var(--font-size-sm);
+ font-variant: small-caps;
+ font-weight: 600;
+ text-decoration: none;
+
+ @include mix.media("screen") {
+ @include mix.dimensions("md") {
+ background: inherit;
+ }
+ }
+}
+
+.icon {
+ display: block;
+ width: fun.convert-px(25);
+ margin: auto;
+
+ @include mix.media("screen") {
+ @include mix.dimensions("md") {
+ width: fun.convert-px(30);
+ }
+ }
+}
+
+.checkbox:not(:checked) {
+ ~ .nav {
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(100vw);
+
+ @include mix.media("screen") {
+ @include mix.dimensions("sm") {
+ transform: perspective(20rem) translate3d(0, 100%, -20rem);
+ }
+
+ @include mix.dimensions("md") {
+ opacity: 1;
+ visibility: visible;
+ transform: none;
+ }
+ }
+ }
+}
diff --git a/src/components/MainNav/MainNav.tsx b/src/components/MainNav/MainNav.tsx
new file mode 100644
index 0000000..3140e64
--- /dev/null
+++ b/src/components/MainNav/MainNav.tsx
@@ -0,0 +1,71 @@
+import { useState } from 'react';
+import Link from 'next/link';
+import { t } from '@lingui/macro';
+import { HamburgerIcon } from '@components/Icons';
+import { mainNav } from '@config/nav';
+import ArticlesIcon from '@assets/images/icon-articles.svg';
+import ContactIcon from '@assets/images/icon-contact.svg';
+import CVIcon from '@assets/images/icon-cv.svg';
+import HomeIcon from '@assets/images/icon-home.svg';
+import styles from './MainNav.module.scss';
+
+const MainNav = () => {
+ const [isChecked, setIsChecked] = useState<boolean>(false);
+
+ const getIcon = (id: string) => {
+ switch (id) {
+ case 'home':
+ return <HomeIcon />;
+ case 'blog':
+ return <ArticlesIcon />;
+ case 'contact':
+ return <ContactIcon />;
+ case 'cv':
+ return <CVIcon />;
+ default:
+ break;
+ }
+ };
+
+ const navItems = mainNav.map((item) => {
+ return (
+ <li key={item.id} className={styles.item}>
+ <Link href={item.slug}>
+ <a className={styles.link}>
+ <span className={styles.icon}>{getIcon(item.id)}</span>
+ <span>{item.name}</span>
+ </a>
+ </Link>
+ </li>
+ );
+ });
+
+ return (
+ <div className={styles.wrapper}>
+ <input
+ type="checkbox"
+ name="main-nav__checkbox"
+ id="main-nav__checkbox"
+ aria-labelledby="main-nav-toggle"
+ className={styles.checkbox}
+ checked={isChecked}
+ onChange={() => setIsChecked(!isChecked)}
+ />
+ <label
+ htmlFor="main-nav__checkbox"
+ id="main-nav-toggle"
+ className={styles.label}
+ >
+ <HamburgerIcon isActive={isChecked} />
+ <span className="screen-reader-text">
+ {isChecked ? t`Close menu` : t`Open menu`}
+ </span>
+ </label>
+ <nav className={styles.nav}>
+ <ul className={styles.list}>{navItems}</ul>
+ </nav>
+ </div>
+ );
+};
+
+export default MainNav;
diff --git a/src/config/nav.ts b/src/config/nav.ts
new file mode 100644
index 0000000..de60369
--- /dev/null
+++ b/src/config/nav.ts
@@ -0,0 +1,9 @@
+import { t } from '@lingui/macro';
+import { NavItem } from '@ts/types/nav';
+
+export const mainNav: NavItem[] = [
+ { id: 'home', name: t`Home`, slug: '/' },
+ { id: 'blog', name: t`Blog`, slug: '/blog' },
+ { id: 'cv', name: t`Resume`, slug: '/cv' },
+ { id: 'contact', name: t`Contact`, slug: '/contact' },
+];
diff --git a/src/services/graphql/client.ts b/src/services/graphql/client.ts
index 160021b..a58441f 100644
--- a/src/services/graphql/client.ts
+++ b/src/services/graphql/client.ts
@@ -2,7 +2,6 @@ import { GraphQLClient } from 'graphql-request';
export const getGraphQLClient = () => {
const apiUrl: string = process.env.NEXT_PUBLIC_GRAPHQL_API || '';
- console.log(apiUrl);
if (!apiUrl) throw new Error('API URL not defined.');
diff --git a/src/styles/globals.scss b/src/styles/globals.scss
index c1b6d95..8a3daca 100644
--- a/src/styles/globals.scss
+++ b/src/styles/globals.scss
@@ -15,5 +15,6 @@
@use "base/base";
@use "base/colors";
@use "base/fonts";
+@use "base/helpers";
@use "base/spacings";
@use "base/typography";
diff --git a/src/ts/types/nav.ts b/src/ts/types/nav.ts
new file mode 100644
index 0000000..7cfc46b
--- /dev/null
+++ b/src/ts/types/nav.ts
@@ -0,0 +1,5 @@
+export type NavItem = {
+ id: string;
+ name: string;
+ slug: string;
+};