In this tutorial, we'll show you how to create a unique portfolio page using Neobrutalism design style, HTML, CSS, and JavaScript.
Table of Contents
Neobrutalism is a design style that emerged in the 2010s as a reaction to the sleek and polished aesthetic of contemporary web design. This style draws inspiration from the raw and industrial-looking materials used in modernist architecture and embraces asymmetry, bold typography, and a monochromatic color palette.
The term "Neobrutalism" comes from the architectural movement known as Brutalism, which emerged in the mid-20th century and was characterized by the use of raw concrete and geometric forms. Neobrutalism takes this aesthetic and applies it to web and graphic design, using rough textures, bold typography, and asymmetrical layouts to create a striking and memorable visual style.
In Neobrutalist design, the focus is on simplicity and functionality, rather than on decorative elements or superfluous details. This means that elements such as navigation menus and buttons are often presented in a stripped-down, minimalist form, with no unnecessary visual clutter.
The use of typography is also a crucial element of Neobrutalist design. Bold and oversized typography is commonly used to emphasize key messages and draw attention to important information, while minimalist fonts such as sans-serif are often used to give a clean and modern feel to the design.
Overall, Neobrutalism is a design style that offers a fresh and alternative approach to contemporary web and graphic design. Its use of raw and industrial-looking materials, bold typography, and asymmetrical layouts create an aesthetic that is both striking and memorable. A portfolio page is an essential element of any creative professional's online presence, as it showcases their work and skills to potential clients or employers. In this tutorial, we'll combine Neobrutalism design principles with HTML, CSS, and JavaScript to create a unique and visually compelling portfolio page.
Let's start making an amazing neobrutalism portfolio page using HTML, CSS, and JavaScript step by step.
Join My Telegram Channel to Download the Project: Click Here
Prerequisites:
Before starting this tutorial, you should have a basic understanding of HTML, CSS, and JavaScript. Additionally, you will need a code editor such as Visual Studio Code or Sublime Text to write and save your code.
Source Code
Step 1 (HTML Code):
To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our neobrutalism portfolio page.
The code starts by defining the document type (<!DOCTYPE html>), followed by the opening of the html tag. The lang attribute specifies that the language used is English.
Inside the html tag, there is the head section, where the title of the page is defined with the title tag, and the character encoding is specified with the meta tag. The viewport meta tag is used to control the layout of the page on different devices.
The link tag is used to link an external CSS stylesheet to the page. The stylesheet is located in the same directory as the HTML file and has the filename "styles.css".
The body section contains the content of the page. There is a div container with the class "container circle-load-svg", which is likely used to center and style the content of the page. Inside this container, there is a header with a logo and a navigation menu that contains three links: "Home", "Showcase", and "Contact". The "Showcase" link has an href attribute that links to an element with the id "portfolio".
The main section contains two sections, one with the class "sctn-hero" and another with the class "hero-flaire". These sections are likely used to display the hero content of the page. The "sctn-hero" section contains a hero message with a tagline, a primary message, and a sub-message. There is also a hero-actions div that contains a button with the class "btn hover-effect". The button has an onclick attribute that triggers the function "showShowcase()" when clicked.
The "hero-flaire" section contains an SVG image of a laptop that has an animation effect. The SVG is wrapped inside a title tag that describes the image for accessibility purposes.
After creating the files just paste the following below codes into your file. Make sure to save your HTML document with a .html extension, so that it can be properly viewed in a web browser.
This is the basic structure of our neobrutalism portfolio page using HTML, and now we can move on to styling it using CSS.
Step 2 (CSS Code):
Once the basic HTML structure of the neobrutalism portfolio page is in place, the next step is to add styling to the portfolio page using CSS. CSS allows us to control the visual appearance of the website, including things like layout, color, and typography.
Next, we will create our CSS file. In this file, we will use some basic CSS rules to create our neobrutalism portfolio page.
The code begins by importing the Poppins font family from Google Fonts, specifying specific font weights to use. It then defines three keyframe animations, including "line-anime," "spinner," and "color-change."
The :root selector is used to specify a default font family and color, while the ::selection and ::-moz-selection selectors are used to define the styles for highlighted text.
The html and body selectors are used to specify the default scroll behavior and background color.
The .container class is used to set the width of the container element, and the .spinner class defines the styles for a spinner animation.
The .btn class defines the styles for buttons, including border, padding, font size, and transition effects. The .btn.hover-effect class adds a hover effect to buttons, and the .btn-primary and .btn-del classes are used to define specific button styles.
The logo and nav selectors are used to define styles for the header, including the logo text, navigation links, and a repeating linear gradient background. The dialog selector defines the styles for a dialog box, including the transition, clip-path, transform, width, padding, and box-shadow.
This will give our neobrutalism portfolio page an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;500;700;900&display=swap");
@keyframes line-anime {
to {
stroke-dashoffset: 0;
}
}
@keyframes spinner {
to {
transform: rotate(360deg);
}
}
@keyframes color-change {
0% {
color: #1f2020;
}
20% {
color: #25282a;
}
40% {
color: #a5282c;
}
60% {
color: #5eb0e5;
}
80% {
color: #ebebe3;
}
100% {
color: #f9f6ef;
}
}
* {
box-sizing: border-box;
}
:root {
font-family: "Poppins", sans-serif;
color: #1f2020;
}
::selection {
background: #ffb7b7;
}
::-moz-selection {
background: #ffb7b7; /* cannot combine*/
}
html {
scroll-behavior: smooth;
}
body,
.container,
header,
div.logo,
nav,
ul {
margin: 0;
/*-- annoying margin at top --- */
}
body {
padding: 0;
background-color: #f3d060;
}
.container {
width: min(120ch, calc(100% - 2rem));
margin: 0 auto;
}
.spinner {
background-color: #a5282c !important;
color: #a5282c !important;
}
.spinner:before {
content: "";
box-sizing: border-box;
position: absolute;
top: 50%;
left: 50%;
width: 2rem;
height: 2rem;
margin-top: -1rem;
margin-left: -1rem;
border-radius: 50%;
border: 4px solid #25282a;
border-top-color: #f3d060;
transform-origin: center center;
animation: spinner 1s linear infinite;
}
.btn {
position: relative;
border: 2px solid #1f2020;
border-radius: 3px;
box-shadow: 3px 3px 0px #25282a;
padding: 0.5rem 1rem;
font-size: 1.4rem;
transition: 200ms ease;
z-index: 2;
background-color: #5eb0e5;
}
.btn + .btn {
margin-left: 1rem;
}
.btn:active {
box-shadow: -2px -2px 0px #25282a;
transform: translate(2px, 2px);
}
.btn.hover-effect::before {
content: "";
position: absolute;
inset: 0;
background-color: #1f2020;
transform-origin: bottom right;
transition: 100ms ease-in-out;
mix-blend-mode: screen;
z-index: 1;
clip-path: ellipse(0px 0px at bottom center);
}
.btn.hover-effect:hover:before {
clip-path: ellipse(50% 100% at bottom center);
}
.btn.hover-effect:active:before {
background-color: #25282a;
mix-blend-mode: color-dodge;
}
.btn-primary {
background-color: #aee1cd;
}
.btn-del {
background-color: #a5282c;
color: #f9f6ef;
}
a {
cursor: pointer;
}
img {
width: 100%;
}
.container > header {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
padding: 0.5rem;
font-weight: 900;
font-size: 1.5rem;
letter-spacing: -0.15em;
color: transparent;
background-color: #f3d060;
background-size: 2px 2px;
background-image: repeating-linear-gradient(
45deg,
#1f2020 0,
#1f2020 0.5px,
#f3d060 0,
#f3d060 50%
);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-stroke: 1px #1f2020;
}
.logo:first-letter {
color: #a5282c;
}
nav ul {
padding: 0;
list-style: none;
display: grid;
grid-template-columns: repeat(3, auto);
gap: 1rem;
}
nav ul li {
text-align: center;
}
nav ul li a {
display: inline-block;
text-decoration: underline;
text-decoration-thickness: 2px;
text-decoration-color: #a5282c;
text-underline-offset: 2px;
color: #1f2020;
font-size: 1rem;
}
dialog {
transition: 300ms ease-in-out, clip-path 0.5s linear;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
transform: scale(0);
min-width: min(50vw, 80ch);
padding: 0;
box-shadow: 2.5px 2.5px 0px #25282a, 5px 5px 0px #25282a,
7.5px 7.5px 0px #25282a, 10px 10px 0px #25282a, 12.5px 12.5px 0px #25282a,
15px 15px 0px #25282a;
}
dialog::backdrop {
opacity: 0.7;
background-color: #f3d060;
background-size: 100%, 50px 50px;
background-image: radial-gradient(
circle at bottom right,
#f3c050c0 0%,
#f3d060c0 50%
),
repeating-linear-gradient(
45deg,
#1f2020 0,
#1f2020 1.5px,
#f3d060 0,
#f3d060 50%
);
}
dialog header {
border-bottom: 3px solid;
padding-inline: 2rem;
display: grid;
grid-template-columns: 1fr auto;
position: relative;
background-color: #25282a;
color: #f9f6ef;
}
dialog .close .btn {
border-radius: 50%;
top: 5px;
right: 10px;
width: 3rem;
height: 3rem;
position: absolute;
box-shadow: 2px 2px 0px #25282a;
overflow: hidden;
background-color: #a5282c;
color: #f9f6ef;
padding: 0;
}
#confirm-dialog {
background-color: #ebebe3;
}
.dialog-message {
border: 5px solid #1f2020;
}
.form-container {
padding-block: 1rem;
padding-inline: 2rem;
}
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
textarea {
background-color: #f9f6ef;
border: 3px solid #25282a;
font-size: 1.3rem;
padding: 0.3rem 0.5rem;
position: relative;
width: 100%;
}
input[type="text"]:invalid,
input[type="email"]:invalid,
input[type="tel"]:invalid,
input[type="url"]:invalid,
textarea:invalid {
border-color: #a5282c;
}
input[type="text"]:valid,
input[type="email"]:valid,
input[type="tel"]:valid,
input[type="url"]:valid,
textarea:invalid {
border-color: #aee1cd;
}
.rt-algn {
display: flex;
justify-content: end;
}
.fnt-sml {
font-size: 0.9rem;
}
/* table */
.row {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 0.5rem;
}
.cell {
padding: 0.3rem 0.5rem;
}
.cell-2 {
grid-column: span 2;
}
.cell-4 {
grid-column: span 4;
}
.cell-5 {
grid-column: span 5;
}
.cell-6 {
grid-column: span 6;
}
/* table end */
.sctn-hero {
position: relative;
min-height: 60vh;
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
padding: 5em 0;
}
.hero-msg-primary {
font-size: clamp(2rem, 5vw + 2rem, 7rem);
line-height: 1;
font-weight: 900;
inline-size: min(140%, calc(100vw - 2rem));
overflow-wrap: break-word;
hyphens: manual;
position: relative;
}
.hero-msg-tag {
font-size: clamp(1rem, 1vw + 1rem, 2rem);
}
.hero-flaire {
position: absolute;
inset: 0 auto;
right: 0;
width: 100%;
display: grid;
grid-template-columns: 1fr;
place-items: center right;
filter: drop-shadow(-2px 5px 0px #5eb0e5);
}
.hero-flaire svg {
width: min(60%, calc(40vw + 50px));
opacity: 0.9;
transform: scaleX(-1);
}
.hero-actions {
padding-top: 5em;
}
.sctn-portfolio {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, auto));
gap: 1rem;
}
.portfolio-card {
border: 3px solid #25282a;
background-color: #5eb0e5;
box-shadow: 5px 5px 0px #25282a;
position: relative;
transform: scale(1);
transition: 200ms cubic-bezier(0.11, -0.25, 0.7, 1.22);
transform-origin: bottom right;
}
.portfolio-card:hover {
transform: scale(1.01) translate(-3px, -3px);
box-shadow: 8px 8px 0px #25282a;
z-index: 5;
}
.portfolio-card header {
border-bottom: 2px solid #25282a;
background-color: #a5282c;
color: #f9f6ef;
padding: 0.3rem 0.5rem;
font-size: 0.65rem;
}
.portfolio-card h2 {
margin: 0;
position: absolute;
width: 100%;
padding: 0.5rem 1rem;
color: #f9f6ef;
background-color: #1f2020;
mix-blend-mode: screen;
text-shadow: 2px 2px 0px #5eb0e5;
}
.portfolio-card:nth-of-type(2n) header {
background-color: #aee1cd;
color: #1f2020;
}
.portfolio-card img {
height: 300px;
overflow: hidden;
border-bottom: 3px solid #25282a;
}
.portfolio-card .card-info {
padding: 0.5rem 1rem;
position: relative;
}
.portfolio-card:after {
content: "\27A0";
color: #f9f6ef;
font-size: 2rem;
line-height: 0, 3;
position: absolute;
bottom: 0.5rem;
right: 0.5rem;
height: 2rem;
}
footer {
padding-block: 3rem 1rem;
}
#circle {
position: absolute;
top: 0.8rem;
left: 32rem;
z-index: -10;
pointer-events: none;
width: 650px;
}
.sctn-design-notes {
margin-top: 3rem;
font-size: 1.5rem;
border: 3px solid #25282a;
}
.sctn-design-notes h2 {
margin: 0;
background-color: #5eb0e5;
padding: 1rem;
border-bottom: 2px solid #25282a;
}
.sctn-design-notes .content {
padding: 1rem;
margin: 0;
background-color: #ebebe3;
}
.sctn-design-notes p {
margin: 0;
}
.sctn-design-notes p ~ p {
margin-top: 1rem;
}
.sctn-design-notes ul {
background-color: #aee1cd;
}
.sctn-design-notes li::marker {
content: "\25BA ";
font-size: 1rem;
animation: color-change 10s ease-in-out infinite alternate;
}
.hero-flaire svg path:nth-child(1) {
stroke-dasharray: 1870px;
stroke-dashoffset: 1870px;
animation: line-anime 1s ease forwards;
}
.hero-flaire svg path:nth-child(2) {
stroke-dasharray: 27.5px;
stroke-dashoffset: 27.5px;
animation: line-anime 0.3s ease forwards 0.5s;
}
.hero-flaire svg path:nth-child(3) {
stroke-dasharray: 172.1px;
stroke-dashoffset: 172.1px;
animation: line-anime 1s ease forwards 0.8s;
}
.hero-flaire svg path:nth-child(4) {
stroke-dasharray: 2px;
stroke-dashoffset: 2px;
animation: line-anime 0.1s ease forwards 1s;
}
.hero-flaire svg path:nth-child(5) {
stroke-dasharray: 127.4px;
stroke-dashoffset: 127.4px;
animation: line-anime 0.5s ease forwards 1.5s;
}
.hero-flaire svg path:nth-child(6) {
stroke-dasharray: 341.7px;
stroke-dashoffset: 341.7px;
animation: line-anime 1s ease forwards 3s;
}
.hero-flaire svg path:nth-child(7) {
stroke-dasharray: 113.4px;
stroke-dashoffset: 113.4px;
animation: line-anime 1s ease forwards 2s;
}
.hero-flaire svg path:nth-child(8) {
stroke-dasharray: 68.4px;
stroke-dashoffset: 68.4px;
animation: line-anime 0.5s ease forwards 2.5s;
}
.hero-flaire svg path:nth-child(9) {
stroke-dasharray: 78.9px;
stroke-dashoffset: 78.9px;
animation: line-anime 0.5s ease forwards 2.5s;
}
#circle #big-circle {
stroke: #25282a;
fill: none;
stroke-dasharray: 2487.7px;
stroke-dashoffset: 2487.7px;
animation: line-anime 3s ease forwards;
}
.circle-load-svg {
background-repeat: no-repeat;
background-size: 650px;
background-position: 34.1rem 1.2rem;
background-image: url("data:image/svg+xml,%3Csvg height='100%25' stroke-miterlimit='10' style='fill-rule:nonzero%3Bclip-rule:evenodd%3Bstroke-linecap:round%3Bstroke-linejoin:round%3B' version='1.1' viewBox='0 0 500 500' width='100%25' xml:space='preserve' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cdefs/%3E%3Cg id='LoadCircle'%3E%3Cpath d='M28.1395 132.351C28.1395 124.857 34.2147 118.782 41.7089 118.782C49.203 118.782 55.2783 124.857 55.2783 132.351C55.2783 139.845 49.203 145.921 41.7089 145.921C34.2147 145.921 28.1395 139.845 28.1395 132.351Z' fill='%235eb0e5' fill-rule='evenodd' opacity='1' stroke='none'/%3E%3Cpath d='M21.4398 371.142L24.7478 353.29L28.0557 335.438L43.1619 347.007L58.2682 358.575L39.854 364.858L21.4398 371.142Z' fill='%23aee1cd' fill-rule='evenodd' opacity='1' stroke='none'/%3E%3Cg opacity='0.5'%3E%3Cpath d='M249.406 10.5C231.54 10.6029 213.788 12.9511 196.406 17.0312C183.264 20.1163 170.31 24.1968 157.875 29.4688C143.472 35.5753 129.669 42.9944 116.719 51.7812C90.4539 69.6023 68.4614 92.2674 48.8125 117.031C48.4674 117.466 48.5338 118.092 48.9688 118.438C49.4037 118.783 50.0299 118.716 50.375 118.281C69.8969 93.6784 91.7485 71.174 117.844 53.4688C130.686 44.7555 144.373 37.3683 158.656 31.3125C170.985 26.0851 183.844 22.0579 196.875 19C214.11 14.9557 231.691 12.632 249.406 12.5312C279.15 12.3622 308.799 18.2826 336.281 29.625C362.953 40.6328 387.448 56.6058 408.531 76.2812C429.149 95.5224 446.488 118.35 459.438 143.406C470.887 165.56 478.921 189.486 483 214.094C486.582 235.705 487.073 257.812 484.469 279.562C482.609 295.096 479.152 310.476 474.188 325.312C455.964 379.775 417.654 426.727 368.562 456.375C338.873 474.306 305.37 485.916 270.812 489.344C249.343 491.473 227.586 490.471 206.406 486.344C189.62 483.072 173.257 477.836 157.5 471.219C129.113 459.298 103.445 441.446 81.75 419.656C65.2654 403.1 51.1791 384.423 38.5 364.844C38.1812 364.351 37.5235 364.213 37.0312 364.531C36.539 364.85 36.3999 365.508 36.7188 366C50.9288 387.941 66.9074 408.713 85.9375 426.719C106.83 446.486 131.108 462.459 157.625 473.594C175.303 481.017 193.88 486.569 212.812 489.656C232.035 492.791 251.622 493.36 271 491.438C294.974 489.059 318.571 482.795 340.656 473.188C350.986 468.694 360.924 463.448 370.562 457.625C395.742 442.413 418.154 422.349 436.375 399.281C454.61 376.196 468.744 349.81 477.531 321.719C484.329 299.987 487.917 277.3 488.156 254.531C488.347 236.406 486.416 218.215 482.438 200.531C469.873 144.681 437.033 94.114 391.656 59.3125C374.611 46.2397 355.882 35.534 336.031 27.3438C308.687 16.0614 278.974 10.3298 249.406 10.5Z' fill='%2325282a' stroke='none'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
}
Step 3 (JavaScript Code):
Finally, we need to create a function in JavaScript.
The script starts by defining two constants, contactDialog and sendButton, which reference elements in the HTML document with the IDs "confirm-dialog" and "send-message", respectively. These elements are likely part of the contact form that the script controls.
Next, an event listener is added to the contactDialog element. This listener listens for click events on the contact dialog, but only takes action if the user clicked outside of the dialog box itself. If the user clicked outside of the dialog, the function closeContactForm() is called, which animates the contact form and then closes it.
The showContactForm() and closeContactForm() functions are used to animate the contact form. showContactForm() displays the contact form by removing a clip-path property that hides it, displaying it as a modal, and setting its scale to 1.0. closeContactForm() hides the contact form by setting its scale to 0.0, adding a clip-path property that hides it, and then closing the modal.
The showShowcase() function is used to scroll the page to a showcase section when called. It does this by setting the location hash to "#portfolio" and then scrolling the portfolio element into view.
Finally, the sendButton element is assigned an event listener that listens for click events. When clicked, the listener sets the clip-path and transform properties of the contactDialog element to animate it, and then adds and removes classes on the sendButton element to animate it as well. After a delay of 1.5 seconds, the closeContactForm() function is called to hide the contact form.
Create a JavaScript file with the name of script.js and paste the given codes into your JavaScript file and make sure it's linked properly to your HTML document, so that the scripts are executed on the page. Remember, you’ve to create a file with .js extension.
Credit: Amit
const contactDialog = document.getElementById("confirm-dialog");
const sendButton = document.getElementById("send-message");
contactDialog.addEventListener("click", function (event) {
if (event.target !== contactDialog) {
return;
}
console.log(event.target.tagName);
if (
event.offsetX < 0 ||
event.offsetX > event.target.offsetWidth ||
event.offsetY < 0 ||
event.offsetY > event.target.offsetHeight
) {
closeContactForm();
}
});
function showContactForm() {
contactDialog.style.clipPath = "unset";
contactDialog.showModal();
contactDialog.style.transform = "scale(1)";
}
function closeContactForm() {
contactDialog.style.clipPath = "unset";
contactDialog.style.transform = "scale(0)";
contactDialog.close();
sendButton.classList.remove("spinner");
sendButton.classList.add("hover-effect");
}
function showShowcase() {
location.hash = "#portfolio";
document.getElementById("portfolio").scrollIntoView();
}
//only used to get path length for animation.
const logo = document.querySelectorAll("#big-circle");
for (let i = 0; i < logo.length; i++) {
console.log(logo[i].getTotalLength());
}
sendButton.addEventListener("click", (e) => {
/*let offsetTop = e.target.offsetTop;
let offsetLeft = e.target.offsetLeft;
let offsetHeight = e.target.offsetHeight;*/
let { offsetLeft, offsetTop, offsetHeight, offsetWidth } = e.target;
let strClipPath =
"polygon(" +
offsetLeft +
"px " +
offsetTop +
"px, " +
(offsetLeft + offsetWidth + 5) +
"px " +
offsetTop +
"px, " +
(offsetLeft + offsetWidth + 5) +
"px " +
(offsetTop + offsetHeight + 5) +
"px, " +
offsetLeft +
"px " +
(offsetTop + offsetHeight + 5) +
"px)";
contactDialog.style.clipPath = strClipPath;
contactDialog.style.transform = "translate(-25%, -25%)";
sendButton.classList.remove("hover-effect");
sendButton.classList.add("spinner");
setTimeout(closeContactForm, 1500);
});
Final Output:
Conclusion:
In conclusion, creating a unique Neobrutalist portfolio page with HTML, CSS, and JavaScript can be a fun and rewarding project for web designers and developers. By drawing inspiration from the raw and industrial-looking materials used in modernist architecture and embracing asymmetry, bold typography, and a monochromatic color palette, you can create a visually compelling and memorable portfolio page.
To create a Neobrutalist portfolio page, it's important to consider the specific needs and goals of your portfolio. The use of stripped-down, minimalist elements such as navigation menus and buttons, combined with bold and oversized typography, can help emphasize your key messages and draw attention to important information.
When it comes to the technical implementation, HTML, CSS, and JavaScript offer a range of tools and techniques for creating a Neobrutalist design. From using CSS grids and flexbox for asymmetrical layouts to incorporating rough textures and muted colors, there are many ways to create a unique and visually compelling Neobrutalist portfolio page.
Overall, creating a Neobrutalist portfolio page with HTML, CSS, and JavaScript offers a fresh and alternative approach to contemporary web and graphic design. By embracing the raw and industrial-looking aesthetic of Neobrutalism and prioritizing simplicity and functionality, you can create a portfolio page that is both visually striking and memorable.
That’s a wrap!
I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.
Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee
And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!
Thanks!
Faraz 😊