<!-- Source : https://codepen.io/smnarnold -->
<div class="grid">
  <div class="cell cell--cloud">
    <div class="cloud">
      <svg class="cloud__svg" viewBox="0 0 300 300">
        <path d="M110.9 66.9c-12.4 2-23.6 7.5-31.8 15.7-9.7 9.7-15.5 22.4-16.7 36.5l-.4 4.6-6.2.4c-11.5.7-24.4 5.2-33.3 11.6-7.2 5.2-15 14.5-18.3 21.9-3 6.9-4.1 12.1-4.1 19.9 0 22.7 11.2 41 29.8 48.5 9.6 3.9.7 3.6 116.5 3.6h105.1l5.4-1.5c28.6-7.5 46-31.1 42.8-57.7-1.5-12.4-6.1-22.7-14.2-31.2-9.6-10.2-19.9-15-35.4-16.7l-6.4-.7-2.5-4.2c-3.5-5.8-12.1-14.4-18.4-18.1-15.5-9.2-35-10.5-50.6-3.6-2.1 1-3.8 1.4-3.9 1-.9-2.7-5.6-9.2-9.6-13.3-7.8-7.9-16.9-13.1-27.7-15.7-4.8-1.3-15.4-1.8-20.1-1zm19.9 10.6c9 2.5 18.8 9 24.2 16.1 1.6 2.1 4.1 6.2 5.6 9.1 3.5 7.1 4.5 7.4 11.8 3.6 7.9-4.1 12.5-5.2 21.5-5.2 8.9.1 13.1.9 20.1 4.3 9.1 4.4 16.5 11.8 21.5 21.6 2.7 5.3 4 6.1 8.1 5.1 3.3-.7 10.1-.1 15.1 1.5 7.6 2.3 13.5 5.8 18.8 11.1 4.2 4.2 5.4 5.9 8 11.3 11.4 23.4 2.9 47.6-20.7 59-11 5.3.1 4.8-118.8 4.8-101.4 0-105.6-.1-108.8-1.2-5.1-1.8-10.9-5-14.4-7.9-13.1-11.5-17.5-35.1-9.4-50.9 4.8-9.5 15-18.1 26.8-22.7 6.9-2.7 13.3-3.8 21.6-3.8 9.9 0 9.6.3 10.1-11.1.4-9.7 1.4-13.9 5.5-21.8 3.5-6.8 12.1-15.4 18.9-18.9 5-2.5 9.1-4.1 13.7-5 3.9-.7 16.6-.2 20.8 1z" />
      </svg>
    </div>
  </div>

  <div class="cell">
    <div class="sub-cell">
      <button class="button no1">Commit</button>
    </div>
    <div class="sub-cell">
      <button class="button no2">Commit</button>
    </div>
  </div>

  <div class="cell">
    <div class="sub-cell">
      <div class="laptop">
        <svg class="laptop__svg" viewBox="0 0 300 300">
          <path d="M171 219v3c0 1.7-1.3 3-3 3h-36c-1.7 0-3-1.3-3-3v-3H0v6s0 9 9 9h282c9 0 9-9 9-9v-6H171zM255 66H45c-5 0-9 4-9 9v126c0 5 4 9 9 9h210c5 0 9-4 9-9V75c0-5-4-9-9-9zm-3 132H48V78h204v120z" />
        </svg>
        <div class="laptop__persona">👩</div>
        <div class="laptop__content">
          <div class="laptop__content__animation animation no1">💾</div>
        </div>
      </div>
    </div>

    <div class="sub-cell">
      <div class="laptop no2">
        <svg class="laptop__svg" viewBox="0 0 300 300">
          <path d="M171 219v3c0 1.7-1.3 3-3 3h-36c-1.7 0-3-1.3-3-3v-3H0v6s0 9 9 9h282c9 0 9-9 9-9v-6H171zM255 66H45c-5 0-9 4-9 9v126c0 5 4 9 9 9h210c5 0 9-4 9-9V75c0-5-4-9-9-9zm-3 132H48V78h204v120z" />
        </svg>
        <div class="laptop__persona">👨</div>
        <div class="laptop__content">
          <div class="laptop__content__animation animation no2">💾</div>
        </div>
      </div>
    </div>
  </div>
