Animated S-Wave Login & Sign Up Form
A modern animated authentication form with a glowing SVG S-wave panel, smooth 180-degree transition, login and sign-up states.
Login
Don’t have an account?
Sign Up
Already have an account?
WELCOME
BACK!
Good to see you again. Login to continue your journey.
HELLO
THERE!
Create your account and start something amazing.
<div class="cr-auth-switcher">
<div class="cr-auth-shell">
<div class="cr-auth-form cr-login-form">
<div class="cr-form-inner">
<h2>Login</h2>
<div class="cr-mini-line"></div>
<label>Username</label>
<input type="text" placeholder="Enter username">
<label>Password</label>
<input type="password" placeholder="Enter password">
<div class="cr-form-options">
<label class="cr-check">
<input type="checkbox">
<span>Remember me</span>
</label>
<button class="cr-text-btn">
Forgot?
</button>
</div>
<button class="cr-auth-submit">
Login
</button>
<p>
Don’t have an account?
<button class="cr-switch-btn" data-target="signup">
Sign Up
</button>
</p>
</div>
</div>
<div class="cr-auth-form cr-signup-form">
<div class="cr-form-inner">
<h2>Sign Up</h2>
<div class="cr-mini-line"></div>
<label>Username</label>
<input type="text" placeholder="Choose username">
<label>Email</label>
<input type="email" placeholder="Enter email">
<label>Password</label>
<input type="password" placeholder="Create password">
<button class="cr-auth-submit">
Sign Up
</button>
<p>
Already have an account?
<button class="cr-switch-btn" data-target="login">
Login
</button>
</p>
</div>
</div>
<div class="cr-wave-stage">
<svg
class="cr-wave-svg"
viewBox="0 0 460 470"
preserveAspectRatio="none"
aria-hidden="true"
>
<defs>
<linearGradient id="crWaveBg" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#111a30"/>
<stop offset="55%" stop-color="#07101e"/>
<stop offset="100%" stop-color="#02050c"/>
</linearGradient>
<linearGradient id="crWaveEdge" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#22d3ee"/>
<stop offset="45%" stop-color="#6366f1"/>
<stop offset="100%" stop-color="#8b5cf6"/>
</linearGradient>
<filter id="crWaveGlow" x="-60%" y="-30%" width="220%" height="160%">
<feGaussianBlur stdDeviation="7" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<path
class="cr-wave-shape"
d="
M 150 0
C 200 45, 210 90, 168 126
C 120 168, 115 210, 158 247
C 205 287, 205 335, 158 375
C 125 403, 125 438, 155 470
L 460 470
L 460 0
Z
"
fill="url(#crWaveBg)"
/>
<path
class="cr-wave-edge"
d="
M 150 0
C 200 45, 210 90, 168 126
C 120 168, 115 210, 158 247
C 205 287, 205 335, 158 375
C 125 403, 125 438, 155 470
"
fill="none"
stroke="url(#crWaveEdge)"
stroke-width="5"
filter="url(#crWaveGlow)"
/>
</svg>
<div class="cr-panel-content cr-panel-login">
<h2>
WELCOME<br>
BACK!
</h2>
<p>
Good to see you again.
Login to continue your journey.
</p>
</div>
<div class="cr-panel-content cr-panel-signup">
<h2>
HELLO<br>
THERE!
</h2>
<p>
Create your account and start
something amazing.
</p>
</div>
</div>
</div>
</div>
*{
box-sizing:border-box;
}
.cr-auth-switcher{
width:100%;
min-height:600px;
display:flex;
align-items:center;
justify-content:center;
padding:40px 24px;
background:
radial-gradient(circle at 50% 50%,rgba(99,102,241,.10),transparent 34%),
#050914;
font-family:Inter,Arial,sans-serif;
}
.cr-auth-shell{
position:relative;
width:min(820px,100%);
height:470px;
overflow:hidden;
background:#f8fafc;
border:1px solid rgba(148,163,184,.30);
border-radius:24px;
box-shadow:
0 30px 80px rgba(0,0,0,.55),
0 0 35px rgba(99,102,241,.10);
}
.cr-auth-form{
position:absolute;
top:0;
width:50%;
height:100%;
display:flex;
align-items:center;
justify-content:center;
padding:42px 48px;
color:#111827;
transition:
opacity .42s ease,
transform .78s cubic-bezier(.77,0,.18,1);
}
.cr-login-form{
left:0;
opacity:1;
transform:translateX(0);
pointer-events:auto;
}
.cr-signup-form{
right:0;
opacity:0;
transform:translateX(34px);
pointer-events:none;
}
.cr-auth-shell.signup-active .cr-login-form{
opacity:0;
transform:translateX(-34px);
pointer-events:none;
}
.cr-auth-shell.signup-active .cr-signup-form{
opacity:1;
transform:translateX(0);
pointer-events:auto;
}
.cr-form-inner{
width:100%;
max-width:285px;
}
.cr-form-inner h2{
margin:0;
color:#111827;
font-size:32px;
font-weight:800;
line-height:1.1;
}
.cr-mini-line{
width:40px;
height:3px;
margin:10px 0 27px;
border-radius:20px;
background:linear-gradient(90deg,#22d3ee,#6366f1,#8b5cf6);
box-shadow:0 0 12px rgba(99,102,241,.35);
}
.cr-form-inner > label{
display:block;
margin:16px 0 6px;
color:#475569;
font-size:12px;
font-weight:700;
}
.cr-form-inner input[type="text"],
.cr-form-inner input[type="email"],
.cr-form-inner input[type="password"]{
width:100%;
height:42px;
padding:0 4px;
border:0;
border-bottom:1px solid #94a3b8;
border-radius:0;
outline:none;
background:transparent;
color:#111827;
font-family:inherit;
font-size:14px;
}
.cr-form-options{
display:flex;
align-items:center;
justify-content:space-between;
margin-top:14px;
}
.cr-check{
display:flex;
align-items:center;
gap:6px;
margin:0 !important;
color:#64748b;
font-size:11px;
}
.cr-check input{
width:13px;
height:13px;
margin:0;
accent-color:#6366f1;
}
.cr-text-btn{
padding:0;
border:0;
background:transparent !important;
color:#64748b;
font-family:inherit;
font-size:11px;
cursor:pointer;
}
.cr-auth-submit{
width:100%;
margin-top:24px;
padding:12px 20px;
border:0;
border-radius:30px;
background:linear-gradient(90deg,#0f172a,#111827);
color:#ffffff;
font-family:inherit;
font-size:13px;
font-weight:800;
cursor:pointer;
}
.cr-form-inner p{
margin:16px 0 0;
color:#64748b;
font-size:11px;
text-align:center;
}
.cr-switch-btn{
padding:0;
border:0;
background:transparent !important;
color:#4f46e5;
font-family:inherit;
font-size:11px;
font-weight:800;
cursor:pointer;
}
.cr-wave-stage{
position:absolute;
z-index:5;
top:0;
right:0;
width:460px;
height:470px;
transform-origin:center center;
transition:
right .95s cubic-bezier(.77,0,.18,1),
transform .95s cubic-bezier(.77,0,.18,1);
}
.cr-wave-svg{
position:absolute;
inset:0;
width:100%;
height:100%;
overflow:visible;
display:block;
pointer-events:none;
}
.cr-wave-shape{
filter:drop-shadow(-12px 0 22px rgba(0,0,0,.18));
}
.cr-wave-edge{
opacity:.95;
}
.cr-wave-stage::before{
content:"";
position:absolute;
z-index:2;
right:-40px;
top:-55px;
width:190px;
height:190px;
border-radius:50%;
background:
radial-gradient(
circle,
rgba(124,58,237,.27),
rgba(99,102,241,.08) 48%,
transparent 72%
);
pointer-events:none;
}
.cr-panel-content{
position:absolute;
z-index:10;
top:50%;
width:220px;
color:#ffffff;
transition:opacity .25s ease .32s;
}
.cr-panel-content h2{
margin:0 0 14px;
color:#ffffff;
font-size:31px;
font-weight:900;
line-height:1.05;
}
.cr-panel-content p{
margin:0;
color:#b7c4d8;
font-size:13px;
line-height:1.65;
}
.cr-panel-login{
right:42px;
transform:translateY(-50%);
opacity:1;
}
.cr-panel-signup{
left:150px;
width:190px;
transform:
translateY(-50%)
rotate(180deg);
opacity:0;
}
.cr-auth-shell.signup-active .cr-wave-stage{
right:360px;
transform:rotate(180deg);
}
.cr-auth-shell.signup-active .cr-panel-login{
opacity:0;
}
.cr-auth-shell.signup-active .cr-panel-signup{
opacity:1;
}
@media(max-width:700px){
.cr-auth-switcher{
min-height:580px;
padding:25px 14px;
}
.cr-auth-shell{
height:470px;
}
.cr-auth-form{
padding:30px 20px;
}
}
document.addEventListener(
'DOMContentLoaded',
function() {
var shell =
document.querySelector('.cr-auth-shell');
if (!shell) {
return;
}
var switchButtons =
shell.querySelectorAll('.cr-switch-btn');
switchButtons.forEach(
function(button) {
button.addEventListener(
'click',
function() {
var target =
button.getAttribute('data-target');
if (target === 'signup') {
shell.classList.add(
'signup-active'
);
}
if (target === 'login') {
shell.classList.remove(
'signup-active'
);
}
}
);
}
);
}
);
How This Animated S-Wave Login & Sign Up Form Works
The Animated S-Wave Login & Sign Up Form combines two authentication forms with a moving SVG panel. The main .cr-auth-shell is an 820px-wide container with a fixed height of 470px, rounded 24px corners, and hidden overflow. Both the login and sign-up interfaces are positioned inside this same container, so switching modes does not require loading a separate page.
The login form starts on the left side and is visible by default. The sign-up form is positioned on the right with opacity: 0, a translateX(34px) offset, and disabled pointer events. Each form occupies 50% of the shell. When the active state changes, CSS adjusts opacity, horizontal translation, and pointer events to determine which form can be seen and used.
The central visual feature is .cr-wave-stage, a 460 × 470px panel containing an SVG. Its main path creates the curved S-like boundary with several cubic Bézier curve commands. The dark surface uses an SVG linear gradient running from #111a30 through #07101e to #02050c. A second path follows the same curved edge with a 5px cyan, indigo, and violet gradient stroke. An SVG Gaussian blur filter adds the glow around this line.
When the user clicks Sign Up, JavaScript reads the button’s data-target attribute and adds the signup-active class to .cr-auth-shell. CSS then moves the wave stage by setting right: 360px while rotating it 180deg. The transition lasts .95s and uses cubic-bezier(.77,0,.18,1). The login and sign-up forms also transition between their visible and hidden states.
The panel contains separate welcome messages for each mode. Because the entire wave rotates, the sign-up panel content includes its own rotate(180deg) transform so its text appears upright after the switch. Opacity transitions hide the old message and reveal the appropriate one.
Clicking Login inside the sign-up form reverses the process. JavaScript removes signup-active, returning the wave, forms, and panel text to their original states. For more information about the class methods behind this state change, see the MDN classList documentation.
Customizing the Animated S-Wave Login & Sign Up Form
Most of the appearance can be adjusted directly in the CSS and SVG without changing the switching logic.
- Change the
820pxmaximum shell width,470pxheight, or24pxborder radius to alter the overall form proportions. - Edit the cyan
#22d3ee, indigo#6366f1, and violet#8b5cf6values to create a different accent palette. - Modify the SVG
crWaveBggradient stops to change the dark wave background. - Adjust the SVG path coordinates if you want to change the actual S-shaped curve.
- Change the
.95swave transition or.78sform transition to make switching faster or slower. - Adjust
right: 360pxon the active wave stage to control how far the panel travels. - Edit the 32px form headings and 31px panel headings to change typography scale.
- Update the
@media(max-width:700px)rules to fine-tune padding on smaller screens.
Where to Use This Animated S-Wave Form
This component fits interfaces where login and registration need to remain together while still having clearly separated states.
- Account authentication pages for web applications
- SaaS login and registration screens
- Member portals and customer dashboards
- Community or membership websites
- Portfolio projects demonstrating SVG and CSS animation
- Landing pages that need combined sign-in and account creation
For another authentication layout with a different reveal interaction, the Interactive Lamp Login Reveal Form is a related CodeRipple component worth exploring. In a production project, the inputs and buttons would still need to be connected to your own validation, authentication, password recovery, and form-submission logic.
Frequently Asked Questions
Does this form use JavaScript?
Yes. JavaScript waits for DOMContentLoaded, finds .cr-auth-shell, attaches click listeners to both .cr-switch-btn elements, and adds or removes the signup-active class according to each button’s data-target value.
How is the S-wave shape created?
The shape is an inline SVG containing two paths. One path provides the dark filled panel, while the second traces its curved boundary with a 5px gradient stroke and Gaussian-blur glow. The curves themselves are defined with SVG cubic Bézier commands.
Does the component actually submit login or sign-up information?
No. The current JavaScript only controls switching between the two interface states. It does not send credentials, validate fields, create accounts, or authenticate users with a server.
How does the form behave on smaller screens?
A media query activates below 700px. It reduces the outer wrapper padding from 40px 24px to 25px 14px and changes form padding to 30px 20px. The shell remains 470px high.
The Animated S-Wave Login & Sign Up Form keeps both authentication views inside one interface and uses a single state class to coordinate the forms, SVG movement, rotation, and panel content.
