JSFiddle - React, Tailwind, and code Playground

by Milan Gladiš

HTML

<div class="container">
  <div class="team">
    <div class="member">
      <div class="card">
        <div class="title">
          <div class="name">Sam Huber</div>
          <div class="role">CEO</div>
        </div>
        <div class="picture">
          <div class="pictureWrapper"><img width="165" height="246" src="https://i.postimg.cc/cLL03kwz/team-1.png" alt="Sam Huber" draggable="false"></div>
        </div>
      </div>
      <div class="quote quote-responsive">
        <p>“As the world’s largest metaverse builder, LandVault is the backbone of the metaverse. We create. We promote. We build. LandVault is the top choice in the space for globally renowned brands.”</p>
        <div class="name">Sam Huber</div>
        <div class="role">CEO</div>
      </div>  
    </div>

    <div class="member">
      <div class="card">
        <div class="title">
          <div class="name">Katie Wan</div>
          <div class="role">VP of People</div>
        </div>
        <div class="picture">
          <div class="pictureWrapper"><img width="165" height="246" src="https://i.postimg.cc/t4dnR4Fj/team-2.png" alt="Katie Wan" draggable="false"></div>
        </div>
      </div>
      <div class="quote quote-responsive">
        <p>“As the world’s largest metaverse builder, LandVault is the backbone of the metaverse. We create. We promote. We build. LandVault is the top choice in the space for globally renowned brands.”</p>
        <div class="name">Katie Wan</div>
        <div class="role">VP of People</div>
      </div>
    </div>

    <div class="member active">
      <div class="card">
        <div class="title">
          <div class="name">Raul Cerezo de la Puente</div>
          <div class="role">Creative Solutions Director</div>
        </div>
        <div class="picture">
          <div class="pictureWrapper"><img width="165" height="246" src="https://i.postimg.cc/htR7qdzs/team-3.png" alt="Raul Cerezo de la Puente" draggable="false"></div>
        </div>
     ...

CSS

body {
  background-color: #151617;
  font-family: "Inter", sans-serif;
  padding-top: 40px;
}

.container  {
  max-width: 850px;
  margin: auto;
  padding: 32px;
}

.team {
  display: flex;
  gap: 32px;
  margin-bottom: 40px;
  position: relative;
  user-select: none;
}

.member {
  margin: 2px;
  flex: 1;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.card {
  position: relative;
  overflow: hidden;
  border-radius: 8px;
  max-width: 100%;
  transition: all 0.15s ease;
  cursor: pointer;
}

.member:hover .card {
  box-shadow: 0 0 0 2px rgba(255,255,255,0.2)
}

.member.active .card {
  box-shadow: 0 0 0 2px rgba(255,255,255,1)
}

.title {
  position: absolute;
  bottom: 16px;
  left: 16px;
  z-index: 1;
  color: #fff;
  line-height: 130%;
}

.picture {
  position: relative;
}

.pictureWrapper:after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 44.27%, rgba(0, 0, 0, 0.7) 100%), linear-gradient(180deg, rgba(48, 99, 177, 0) 44.27%, rgba(48, 99, 177, 0.7) 100%), url(image.png);
}

img {
  width: 100%;
  object-fit: cover;
  display: block;
}

.name {
  font-size: 16px;
  font-weight: 600;
}

.role {
  font-size: 14px;
  opacity: 0.5;
  margin-top: 4px;
}

.quote {
  padding: 0 48px;
  position: relative;
  color: white;
  text-align: center;
}

.quote p {
  max-width: 600px;
  margin: auto;
  margin-bottom: 16px;
}

.quote-responsive {
  display: none;
}

.arrow {
  position: absolute;
  z-index: 1;
  top: 40px;
  cursor: pointer;
}

.arrow-left {
  left: 0px;
}

.arrow-right {
  right: 0px;
}

@media (max-width: 680px) {
  .team {
    flex-direction: column;
  }
  .member {
    margin-bottom: 40px;
  }
  .card {
    margin-bottom: 24px;
  }
.member:hover .card, .member.active .card {
    box-shadow: none;
  }
  .title {
    display: none;
  }
  
  .quote {
    padding: 0;
  }
  
  #quote {
    display:...

JavaScript

var team = [
  {
    quote: 'As the world’s largest metaverse builder, LandVault is the backbone of the metaverse. We create. We promote. We build. ',
    name: "Sam Huber",
    role: 'CEO'
  },
  {
    quote: 'We build. LandVault is the top choice in the space for globally renowned brands. ',
    name: "Katie Wan",
    role: 'VP of People'
  },
  {
    quote: 'Lorem ipsum LandVault is the top choice in the space for globally renowned brands. ',
    name: "Raul Cerezo de la Puente",
    role: 'Creative Solutions Director'
  },
  {
    quote: 'LandVault is the top choice in the space for globally renowned brands. ',
    name: "Loadfruit",
    role: 'VP Metaverse Ops'
  },
  {
    quote: 'LandVault is the backbone of the metaverse. We create. We promote. We build as the world’s largest metaverse builder. ',
    name: "Marcin Gierlak",
    role: 'VP of Engineering'
  }
]

const teamMembers = document.querySelectorAll(".member");
const quote = document.querySelector("#quote p");
const quoteName = document.querySelector("#name");
const quoteRole = document.querySelector("#role");
const leftArrow = document.querySelector(".arrow-left");
const rightArrow = document.querySelector(".arrow-right");

let currentIndex = 2;

teamMembers.forEach((member, i) => {
    member.addEventListener("click", () => setQuote(i));
});

leftArrow.addEventListener("click", () => setQuote(--currentIndex < 0 ? teamMembers.length-1 : currentIndex));
rightArrow.addEventListener("click", () => setQuote(++currentIndex >= teamMembers.length ? 0 : currentIndex));

function setQuote(index) {
    currentIndex = index;
    const activeMember = document.querySelector(".member.active");
    activeMember.classList.remove("active");
    teamMembers[index].classList.add("active");
    quote.textContent = team[index].quote;
    quoteName.textContent = team[index].name;
    quoteRole.textContent = team[index].role;
}