App UI

Onboarding Screen

A phone frame that pops in, then fills with list rows.

Your day
10
Elements
7
Groups
0
Hover states
1545ms
Duration

Why it is timed this way

The reasoning

Two sequences rather than one: the frame establishes itself, and only then does content arrive inside it. Running both at once makes the rows look like they are falling through the phone rather than into it.

10 elements move, the first at 0ms and the last starting at 645ms — the whole scene settles by 1545ms. Every bar below is one element's animation window.

Notch
Screen Title
Row 1 Dot
Row 1 Bar
Row 2 Dot
Row 2 Bar
Row 3 Dot
Row 3 Bar
Row 4 Dot
Row 4 Bar
0ms773ms1545ms

The code

Everything the scene needs, in whichever format you ship. Entrances compile to@keyframesand hover states totransition, with a reduced-motion guard on both.

371 lines
.onboarding {
  transform: translate3d(0px, 0px, 0);
  width: 960px;
  height: 480px;
  transform-origin: 480px 120px;
}

.phone {
  transform: translate3d(0px, 0px, 0);
  box-shadow: 0px 20px 50px 0px #00000073;
  width: 200px;
  height: 192px;
  background: #171a24;
  border-radius: 30px;
  transform-origin: 120px 116px;
}

.rows {
  transform: translate3d(0px, 0px, 0);
  height: 116px;
  transform-origin: 16px 58px;
}

.row-1 {
  transform: translate3d(0px, 0px, 0);
  height: 20px;
  background: #1f2331;
  border-radius: 14px;
  transform-origin: 30px 24px;
}

.row-2 {
  transform: translate3d(0px, 0px, 0);
  height: 20px;
  background: #1f2331;
  border-radius: 14px;
  transform-origin: 30px 24px;
}

.row-3 {
  transform: translate3d(0px, 0px, 0);
  height: 20px;
  background: #1f2331;
  border-radius: 14px;
  transform-origin: 30px 24px;
}

.row-4 {
  transform: translate3d(0px, 0px, 0);
  height: 20px;
  background: #1f2331;
  border-radius: 14px;
  transform-origin: 30px 24px;
}

.notch {
  transform: translate3d(0px, 0px, 0);
  width: 64px;
  height: 10px;
  background: #0e1016;
  border-radius: 999px;
  animation: notch-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes notch-anim {
  0% {
    transform: translate3d(0px, 0px, 0) scale(0, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  12.94% {
    transform: translate3d(0px, 0px, 0) scale(1.029, 1.029);
    opacity: 1;
  }
  32.36% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.screen-title {
  transform: translate3d(0px, 0px, 0);
  height: 30px;
  background: #00000000;
  color: #eceef4;
  font-size: 22px;
  font-weight: 700;
  animation: screen-title-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes screen-title-anim {
  0% {
    transform: translate3d(0px, 0px, 0) scale(0, 0);
    opacity: 0;
  }
  3.88% {
    transform: translate3d(0px, 0px, 0) scale(0, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  16.83% {
    transform: translate3d(0px, 0px, 0) scale(1.029, 1.029);
    opacity: 1;
  }
  36.25% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.row-1-dot {
  transform: translate3d(0px, 0px, 0);
  width: 20px;
  height: 20px;
  background: #6366f1;
  border-radius: 999px;
  animation: row-1-dot-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes row-1-dot-anim {
  0% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
  }
  16.83% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  62.14% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.row-1-bar {
  transform: translate3d(0px, 0px, 0);
  height: 10px;
  background: #272c3a;
  border-radius: 999px;
  animation: row-1-bar-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes row-1-bar-anim {
  0% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
  }
  20.39% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  65.7% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.row-2-dot {
  transform: translate3d(0px, 0px, 0);
  width: 20px;
  height: 20px;
  background: #22d3ee;
  border-radius: 999px;
  animation: row-2-dot-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes row-2-dot-anim {
  0% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
  }
  23.95% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  69.26% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.row-2-bar {
  transform: translate3d(0px, 0px, 0);
  height: 10px;
  background: #272c3a;
  border-radius: 999px;
  animation: row-2-bar-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes row-2-bar-anim {
  0% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
  }
  27.51% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  72.82% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.row-3-dot {
  transform: translate3d(0px, 0px, 0);
  width: 20px;
  height: 20px;
  background: #6366f1;
  border-radius: 999px;
  animation: row-3-dot-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes row-3-dot-anim {
  0% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
  }
  31.07% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  76.38% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.row-3-bar {
  transform: translate3d(0px, 0px, 0);
  height: 10px;
  background: #272c3a;
  border-radius: 999px;
  animation: row-3-bar-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes row-3-bar-anim {
  0% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
  }
  34.63% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  79.94% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.row-4-dot {
  transform: translate3d(0px, 0px, 0);
  width: 20px;
  height: 20px;
  background: #22d3ee;
  border-radius: 999px;
  animation: row-4-dot-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes row-4-dot-anim {
  0% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
  }
  38.19% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  83.5% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.row-4-bar {
  transform: translate3d(0px, 0px, 0);
  height: 10px;
  background: #272c3a;
  border-radius: 999px;
  animation: row-4-bar-anim 1545ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes row-4-bar-anim {
  0% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
  }
  41.75% {
    transform: translate3d(-64px, 0px, 0);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  87.06% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .notch,
  .screen-title,
  .row-1-dot,
  .row-1-bar,
  .row-2-dot,
  .row-2-bar,
  .row-3-dot,
  .row-3-bar,
  .row-4-dot,
  .row-4-bar {
    animation: none;
    transition: none;
  }
}

More scenes

Sign-In Card

A sign-in card that assembles downward, with fields that answer to focus.

Now in beta
Ship motion
that feels right.
Design it, tune it, export the CSS.

Launch Hero

A product hero whose copy, buttons and panel arrive in sequence.

Starter
$0
Pro
$12
Team
$40

Three-Plan Pricing

Three plans that pop in, with the featured column raised and hover lifts on every card.