</div>

<div class="mask"></div>
<div class="popup">De nouveaux changements sont disponibles en ligne. Vous devez les tirer avant de pousser vos changements.</div>
:root {
  --primary: #fefefe;
  --secondary: rgb(39, 42, 53);
  --green: #00c774;
  --green-dark: #009e24;
  --red: #ff8487;
  --red-dark: #ff262b;
}

@media (prefers-color-scheme: dark) {
  :root {
    --primary: rgb(39, 42, 53);
    --secondary: #fefefe;
  }
}

* {
  box-sizing: border-box;
}

body {
  display: flex;
  width: 100%;
  height: 100vh;
  justify-content: center;
  align-items: center;
  color: var(--secondary);
  background-color: var(--primary);
}

.grid {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  width: 100vmin;
  margin: 0 auto;
}

.cell {
  position: relative;
  display: flex;
  flex: 0 0 100%;
  justify-content: center;
  align-items: center;
}

.sub-cell {
  display: flex;
  width: 50%;
  justify-content: center;
  align-items: center;
}

.cloud {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 50%;

  &__svg {
    display: block;
    fill: var(--secondary);
    width: 80%;
  }

  .sub-cell {
    width: 50%;
  }
}

.laptop {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 50%;

  &__svg {
    display: block;
    fill: var(--secondary);
    width: 80%;
  }

  &__persona {
    position: absolute;
    bottom: 20%;
    left: 20%;
    font-size: 8vmin;
    transform: translate(-50%, 25%);
  }

  &__content {
    position: absolute;
    left: 50%;
    top: 50%;
    font-size: 10vmin;
    transform: translate(-50%, -60%);

    &__animation {
      opacity: 0;
    }
  }

  .sub-cell & {
    width: 100%;
  }
}

.button {
  color: #fff;
  background-color: var(--green);
  border: solid 1px var(--green-dark);
  border-radius: 3vmin;
  min-width: 25vmin;
  font-size: 4vmin;
  padding: 1vmin 2vmin;
  opacity: 0;
  transform: scale(1);
}

.mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: var(--primary);
  opacity: 0;
}

.popup {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 45vmin;
  padding: 3vmin;
  text-align: center;
  transform: translate(-50%, -50%);
  font-size: 3vmin;
  background-color: var(--red);
  border-radius: 4vmin;
  opacity: 0;
}
View Compiled
const tl = gsap.timeline({ repeat: -1, repeatDelay: 1 });

