<section class="card">
  <div class="gift-container">
    <div class="letters">
      <h1 class="letter F">F</h1>
      <h1 class="letter l">l</h1>
      <h1 class="letter i">i</h1>
      <h1 class="letter p">p</h1>
      <div class="for">for</div>
      <div class="gsap">GSAP</div>
    </div>
    <div class="gift">
      <div class="plane">
        <div class="box bottom">
          <div class="box__side"></div>
          <div class="box__side"></div>
          <div class="box__side"></div>
          <div class="box__side"></div>
          <div class="box__side"></div>
          <div class="box__side"></div>
        </div>
        <div class="box top">
          <div class="box__side"></div>
          <div class="box__side"></div>
          <div class="box__side"></div>
          <div class="box__side"></div>
          <div class="box__side"></div>
          <div class="box__side"></div>
        </div>
        <div class="confetti-cont"></div>
      </div>
    </div>

  </div>
  <div class="content content--closed">
    <h1 class="title">Merry Christmas!</h1>
    <p class="intro">You've all been very good this year. So here's a gift for you from all of us at GreenSock...</p>
  </div>
  <div class="content content--open">
    <h2>Flip Plugin is no longer members-only!</h2>
    <p>Flippin' amazing! One of GreenSock's most useful plugins is now available to <strong>everyone</strong>, not just <a href="https://greensock.com/club/">members</a>. Enjoy! <a href="https://greensock.com/flip">Learn more</a>. </p>
    <p></p>
  </div>
</section>

<a href="https://greensock.com/"><img src="https://assets.codepen.io/16327/greensock-logo-icon.svg" class="logo" /></a>
* {
  box-sizing: border-box;
}

body {
  font-family: "Signika Negative", sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  padding: 0;
  margin: 0;
  background-color: #1d1e22;
  color: #23272a;
  font-size: var(--step-0);
  line-height: 1.34;
  overflow: hidden;
  --one: hsl(192deg 40% 43%);
  --two: hsl(268deg 45% 46%);
  --three:hsl(268deg 45% 42%);
  --four: hsl(192deg 40% 43%);
  --five: hsl(356deg 80% 25%);
}

h1,
h2 {
  margin: 0;
}

p {
  margin-top: 0.75em;
  color: #4c4c52;
}

a {
  color: #61AC27;
  font-weight: bold;
}

h1 {
  font-size: var(--step-2);
}

h2 {
  font-size: var(--step-1);
}

.content--open {
  display: none;
  max-width: 750px;
  margin: 0 auto;
}

.open .content--open {
  display: block;
}

.open .content--closed {
  display: none;
  visibility: hidden;
}

.card {
  position: relative;
  background: #fff;
  padding: var(--space-s-l);
  padding-top: 80px;
  width: 90vw;
  max-width: 580px;
  border-radius: 16px;
  margin-top: 120px;
  cursor: pointer;
}

.flipping.card {
  max-width: unset;
}

.open .card {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  border-radius: 0;
  width: 100%;
  max-width: 100%;
  height: 40vh;
  padding: var(--space-s-xl);
  padding-top: 90px;
}

@media only screen and (max-width: 600px) {
  .open .card {
    height: 65vh;
    padding-top: 75px;
 }
  
  .card {
    padding-top: 65px
  }
}

.gift-container {
  position: absolute;
  bottom: calc(100% - 120px);
  z-index: 3;
  opacity: 0;
  left: calc(50% - 125px);
}

.open .gift-container {
  left: 8rem;
}

.bottom {
  --width: 20;
  --height: 15;
  --depth: 20; 
}
.top {
  --width: 22;
  --height: 5;
  --depth: 22;
}

/* mad props to Jhey for this article
https://css-tricks.com/css-in-3d-learning-to-think-in-cubes-instead-of-boxes/ */
.plane {
  height: 250px;
  width: 250px;
  transform-style: preserve-3d;
  transform: rotateX(-15deg) rotateY(314deg) rotateX(90deg) translate3d(0, 0, 0);
  --size: 8px;
}

@media only screen and (max-width: 600px) {
  .plane {
  --size: 5px;
  }
  
  .gift-container {
  bottom: calc(100% - 150px);
  left: calc(50% - 125px);
}

.open .gift-container {
  left: -2rem;
}

  
}

