Sign-In Card
A sign-in card that assembles downward, with fields that answer to focus.
Why it is timed this way
The reasoning
The focus states are the useful part. They compile to a transition on a :focus rule, so keyboard users get the same ring as mouse users — which is the whole point, and the thing most hand-written form CSS forgets.
5 elements move, the first at 0ms and the last starting at 260ms — the whole scene settles by 1160ms. Every bar below is one element's animation window.
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.
.sign-in {
transform: translate3d(0px, 0px, 0);
width: 960px;
height: 480px;
transform-origin: 480px 185px;
}
.form-card {
transform: translate3d(0px, 0px, 0);
box-shadow: 0px 16px 44px 0px #00000066;
width: 288px;
height: 250px;
background: #171a24;
border-radius: 18px;
transform-origin: 180px 161px;
}
.form-title {
transform: translate3d(0px, 0px, 0);
width: 288px;
height: 32px;
background: #00000000;
color: #eceef4;
font-size: 24px;
font-weight: 700;
animation: form-title-anim 1160ms linear 0ms infinite both;
will-change: transform, opacity;
}
@keyframes form-title-anim {
0% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
animation-timing-function: ease-out;
}
60.34% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
100% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
}
.form-sub {
transform: translate3d(0px, 0px, 0);
width: 288px;
height: 20px;
background: #00000000;
color: #98a1b5;
font-size: 14px;
font-weight: 500;
animation: form-sub-anim 1160ms linear 0ms infinite both;
will-change: transform, opacity;
}
@keyframes form-sub-anim {
0% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
}
5.6% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
animation-timing-function: ease-out;
}
65.95% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
100% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
}
.email-field {
transform: translate3d(0px, 0px, 0);
width: 288px;
height: 46px;
background: #1f2331;
border-radius: 10px;
transition: box-shadow 200ms ease-out, background 200ms ease-out;
animation: email-field-anim 1160ms linear 0ms infinite both;
will-change: transform, opacity;
}
.email-field:focus-visible {
box-shadow: 0px 0px 0px 3px #6366f166;
background: #272c3a;
transition: box-shadow 150ms ease-out, background 150ms ease-out;
}
@keyframes email-field-anim {
0% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
}
11.21% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
animation-timing-function: ease-out;
}
71.55% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
100% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
}
.password-field {
transform: translate3d(0px, 0px, 0);
width: 288px;
height: 46px;
background: #1f2331;
border-radius: 10px;
transition: box-shadow 200ms ease-out, background 200ms ease-out;
animation: password-field-anim 1160ms linear 0ms infinite both;
will-change: transform, opacity;
}
.password-field:focus-visible {
box-shadow: 0px 0px 0px 3px #6366f166;
background: #272c3a;
transition: box-shadow 150ms ease-out, background 150ms ease-out;
}
@keyframes password-field-anim {
0% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
}
16.81% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
animation-timing-function: ease-out;
}
77.16% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
100% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
}
.sign-in-2 {
transform: translate3d(0px, 0px, 0);
width: 288px;
height: 42px;
background: #6366f1;
border-radius: 10px;
color: #ffffff;
font-size: 14px;
font-weight: 600;
transition: transform 200ms ease-out, background 200ms ease-out;
animation: sign-in-2-anim 1160ms linear 0ms infinite both;
will-change: transform, opacity;
}
.sign-in-2:hover {
transform: translate3d(36px, 242px, 0);
background: #8b7bff;
transition: transform 180ms ease-out, background 180ms ease-out;
}
@keyframes sign-in-2-anim {
0% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
}
22.41% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
animation-timing-function: ease-out;
}
82.76% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
100% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.form-title,
.form-sub,
.email-field,
.password-field,
.sign-in-2 {
animation: none;
transition: none;
}
}More scenes
Onboarding Screen
A phone frame that pops in, then fills with list rows.
Launch Hero
A product hero whose copy, buttons and panel arrive in sequence.
Three-Plan Pricing
Three plans that pop in, with the featured column raised and hover lifts on every card.