tl.to(".button.no1", { scale: 1, opacity: 1, delay: 0.5, duration: 0.5 });
tl.to(".button.no1", { scale: 0.9, duration: 0.25 });
tl.to(".button.no1", { scale: 1, duration: 0.25 });
tl.to(".button.no1", { opacity: 0, delay: 0.5, duration: 0.5 });
tl.to(".button.no1", { duration: 0, text: "Push" });
tl.to(".animation.no1", { opacity: 1, delay: -0.5, duration: 0.25 });
tl.to(".animation.no1", { scale: 1.2, duration: 0.2 });
tl.to(".animation.no1", { scale: 1, duration: 0.2 });
tl.to(".animation.no1", { scale: 1.2, duration: 0.2 });
tl.to(".animation.no1", { scale: 1, duration: 0.2 });
tl.to(".animation.no1", { opacity: 0, duration: 0.2 });
tl.to(".animation.no1", { text: "📄", duration: 0, ease: "none" });
tl.to(".button.no1", { scale: 1, opacity: 1, delay: 0.5, duration: 0.5 });
tl.to(".button.no1", { scale: 0.9, duration: 0.25 });
tl.to(".button.no1", { scale: 1, duration: 0.25 });
tl.to(".button.no1", { opacity: 0, delay: 0.5, duration: 0.5 });
tl.to(".animation.no1", { scale: 1, opacity: 1, delay: -0.5, duration: 0.25 });
tl.to(".animation.no1", { x: "250%", y: "-375%", duration: 1.5 });
tl.to(".button.no2", { scale: 1, opacity: 1, duration: 0.25 });
tl.to(".button.no2", { scale: 0.9, duration: 0.25 });
tl.to(".button.no2", { scale: 1, duration: 0.25 });
tl.to(".button.no2", { opacity: 0, delay: 0.5, duration: 0.5 });
tl.to(".button.no2", { duration: 0, text: "Push" });
tl.to(".animation.no2", { opacity: 1, delay: -0.5, duration: 0.25 });
tl.to(".animation.no2", { scale: 1.2, duration: 0.2 });
tl.to(".animation.no2", { scale: 1, duration: 0.2 });
tl.to(".animation.no2", { scale: 1.2, duration: 0.2 });
tl.to(".animation.no2", { scale: 1, duration: 0.2 });
tl.to(".animation.no2", { opacity: 0, duration: 0.2 });
tl.to(".animation.no2", { text: "📄", duration: 0 });
tl.to(".button.no2", { scale: 1, opacity: 1, delay: 0.5, duration: 0.5 });
tl.to(".button.no2", { scale: 0.9, duration: 0.25 });
tl.to(".button.no2", { scale: 1, duration: 0.25 });
tl.to(".button.no2", {
  x: "-25%",
  rotateZ: "-5deg",
  delay: 0.25,
  duration: 0.2
});
tl.to(".button.no2", { x: "20%", rotateZ: "3deg", duration: 0.2 });
tl.to(".button.no2", { x: "-15%", rotateZ: "-3deg", duration: 0.2 });
tl.to(".button.no2", { x: "10%", rotateZ: "2deg", duration: 0.2 });
tl.to(".button.no2", { x: "-5%", rotateZ: "-1deg", duration: 0.2 });
tl.to(".button.no2", { x: "0", rotateZ: "0deg", duration: 0.2 });
tl.to(".animation.no2", { opacity: 1, delay: -1.2, duration: 0.25 });
tl.to(".button.no2", { opacity: 0, delay: 0.5, duration: 0.2 });
tl.to(".button.no2", { duration: 0, text: "Pull" });
tl.to(".mask", { opacity: 0.5, delay: 0.25, duration: 0.5 });
tl.to(".popup", { opacity: 1, scale: 1, delay: -0.25, duration: 0.5 });
tl.to(".popup", { opacity: 0, scale: 0.5, delay: 4, duration: 0.5 });
tl.to(".mask", { opacity: 0, delay: -0.5, duration: 0.5 });
tl.to(".button.no2", { scale: 1, opacity: 1, delay: 0.5, duration: 0.5 });
tl.to(".button.no2", { scale: 0.9, duration: 0.25 });
tl.to(".button.no2", { scale: 1, duration: 0.25 });
tl.to(".animation.no1", { x: "495%", y: "-5%", duration: 1.5 });
tl.to(".button.no2", { opacity: 0, delay: -0.5, duration: 0.2 });
tl.to(".button.no2", { duration: 0, text: "Push" });
tl.to(".button.no2", { scale: 1, opacity: 1, delay: 0.5, duration: 0.5 });
tl.to(".button.no2", { scale: 0.9, duration: 0.25 });
tl.to(".button.no2", { scale: 1, duration: 0.25 });
tl.to(".button.no2", { opacity: 0, delay: 0.25, duration: 0.2 });
tl.to(".animation.no1", { x: "245%", y: "-380%", duration: 1.5 });
tl.to(".animation.no2", { x: "-250%", y: "-375%", delay: -1.5, duration: 1.5 });
tl.to(".animation.no1", { opacity: 0, delay: 1, duration: 0.25 });
tl.to(".animation.no2", { opacity: 0, delay: -0.25, duration: 0.25 });
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.0/gsap.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.2/TextPlugin.min.js