.box > div {
  background: linear-gradient(
    to right,
    var(--three),
    var(--three) 42%,
    var(--one) 42%,
    var(--one) 58%,
    var(--three) 58%
  );
}

.top {
  transform: translate3d(0, 0, calc(8 * var(--size)));
}

.top > div:nth-of-type(5) {
  background: linear-gradient(
      to bottom,
      transparent,
      transparent 42%,
      var(--one) 42%,
      var(--one) 58%,
      transparent 58%
    ),
    linear-gradient(
      to right,
      var(--two),
      var(--two) 42%,
      var(--one) 42%,
      var(--one) 58%,
      var(--two) 58%
    );
}
.bottom > div:nth-of-type(5) {
  background: transparent;
}
.bottom > div:nth-of-type(2),
.bottom > div:nth-of-type(4) {
  background: #422e61;
  border: solid 0.2px #341d1d;
  z-index: -200,
}
.box {
  height: calc(var(--depth) * var(--size));
  width: calc(var(--width) * var(--size));
  transform-style: preserve-3d;
  position: absolute;
  font-size: 1rem;
}
.box > div:nth-of-type(1) {
  height: calc(var(--height) * var(--size));
  width: 100%;
  transform-origin: 50% 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotateX(-90deg) translate3d(0, 0, calc((var(--depth) / 2) * var(--size)));
  background: linear-gradient(
    to right,
    var(--three),
    var(--three) 42%,
    var(--one) 42%,
    var(--one) 58%,
    var(--three) 58%
  );
}
.box > div:nth-of-type(2) {
  height: calc(var(--height) * var(--size));
  width: 100%;
  transform-origin: 50% 50%;
  transform: translate(-50%, -50%) rotateX(-90deg) rotateY(180deg) translate3d(0, 0, calc((var(--depth) / 2) * var(--size)));
  position: absolute;
  top: 50%;
  left: 50%;
}
.box > div:nth-of-type(3) {
  height: calc(var(--height) * var(--size));
  width: calc(var(--depth) * var(--size));
  transform: translate(-50%, -50%) rotateX(-90deg) rotateY(90deg) translate3d(0, 0, calc((var(--width) / 2) * var(--size)));
  position: absolute;
  top: 50%;
  left: 50%;
}
.box > div:nth-of-type(4) {
  height: calc(var(--height) * var(--size));
  width: calc(var(--depth) * var(--size));
  transform: translate(-50%, -50%) rotateX(-90deg) rotateY(-90deg) translate3d(0, 0, calc((var(--width) / 2) * var(--size)));
  position: absolute;
  top: 50%;
  left: 50%;
}
.box > div:nth-of-type(5) {
  height: calc(var(--depth) * var(--size));
  width: calc(var(--width) * var(--size));
  transform: translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * var(--size)));
  position: absolute;
  top: 50%;
  left: 50%;
}
.box > div:nth-of-type(6) {
  height: calc(var(--depth) * var(--size));
  width: calc(var(--width) * var(--size));
  transform: translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * var(--size) * -1)) rotateX(180deg);
  position: absolute;
  top: 50%;
  left: 50%;
}

.top > div:nth-of-type(6) {
  background: transparent
}

.confetti {
  position: absolute;
  width: 20px;
  height: 20px;
  left: 48%;
  top: 40%;
  z-index: 1
}

.confetti-cont {
  width: 100px;
  height: 100px;
  transform: rotate(312deg) rotateY(181deg) rotateX(72deg) translate3d(0, 0, 4px);
}

.letters {
  display: flex;
  flex-direction: row;
  align-items: center;
  left: 0;
  bottom: 50%;
}

.letter {
  text-align: center;
  color: black;
  font-size: 15vmin;
  font-weight: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2px 6px;
}

.F {
  background: #428899;
}
.l {
  background: #386ab5;
}
.i {
  background: #683b9c;
}
.p {
  background: #424d9f;
}

.for, .gsap {
  display: none;
  color: white;
  font-size: 5vmin;
}
.for {
  padding: 2px 1.6vmin;
  font-weight: 300;
}
.gsap {
  padding: 2px 0;
  font-weight: 600;
}

.open {
  align-items: flex-start;
}

