<nav class="main-nav w-full h-16">
<div class="container">
<div class="flex items-center h-16">
<div class="flex items-center w-full">
<div class="flex-shrink-0 z-50">
<a class="main-nav-logo" href="javascript:;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242.41 323.21">
<path d="M161.6 80.8v80.8H80.8V80.8H0v242.41h80.8v-80.8h80.8v80.8h80.81V80.8H161.6zM80.8 0h80.8v80.8H80.8z" />
</svg>
</a>
</div>
<div class="flex ml-auto">
<div class="select-wrapper">
<div class="select-prepend">
<svg aria-hidden="true" class="w-4 h-4" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M8 256c0 136.966 111.033 248 248 248s248-111.034 248-248S392.966 8 256 8 8 119.033 8 256zm248 184V72c101.705 0 184 82.311 184 184 0 101.705-82.311 184-184 184z"></path>
</svg>
</div>
<label class="sr-only" for="theme-select">Set Theme</label>
<select name="theme" id="theme-select">
</select>
<div class="select-append">
<svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="w-4 h-4">
<path fill="currentColor" d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"></path>
</svg>
</div>
</div>
<button class="menu-btn"><svg class="block h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
<g class="menu">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
</g>
<g class="close-menu">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</g>
</svg></button>
<div class="menu-dropdown">
<ul>
<li>
<a href="javascript:;">Menu item 1</a>
</li>
<li>
<a href="javascript:;">Menu item 2</a>
</li>
<li>
<a href="javascript:;">Menu item 3</a>
</li>
<li>
<a href="javascript:;">Menu item 4</a>
</li>
<li>
<a href="javascript:;">Menu item 5</a>
</li>
<li>
<a href="javascript:;">Menu item 6</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</nav>
<main>
<div class="container">
<h1 class="page-title">The Lord of the Rings Vinyl Figures</h1>
<div class="card-container p-4 rounded-xl md:p-8">
<div class="
grid
gap-4
grid-cols-1
sm:grid-cols-2
md:gap-8
lg:grid-cols-3
xl:grid-cols-4
">
<div class="group homepage-card relative p-4 w-full rounded-lg">
<div class="card-img-wrapper rounded-md"><img src="https://dhs1n389ze6jv.cloudfront.net/img/product-thumb/1521431900460b50b418b0b56d17ceb711c6d74a5d.png" alt="" />
<div class="card-text-wrapper">
<a href="javascript:;" class="homepage-card-link">Aragorn</a>
<p class="homepage-card-text">
I am Aragorn son of Arathorn, the heir of Isildur Elendil's son of Gondor.
</p>
</div>
</div>
</div>
<div class="group homepage-card relative p-4 w-full rounded-lg">
<div class="card-img-wrapper rounded-md"><img src="https://dhs1n389ze6jv.cloudfront.net/img/product-thumb/15663525367ad75fd6129f72e68cd03e74f2dbb4fe.png" alt="" />
<div class="card-text-wrapper">
<a href="javascript:;" class="homepage-card-link">Frodo</a>
<p class="homepage-card-text">
Son of Drogo Baggins, was a Hobbit of the Shire during the Third Age.
</p>
</div>
</div>
</div>
<div class="group homepage-card relative p-4 w-full rounded-lg">
<div class="card-img-wrapper rounded-md"><img src="https://dhs1n389ze6jv.cloudfront.net/img/product-thumb/149973921567fd975a4617446887acc6c08fb305c7.png" alt="" />
<div class="card-text-wrapper">
<a href="javascript:;" class="homepage-card-link">Gimli
</a>
<p class="homepage-card-text">
Gimli, son of Glóin, was a well-respected dwarf warrior in Middle-earth during the Great Years
</p>
</div>
</div>
</div>
<div class="group homepage-card relative p-4 w-full rounded-lg">
<div class="card-img-wrapper rounded-md"><img src="https://dhs1n389ze6jv.cloudfront.net/img/product-thumb/1521432160f44e2dc9e68acaab0400a3400705ba39.png" alt="" />
<div class="card-text-wrapper">
<a href="javascript:;" class="homepage-card-link">Legolas
</a>
<p class="homepage-card-text">
For the Elves the world moves, and it moves both very swift and very slow.
</p>
</div>
</div>
</div>
<div class="group homepage-card relative p-4 w-full rounded-lg">
<div class="card-img-wrapper rounded-md"><img src="https://dhs1n389ze6jv.cloudfront.net/img/product-featured/16163541776578f15916a41cbfb885676d6ce1c6fe.png" alt="" />
<div class="card-text-wrapper"><a href="javascript:;" class="homepage-card-link">Gandalf</a>
<p class="homepage-card-text">
He wore a tall pointed blue hat, a long grey cloak, and a silver scarf.
</p>
</div>
</div>
</div>
<div class="group homepage-card relative p-4 w-full rounded-lg">
<div class="card-img-wrapper rounded-md"><img src="https://dhs1n389ze6jv.cloudfront.net/img/product-thumb/154561363578536b8ce88750bd1e8085088b8eb679.png" alt="" />
<div class="card-text-wrapper"><a href="javascript:;" class="homepage-card-link">Boromir</a>
<p class="homepage-card-text">
The Ring! Is it not a strange fate that we should suffer so much fear and doubt for so small a thing?
</p>
</div>
</div>
</div>
<div class="group homepage-card relative p-4 w-full rounded-lg">
<div class="card-img-wrapper rounded-md"><img src="https://dhs1n389ze6jv.cloudfront.net/img/product-thumb/1543867212ee34ee224da3f14d2d2c9eca9fc2e018.png" alt="" />
<div class="card-text-wrapper"><a href="javascript:;" class="homepage-card-link">The Witch King</a>
<p class="homepage-card-text">
A crown of steel he bore, but between rim and robe naught was there to see, save only a deadly gleam of eyes.
</p>
</div>
</div>
</div>
<div class="group homepage-card relative p-4 w-full rounded-lg">
<div class="card-img-wrapper rounded-md"><img src="https://dhs1n389ze6jv.cloudfront.net/img/product-thumb/1521431384955c3ac66ee3a3497306a9b73206843a.png" alt="" />
<div class="card-text-wrapper"><a href="javascript:;" class="homepage-card-link">Gandalf the Grey</a>
<p class="homepage-card-text">
He had a long white beard and bushy eyebrows that stuck out beyond the brim of his hat.
</p>
</div>
</div>
</div>
<div class="group homepage-card relative p-4 w-full rounded-lg">
<div class="card-img-wrapper rounded-md"><img src="https://dhs1n389ze6jv.cloudfront.net/img/product-thumb/14997405306ae9d481e71d4d2be4feec7a9ca0dc6d.png" alt="" />
<div class="card-text-wrapper"><a href="javascript:;" class="homepage-card-link">Gollum</a>
<p class="homepage-card-text">
Don’t pay attention to those STUPID fat hobbitses. Gollum’s got a fish, raw and wriggling.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<footer class="homepage-footer">
<div class="container">
<div class="flex justify-center pt-8">
<a class="morph-btn" href="https://github.com/AndrewHeinke" target="_blank" rel="noopener noreferrer">
<svg viewBox="0 0 16 16" aria-hidden="true">
<path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>
</svg>
</a>
<a class="morph-btn" href="https://www.linkedin.com/in/andrewheinke/" target="_blank" rel="noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 34 34">
<path d="M34 2.5v29a2.5 2.5 0 01-2.5 2.5h-29A2.5 2.5 0 010 31.5v-29A2.5 2.5 0 012.5 0h29A2.5 2.5 0 0134 2.5zM10 13H5v16h5zm.45-5.5a2.88 2.88 0 00-2.86-2.9H7.5a2.9 2.9 0 000 5.8 2.88 2.88 0 002.95-2.81zM29 19.28c0-4.81-3.06-6.68-6.1-6.68a5.7 5.7 0 00-5.06 2.58h-.14V13H13v16h5v-8.51a3.32 3.32 0 013-3.58h.19c1.59 0 2.77 1 2.77 3.52V29h5z" />
</svg>
</a>
<a class="morph-btn" href="https://www.instagram.com/andrewheinke/" target="_blank" rel="noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 169.063 169.063">
<path d="M122.406 0H46.654C20.929 0 0 20.93 0 46.655v75.752c0 25.726 20.929 46.655 46.654 46.655h75.752c25.727 0 46.656-20.93 46.656-46.655V46.655C169.063 20.93 148.133 0 122.406 0zm31.657 122.407c0 17.455-14.201 31.655-31.656 31.655H46.654C29.2 154.063 15 139.862 15 122.407V46.655C15 29.201 29.2 15 46.654 15h75.752c17.455 0 31.656 14.201 31.656 31.655v75.752z" />
<path d="M84.531 40.97c-24.021 0-43.563 19.542-43.563 43.563 0 24.02 19.542 43.561 43.563 43.561s43.563-19.541 43.563-43.561c0-24.021-19.542-43.563-43.563-43.563zm0 72.123c-15.749 0-28.563-12.812-28.563-28.561 0-15.75 12.813-28.563 28.563-28.563s28.563 12.813 28.563 28.563c0 15.749-12.814 28.561-28.563 28.561zM129.921 28.251c-2.89 0-5.729 1.17-7.77 3.22a11.053 11.053 0 00-3.23 7.78c0 2.891 1.18 5.73 3.23 7.78 2.04 2.04 4.88 3.22 7.77 3.22 2.9 0 5.73-1.18 7.78-3.22 2.05-2.05 3.22-4.89 3.22-7.78 0-2.9-1.17-5.74-3.22-7.78-2.04-2.05-4.88-3.22-7.78-3.22z" />
</svg>
</a>
</div>
</div>
</footer>
:root {
--bg-color: 31, 39, 51;
--shadow-light: #273140;
--shadow-dark: #171d26;
--text-color: #d8e8f6;
--link-color: #3ba7e9;
}
html,
body {
font-family: "Inter", sans-serif;
background-color: rgb(var(--bg-color));
transition: background-color 300ms ease;
}
/* nav styles */
.main-nav {
z-index: 99;
background-color: rgb(var(--bg-color));
transition: background-color 300ms ease;
margin-bottom: 2rem;
}
.main-nav-logo {
padding: 0.5rem;
cursor: pointer;
display: block;
border-radius: 0.5rem;
outline: none;
background: rgb(var(--bg-color));
box-shadow: 0px 0px 0px var(--link-color), 0px 0px 0px var(--shadow-dark),
0px 0px 0px var(--shadow-light), inset 0px 0px 0px var(--shadow-dark),
inset 0px 0px 0px var(--shadow-light);
transition: background 300ms ease, box-shadow 300ms ease;
}
.main-nav-logo:hover {
box-shadow: 0 0 0 0px var(--link-color), 0px 0px 0px var(--shadow-dark),
0px 0px 0px var(--shadow-light), inset 5px 5px 10px var(--shadow-dark),
inset -5px -5px 10px var(--shadow-light);
transition: box-shadow 300ms ease;
}
.main-nav-logo:focus {
box-shadow: 0 0 0 2px var(--link-color), 0px 0px 0px var(--shadow-dark),
0px 0px 0px var(--shadow-light), inset 5px 5px 10px var(--shadow-dark),
inset -5px -5px 10px var(--shadow-light);
transition: box-shadow 300ms ease;
outline: none;
}
.main-nav-logo svg {
height: 2rem;
width: 2rem;
fill: var(--link-color);
transition: fill 300ms ease;
}
.select-wrapper {
z-index: 99;
border-radius: 0.5rem;
display: flex;
position: relative;
background: rgb(var(--bg-color));
box-shadow: 5px 5px 10px var(--shadow-dark),
-5px -5px 10px var(--shadow-light), inset 0px 0px 0px var(--shadow-dark),
inset 0px 0px 0px var(--shadow-light);
transition: background 300ms ease, box-shadow 300ms ease;
width: 130px;
padding: 0.25rem 0;
margin-right: 1rem;
justify-content: space-between;
flex-shrink: 0;
}
.select-wrapper:focus-within {
box-shadow: 0 0 0 2px var(--link-color), 5px 5px 10px var(--shadow-dark),
-5px -5px 10px var(--shadow-light), inset 0px 0px 0px var(--shadow-dark),
inset 0px 0px 0px var(--shadow-light);
}
.select-prepend {
display: flex;
border-top-left-radius: 0.5rem;
border-bottom-left-radius: 0.5rem;
align-items: center;
padding: 0.5rem 0.5rem;
justify-content: center;
color: var(--text-color);
background-color: transparent;
height: 100%;
}
.select-append {
display: flex;
border-top-right-radius: 0.5rem;
border-bottom-right-radius: 0.5rem;
align-items: center;
padding: 0.5rem 0.5rem;
justify-content: center;
color: var(--text-color);
background-color: transparent;
height: 100%;
}
#theme-select {
flex: 1;
cursor: pointer;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
border-radius: 0.5rem;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
padding: 0.25rem 2rem 0.25rem 2rem;
outline: none;
border: none;
box-shadow: none;
color: var(--text-color);
width: 100%;
background-image: none;
background-color: transparent;
-webkit-appearance: none;
-moz-appearance: none;
}
.page-title {
color: var(--text-color);
font-weight: bolder;
font-size: 3.5rem;
line-height: 1;
margin-bottom: 1em;
text-shadow: 0 .25rem .25rem var(--shadow-dark);
transition: 300ms ease;
@media screen and (max-width: 1024px) {
font-size: 3rem;
}
@media screen and (max-width: 768px) {
font-size: 1.5rem;
line-height: 1.25;
}
}
.card-container {
background-color: rgb(var(--bg-color));
margin-bottom: 4rem;
box-shadow: -2px -2px 4px 0px var(--shadow-light),
0px 40px 40px 0px var(--shadow-dark);
transition: background-color 300ms ease, box-shadow 300ms ease;
z-index: 10;
}
.homepage-card {
box-shadow: 0 0 0 0 var(--link-color), 4px 4px 8px var(--shadow-dark),
-4px -4px 8px var(--shadow-light), inset 0px 0px 0px 0px var(--shadow-dark),
inset 0px 0px 0px 0px var(--shadow-light);
background-color: rgb(var(--bg-color));
cursor: pointer;
border: none;
position: relative;
transition: box-shadow 300ms ease, background-color 300ms ease;
&:hover,
&:focus-within {
box-shadow: 0 0 0 2px var(--link-color), 0px 0px 0px var(--shadow-dark),
0px 0px 0px var(--shadow-light), inset 4px 4px 8px var(--shadow-dark),
inset -4px -4px 8px var(--shadow-light);
transition: box-shadow 300ms ease;
}
}
.homepage-card-link {
cursor: pointer;
display: inline-flex;
align-items: center;
font-weight: 600;
font-size: 1.25rem;
line-height: 1.5rem;
outline: 2px solid transparent;
outline-offset: 2px;
color: var(--link-color);
transition: color 300ms ease;
&::after {
content: "";
background-color: transparent;
pointer-events: auto;
position: absolute;
top: -1rem;
right: -1rem;
bottom: -1rem;
left: -1rem;
z-index: 10;
}
}
.homepage-card-text {
font-size: 0.875rem;
line-height: 1.25rem;
margin-top: 0.25rem;
margin-bottom: 0.25rem;
color: var(--text-color);
transition: color 300ms ease;
}
.stretched-link::after {
content: "";
@apply z-10 absolute inset-0 bg-transparent pointer-events-auto;
}
.container {
width: 100%;
margin-right: auto;
margin-left: auto;
padding-right: 1rem;
padding-left: 1rem;
}
@media (min-width: 640px) {
.container {
max-width: 640px;
}
}
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1024px;
}
}
@media (min-width: 1280px) {
.container {
max-width: 1280px;
}
}
@media (min-width: 1536px) {
.container {
max-width: 1536px;
}
}
.menu-btn {
border-radius: 0.375rem;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.5rem;
color: var(--text-color);
background: rgb(var(--bg-color));
box-shadow: 5px 5px 10px var(--shadow-dark),
-5px -5px 10px var(--shadow-light), inset 0 0 0 var(--shadow-dark),
inset 0 0 0 var(--shadow-light);
transition: background 0.5s ease, box-shadow 0.5s ease;
border-radius: 0.5rem;
position: relative;
&:hover {
&::after {
box-shadow: 2px 2px 2px 0px var(--shadow-dark) inset,
-2px -2px 2px 0px var(--shadow-light) inset;
content: "";
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
border-radius: 0.25rem;
transition: box-shadow 300ms ease;
}
}
&:focus {
outline: none;
&::after {
box-shadow: 2px 2px 2px 0px var(--shadow-dark) inset,
-2px -2px 2px 0px var(--shadow-light) inset;
content: "";
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
border-radius: 0.25rem;
transition: box-shadow 300ms ease;
}
}
}
.menu-btn {
z-index: 99;
.menu {
stroke: currentColor;
}
.close-menu {
stroke: transparent;
}
}
.menu-btn.open {
.menu {
stroke: transparent;
}
.close-menu {
stroke: currentColor;
}
}
.menu-dropdown {
visibility: hidden;
opacity: 0;
position: absolute;
left: 0;
top: 0;
bottom: 0;
padding: 5rem 2rem 3rem;
width: 100%;
z-index: 20;
background: rgb(var(--bg-color));
transition: ease 300ms;
}
.menu-dropdown.show {
visibility: visible;
opacity: 1;
}
.menu-dropdown {
a {
color: var(--link-color);
font-size: 2rem;
line-height: 1.25;
font-weight: bold;
display: block;
text-decoration: underline;
cursor: pointer;
outline: none;
border-radius: 0.5rem;
padding: 0.5rem 1rem;
margin-bottom: 1rem;
border: 2px solid transparent;
transition: 300ms ease;
text-align: center;
&:focus {
outline: none;
border: 2px solid var(--link-color);
background: var(--shadow-dark);
}
&:hover {
background: var(--shadow-dark);
}
}
}
.card-img-wrapper {
background: rgb(var(--bg-color));
display: flex;
height: 250px;
align-items: center;
justify-content: center;
position: relative;
transition: all ease 300ms;
img {
max-height: 100%;
max-width: 100%;
z-index: 0;
opacity: 0.9;
transition: ease 300ms;
pointer-events: none;
}
}
.card-text-wrapper {
background: linear-gradient(0deg, rgb(var(--bg-color)) 0%, rgba(var(--bg-color), 0) 100%);
background-size: 100% 100%;
content: "";
left: 0;
position: absolute;
top: 0;
opacity: 1;
width: 100%;
height: 100%;
z-index: 1;
border-radius: 0.5rem;
transition: ease 300ms;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.homepage-card:hover,
.homepage-card:focus-within {
.card-text-wrapper {
opacity: 0.25;
transition: ease 300ms;
z-index: 0;
}
img {
z-index: 1;
opacity: 1;
transition: ease 300ms;
transform: translateY(-15%);
}
}
.morph-btn {
border-radius: 1rem;
width: 64px;
height: 64px;
display: flex;
outline: none;
margin: 0 0.5rem;
justify-content: center;
align-items: center;
background: rgb(var(--bg-color));
box-shadow: 5px 5px 10px var(--shadow-dark),
-5px -5px 10px var(--shadow-light), inset 0px 0px 0px var(--shadow-dark),
inset 0px 0px 0px var(--shadow-light);
transition: background 300ms ease, box-shadow 300ms ease;
}
.morph-btn:hover,
.morph-btn:focus {
box-shadow: 0px 0px 0px var(--shadow-dark), 0px 0px 0px var(--shadow-light),
inset 5px 5px 10px var(--shadow-dark),
inset -5px -5px 10px var(--shadow-light);
transition: box-shadow 300ms ease;
}
.morph-btn svg {
width: 2rem;
height: 2rem;
fill: var(--link-color);
transition: fill 300ms ease;
}
#cloned-card {
position: fixed;
background: rgba(#000, 0);
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
z-index: 999;
opacity: 0;
animation: fadeIn 300ms;
animation-fill-mode: forwards;
filter: blur(0);
.homepage-card-text {
display: none;
}
.homepage-card-link {
position: absolute;
width: 100%;
display: block;
text-align: center;
font-size: 1.5rem;
font-weight: bolder;
writing-mode: vertical-lr;
bottom: 1rem;
left: 1rem;
text-orientation: upright;
pointer-events: none;
}
.buy-button {
background: rgb(var(--bg-color));
color: var(--text-color);
border: 2px solid var(--link-color);
position: relative;
top: -2rem;
padding: 1rem 2rem;
border-radius: .5rem;
box-shadow: 0 0 20px 0px var(--link-color);
z-index: 50;
&:hover {
background: var(--link-color);
color: rgb(var(--bg-color));
transition: fill 300ms ease;
}
&:focus {
background: var(--link-color);
color: rgb(var(--bg-color));
outline: none;
transition: fill 300ms ease;
}
}
.close-button {
position: absolute;
background: transparent;
display: flex;
justify-content: center;
align-items: center;
color: var(--link-color);
right: 2rem;
top: 2rem;
width: 44px;
height: 44px;
border-radius: .5rem;
border: 2px solid transparent;
&:focus {
outline: none;
border: 2px solid var(--link-color);
}
}
.card-img-wrapper {
max-width: 300px;
width: 100%;
margin: 0 auto;
border: 2px solid var(--link-color);
position:relative;
box-shadow: 0 0 20px 0px var(--link-color);
img {
max-height: none;
height: 350px;
position: absolute;
top: -100px;
opacity: 1;
}
}
.card-text-wrapper {
position: unset;
}
.homepage-card-link {
&::after {
content: none;
}
}
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
body.filter-blur > *:not(#cloned-card) {
filter: blur(7px);
transition: 300ms ease;
}
footer {
margin: 2rem 0;
}
View Compiled
const colorSchemes = [
{
name: "Dark",
bgColor: "31, 39, 51",
shadowLight: "#273140",
shadowDark: "#171d26",
textColor: "#D8E8F6",
linkColor: "#3BA7E9"
},
{
name: "Light",
bgColor: "238, 238, 238",
shadowLight: "#ffffff",
shadowDark: "#cacaca",
textColor: "#6b7280",
linkColor: "#6d28d9"
},
{
name: "Cream",
bgColor: "241, 226, 199",
shadowLight: "#fff2d5",
shadowDark: "#e0d2b9",
textColor: "#5A5353",
linkColor: "#1EA896"
},
{
name: "Blue",
bgColor: "39, 122, 247",
shadowLight: "#2b86ff",
shadowDark: "#236ede",
textColor: "#EFEFEF",
linkColor: "#CEFF1A"
},
{
name: "Green",
bgColor: "124, 165, 105",
shadowLight: "#87B472",
shadowDark: "#719660",
textColor: "#111D13",
linkColor: "#59114D"
},
{
name: "Purple",
bgColor: "102, 8, 196",
shadowLight: "#7509e1",
shadowDark: "#5707A7",
textColor: "#BCF8EC",
linkColor: "#F9CFF2"
},
{
name: "Orange",
bgColor: "252, 121, 0",
shadowLight: "#ff8b00",
shadowDark: "#d66700",
textColor: "#303336",
linkColor: "#1D2F6F"
},
{
name: "Gray",
bgColor: "58, 56, 66",
shadowLight: "#43404c",
shadowDark: "#313038",
textColor: "#D8E8F6",
linkColor: "#44CF6C"
},
{
name: "Pink",
bgColor: "251, 192, 189",
shadowLight: "#ffccc8",
shadowDark: "#ecb4b2",
textColor: "#111D4A",
linkColor: "#5F56B3"
}
];
const FOCUSABLE_SELECTORS =
"a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]";
const root = document.documentElement;
const menuBtn = document.querySelector(".menu-btn");
const menu = document.querySelector(".menu-dropdown");
const themeSelect = document.getElementById("theme-select");
const optGroup = document.createElement("optgroup");
optGroup.label = "Themes";
themeSelect.appendChild(optGroup);
colorSchemes.forEach((element, index) => {
themeSelect.add(new Option(element.name, index));
});
let colorIndex = 0;
themeSelect.addEventListener("change", function () {
colorIndex = this.value;
setStyles(colorIndex);
});
menuBtn.addEventListener("click", function () {
menuBtn.classList.toggle("open");
menu.classList.toggle("show");
});
function setStyles(colorIndex) {
let activeColor = colorSchemes[colorIndex];
root.style.setProperty("--bg-color", activeColor.bgColor);
root.style.setProperty("--text-color", activeColor.textColor);
root.style.setProperty("--shadow-light", activeColor.shadowLight);
root.style.setProperty("--shadow-dark", activeColor.shadowDark);
root.style.setProperty("--link-color", activeColor.linkColor);
}
const cardContainer = document.querySelector(".card-container");
cardContainer.addEventListener("click", (e) => {
if (e.target.classList.contains("homepage-card-link")) {
const closeModal = (element, triggerElement) => {
element.remove();
document.body.classList.remove("filter-blur");
// Untrap the tab focus by removing tabindex=-1. You should restore previous values if an element had them.
const focusableElements = document.querySelectorAll(FOCUSABLE_SELECTORS);
focusableElements.forEach((el) => el.removeAttribute("tabindex"));
// restore focus to the triggering element
triggerElement.focus();
// remove escape keydown listener from document
document.removeEventListener("keydown", escapeHandler);
};
const escapeHandler = () => {
const evt = window.event;
let isEscape = false;
if ("key" in evt) {
isEscape = evt.key === "Escape" || evt.key === "Esc";
} else {
isEscape = evt.keyCode === 27;
}
if (isEscape) {
closeModal(clonedCard, e.target);
}
};
// close modal on escape key press
document.addEventListener("keydown", escapeHandler);
let target = e.target;
// clone the clicked card
let card = e.target.closest(".homepage-card");
let clonedCard = card.cloneNode(true);
clonedCard.classList.remove("homepage-card");
clonedCard.id = "cloned-card";
// add buttons to cloned card
let btn = document.createElement("button");
btn.innerText = "Buy Now";
btn.classList.add("buy-button");
clonedCard.appendChild(btn);
let closeBtn = document.createElement("button");
closeBtn.innerHTML = `<svg class="block h-8 w-8" stroke="currentColor" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>`;
closeBtn.classList.add("close-button");
clonedCard.appendChild(closeBtn);
document.body.appendChild(clonedCard);
document.body.classList.add("filter-blur");
closeBtn.addEventListener("click", () => {
closeModal(clonedCard, target);
});
const focusableElements = document.querySelectorAll(FOCUSABLE_SELECTORS);
focusableElements.forEach((el) => el.setAttribute("tabindex", "-1"));
const modalFocusableElements = clonedCard.querySelectorAll(
FOCUSABLE_SELECTORS
);
modalFocusableElements.forEach((el) => el.setAttribute("tabindex", "0"));
clonedCard.querySelector(FOCUSABLE_SELECTORS).focus();
// close modal on mask click
clonedCard.addEventListener("click", function (e) {
if (e.target.id === "cloned-card") {
closeModal(clonedCard, target);
}
});
}
});
// save color theme selection to local storage
document.addEventListener('DOMContentLoaded', function() {
const myStorage = window.localStorage;
document.getElementById("theme-select").addEventListener("change", function () {
populateStorage();
});
if (!myStorage.getItem("colorIndex")) {
populateStorage();
} else {
setStyles();
}
function setStyles() {
let colorIndex = myStorage.getItem("colorIndex");
let activeColor = colorSchemes[colorIndex];
document.getElementById("theme-select").value = colorIndex;
root.style.setProperty("--bg-color", activeColor.bgColor);
root.style.setProperty("--text-color", activeColor.textColor);
root.style.setProperty("--shadow-light", activeColor.shadowLight);
root.style.setProperty("--shadow-dark", activeColor.shadowDark);
root.style.setProperty("--link-color", activeColor.linkColor);
}
function populateStorage() {
myStorage.setItem(
"colorIndex",
document.getElementById("theme-select").value
);
setStyles();
}
}, false);
View Compiled
This Pen doesn't use any external JavaScript resources.