<!-- 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
This Pen doesn't use any external CSS resources.