.open .for, .open .gsap {
  display: block;
  z-index: -4
}

.letters {
  z-index: -3;
}

.gift-container > .letters {
  position: absolute;
  transform: scale(0.2);
  
  .letter {
    opacity: 0;
  }
}

.open > .letters {
  margin-top: 5vh;
  height: 40vh;
  margin-left: 3rem;
  opacity: 1;
  transform: scale(1)
}

.logo {
  position: fixed;
  width: 60px;
  bottom: 20px;
  right: 30px;
  z-index: 9999;
}
View Compiled
let confettis = document.querySelector(".confetti-cont");
let container = document.querySelector(".gift-container");

gsap.set(container, { opacity: 1 });

let explosion = gsap.timeline({ paused: true });

// create 100 confetti elements
for (let i = 0; i < 100; i++) {
  let c = document.createElement("div");
  c.innerHTML = gsap.utils.random(["💚", "✨", "⭐", "💙", "💜"]);
  c.setAttribute("class", "confetti");
  confettis.appendChild(c);

  explosion.to(
    c,
    {
      keyframes: [
        {
          opacity: 1,
          duration: 0.01
        },
        {
          duration: 3,
          physics2D: {
            velocity: "random(200, 650)",
            angle: "random(250, 290)",
            gravity: 300
          }
        },
        {
          opacity: 0,
          duration: 0.3,
          delay: -2
        }
      ]
    },
    Math.random() * 2
  );
}

let tl = gsap.timeline({
  paused: true
});
tl.to(".top", {
  z: 110,
  duration: 0.2,
  ease: "back.out"
})
  .to(
    ".top",
    {
      rotate: 360,
      transformOrigin: "center center",
      duration: 1,
      ease: "back.out"
    },
    "-=0.2"
  )
  .to(".top", {
    z: 80,
    scale: 0.9,
    rotateY: -240,
    x: -15,
    duration: 1.2,
    transformOrigin: "center left",
    ease: "sine.inOut",
    onStart: () => {
      explosion.play(0);
    }
  })
  .reverse();

let card = document.querySelector(".card");
let letters = document.querySelector(".letters");

let isOpen;

card.addEventListener("click", () => {
  isOpen = !isOpen;

  // Get the initial state
  const cardState = Flip.getState(
    ".card, .gift-container, .content--open, .content--closed",
    { props: "borderRadius,padding" }
  );
  
  const letterState = Flip.getState(".letter, .for, .gsap", {
    props: "opacity"
  });
  
  document.body.classList.toggle("open");


  if (isOpen) {
    document.body.appendChild(letters);
  } else {
    container.appendChild(letters);
    explosion.progress(0).pause();
  }

  Flip.from(cardState, {
    absolute: '.card',
    nested: true,
    duration: 0.75,
    ease: "sine.inOut",
    toggleClass: 'flipping',
    onStart: () => {
      isOpen ? tl.timeScale(1).play() : tl.timeScale(1.5).reverse()
      ;
    },
    onEnter: (elements) => {
      gsap.fromTo(
        elements,
        { autoAlpha: 0 },
        { autoAlpha: 1, duration: 0.5, delay: 0.75, overwrite: true }
      );
    },
    onLeave: (elements) => {
      gsap.fromTo(
        elements,
        { autoAlpha: 1 },
        { autoAlpha: 0, duration: 0.01, overwrite: true }
      );
    }
  });

  Flip.from(letterState, {
    duration: 1,
    delay: isOpen ? 1 : 0,
    ease: "power1.inOut",
    scale: true,
    stagger: 0.2,
    nested: true,
    spin: isOpen ? -1 : 1,
    onEnter: (elements) => {
      gsap.fromTo(
        elements,
        { autoAlpha: 0, x: -40 },
        {
          autoAlpha: 1,
          x: 0,
          duration: 1,
          delay: isOpen ? 2.75 : 0,
          overwrite: true,
          stagger: 0.2
        }
      );
    }
  });
});

External CSS

  1. https://codepen.io/GreenSock/pen/abLNErZ

External JavaScript

  1. https://unpkg.co/gsap@3/dist/gsap.min.js
  2. https://assets.codepen.io/16327/Flip.min.js
  3. https://assets.codepen.io/16327/Physics2DPlugin3.min.js