Bootstrap 5 Neumorphic Signup / Login Form
A soft-UI sign up and log in board with a name field that appears only when signing up, plus a second panel with social sign-in, labelled quick tools and search. Inputs and buttons keep a visible edge so they stay readable in light and dark.
<section class="wdw-stage">
<div class="container" style="max-width:960px">
<div class="text-center mb-4"><span class="wdw-eyebrow">Soft UI</span><h2 class="wdw-heading mt-1 mb-0">Soft sign up / log in</h2></div>
<div class="wdw-neo-board p-4 p-md-5">
<div class="row g-4 g-md-5 align-items-start">
<div class="col-md-6">
<form novalidate id="neoForm">
<div class="wdw-neo-tabs d-flex gap-3 mb-4" role="group" aria-label="Mode">
<button type="button" class="btn wdw-neo-btn flex-fill active" data-mode="up" aria-pressed="true">Sign up</button>
<button type="button" class="btn wdw-neo-btn flex-fill" data-mode="in" aria-pressed="false">Log in</button>
</div>
<div class="wdw-neo-collapse" id="neoNameWrap"><div><div class="pb-4"><label class="visually-hidden" for="nName">Full name</label><input id="nName" type="text" class="form-control wdw-neo-in" placeholder="Full name" autocomplete="name"></div></div></div>
<div class="mb-4"><label class="visually-hidden" for="nEmail">Email address</label><input id="nEmail" type="email" class="form-control wdw-neo-in" placeholder="Email address" autocomplete="email"></div>
<div class="mb-4"><label class="visually-hidden" for="nPass">Password</label><input id="nPass" type="password" class="form-control wdw-neo-in" placeholder="Password" autocomplete="new-password"></div>
<button class="btn wdw-neo-btn w-100 text-primary" type="submit" id="neoSubmit"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="4" y="11" width="16" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/></svg><span>Create account</span></button>
</form>
</div>
<div class="col-md-6">
<div class="wdw-neo-panel p-4">
<p class="fw-semibold text-body-emphasis mb-3">Or continue with</p>
<div class="d-grid gap-3 mb-4">
<button class="btn wdw-neo-btn" type="button"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20.5 12h-8M20 12a8.5 8.5 0 1 1-2.6-6.1"/></svg>Google</button>
<button class="btn wdw-neo-btn" type="button"><svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 .5a11.5 11.5 0 0 0-3.6 22.4c.6.1.8-.3.8-.6v-2c-3.2.7-3.9-1.5-3.9-1.5-.5-1.3-1.3-1.7-1.3-1.7-1-.7.1-.7.1-.7 1.2.1 1.8 1.2 1.8 1.2 1 1.8 2.8 1.3 3.4 1 .1-.8.4-1.3.7-1.6-2.6-.3-5.3-1.3-5.3-5.7 0-1.3.5-2.3 1.2-3.1-.1-.3-.5-1.5.1-3.1 0 0 1-.3 3.2 1.2a11 11 0 0 1 5.8 0c2.2-1.5 3.2-1.2 3.2-1.2.6 1.6.2 2.8.1 3.1.8.8 1.2 1.8 1.2 3.1 0 4.4-2.7 5.4-5.3 5.7.4.4.8 1.1.8 2.2v3.2c0 .3.2.7.8.6A11.5 11.5 0 0 0 12 .5z"/></svg>GitHub</button>
</div>
<p class="fw-semibold text-body-emphasis mb-3">Quick tools</p>
<div class="d-flex gap-3 mb-4">
<div class="text-center flex-fill"><button class="btn wdw-neo-btn wdw-neo-sq mb-1" type="button" aria-label="Back"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19 12H5M11 6l-6 6 6 6"/></svg></button><div class="small wdw-muted" aria-hidden="true">Back</div></div>
<div class="text-center flex-fill"><button class="btn wdw-neo-btn wdw-neo-sq mb-1" type="button" aria-label="Bookmark" aria-pressed="false" data-toggle-press><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 3h12v18l-6-4-6 4z"/></svg></button><div class="small wdw-muted" aria-hidden="true">Save</div></div>
<div class="text-center flex-fill"><button class="btn wdw-neo-btn wdw-neo-sq mb-1" type="button" aria-label="Settings"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9L7 7M17 17l2.1 2.1M4.9 19.1L7 17M17 7l2.1-2.1"/></svg></button><div class="small wdw-muted" aria-hidden="true">Settings</div></div>
</div>
<form class="d-flex gap-3" role="search" onsubmit="return false">
<label class="visually-hidden" for="nSearch">Search</label>
<input id="nSearch" type="search" class="form-control wdw-neo-in" placeholder="Search…">
<button class="btn wdw-neo-btn wdw-neo-sq flex-shrink-0" type="submit" aria-label="Search"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></svg></button>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
/* Web Designer Wall library style — shared base for every Bootstrap 5 snippet.
Indigo accent, Plus Jakarta Sans, soft cards, pill buttons. Works in light and dark. */
@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap");
:root,
[data-bs-theme="light"] {
--wdw-font: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--bs-body-font-family: var(--wdw-font);
--bs-primary: #4f46e5;
--bs-primary-rgb: 79, 70, 229;
--bs-primary-text-emphasis: #3730a3;
--bs-primary-bg-subtle: #eef2ff;
--bs-primary-border-subtle: #c7d2fe;
--bs-link-color: #4f46e5;
--bs-link-color-rgb: 79, 70, 229;
--bs-link-hover-color: #4338ca;
--bs-link-hover-color-rgb: 67, 56, 202;
--bs-focus-ring-color: rgba(79, 70, 229, 0.25);
--bs-border-radius: 0.75rem;
--bs-border-radius-lg: 1rem;
--bs-border-radius-xl: 1.25rem;
--wdw-radius-card: 1.25rem;
--wdw-shadow: 0 1px 2px rgba(16, 24, 40, 0.05), 0 16px 40px -16px rgba(16, 24, 40, 0.22);
--wdw-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06), 0 4px 12px -4px rgba(16, 24, 40, 0.12);
--wdw-stage: #f5f6fb;
}
[data-bs-theme="dark"] {
--bs-primary: #818cf8;
--bs-primary-rgb: 129, 140, 248;
--bs-primary-text-emphasis: #c7d2fe;
--bs-primary-bg-subtle: rgba(129, 140, 248, 0.14);
--bs-primary-border-subtle: rgba(129, 140, 248, 0.35);
--bs-link-color: #a5b4fc;
--bs-link-color-rgb: 165, 180, 252;
--bs-link-hover-color: #c7d2fe;
--bs-link-hover-color-rgb: 199, 210, 254;
--bs-focus-ring-color: rgba(129, 140, 248, 0.35);
--wdw-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 16px 40px -16px rgba(0, 0, 0, 0.7);
--wdw-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 12px -4px rgba(0, 0, 0, 0.5);
--wdw-stage: #0f1117;
}
body { font-family: var(--wdw-font); -webkit-font-smoothing: antialiased; }
/* Bootstrap compiles its blue into these components; point them at the accent. */
.btn-primary {
--bs-btn-bg: var(--bs-primary); --bs-btn-border-color: var(--bs-primary);
--bs-btn-hover-bg: #4338ca; --bs-btn-hover-border-color: #4338ca;
--bs-btn-active-bg: #3730a3; --bs-btn-active-border-color: #3730a3;
--bs-btn-disabled-bg: var(--bs-primary); --bs-btn-disabled-border-color: var(--bs-primary);
--bs-btn-focus-shadow-rgb: var(--bs-primary-rgb);
}
[data-bs-theme="dark"] .btn-primary { --bs-btn-color: #0f1117; --bs-btn-hover-bg: #a5b4fc; --bs-btn-hover-border-color: #a5b4fc; --bs-btn-hover-color: #0f1117; --bs-btn-active-color: #0f1117; }
.btn-outline-primary {
--bs-btn-color: var(--bs-primary); --bs-btn-border-color: var(--bs-primary);
--bs-btn-hover-bg: var(--bs-primary); --bs-btn-hover-border-color: var(--bs-primary);
--bs-btn-active-bg: var(--bs-primary); --bs-btn-active-border-color: var(--bs-primary);
--bs-btn-focus-shadow-rgb: var(--bs-primary-rgb);
}
.btn { --bs-btn-font-weight: 600; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; gap: .5rem; }
.btn-sm { min-height: 36px; }
.form-control, .form-select { min-height: 44px; border-radius: .75rem; }
.form-control:focus, .form-select:focus, .form-check-input:focus { border-color: rgba(var(--bs-primary-rgb), .6); box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }
.form-check-input:checked { background-color: var(--bs-primary); border-color: var(--bs-primary); }
.nav-pills { --bs-nav-pills-link-active-bg: var(--bs-primary); }
.nav { --bs-nav-link-color: var(--bs-secondary-color); --bs-nav-link-hover-color: var(--bs-emphasis-color); }
.pagination { --bs-pagination-active-bg: var(--bs-primary); --bs-pagination-active-border-color: var(--bs-primary); --bs-pagination-color: var(--bs-body-color); --bs-pagination-focus-box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }
.progress, .progress-stacked { --bs-progress-bar-bg: var(--bs-primary); }
.list-group { --bs-list-group-active-bg: var(--bs-primary); --bs-list-group-active-border-color: var(--bs-primary); }
.dropdown-menu { --bs-dropdown-link-active-bg: var(--bs-primary); border-radius: .875rem; box-shadow: var(--wdw-shadow-sm); }
.accordion { --bs-accordion-active-bg: var(--bs-primary-bg-subtle); --bs-accordion-active-color: var(--bs-primary-text-emphasis); --bs-accordion-btn-focus-box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }
.badge { font-weight: 600; }
/* Library building blocks — use these instead of re-inventing them per snippet. */
.wdw-stage { min-height: 100vh; display: flex; align-items: center; background: var(--wdw-stage); padding-block: 3rem; }
.wdw-card { background: var(--bs-body-bg); border: 1px solid var(--bs-border-color-translucent); border-radius: var(--wdw-radius-card); box-shadow: var(--wdw-shadow); }
.wdw-card-sm { background: var(--bs-body-bg); border: 1px solid var(--bs-border-color-translucent); border-radius: 1rem; box-shadow: var(--wdw-shadow-sm); }
.wdw-aurora { position: relative; color: #fff; background: radial-gradient(60% 55% at 100% 0, #818cf8 0, transparent 70%), radial-gradient(65% 60% at 0 100%, #ec4899 0, transparent 65%), #1e1b4b; }
.wdw-eyebrow { display: inline-block; font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--bs-primary); }
.wdw-heading { font-weight: 800; letter-spacing: -.02em; color: var(--bs-emphasis-color); }
.wdw-muted { color: var(--bs-secondary-color); }
.wdw-icon { width: 2.75rem; height: 2.75rem; flex: none; display: inline-flex; align-items: center; justify-content: center; border-radius: .875rem; background: var(--bs-primary-bg-subtle); color: var(--bs-primary); }
/* Component */
.wdw-neo-board { --n-bg: color-mix(in srgb, var(--wdw-stage) 90%, var(--bs-body-color)); --n-hi: color-mix(in srgb, var(--n-bg) 35%, #fff); --n-lo: color-mix(in srgb, var(--n-bg) 78%, #1e2440);
--n-line: color-mix(in srgb, var(--n-bg) 55%, var(--bs-body-color)); background: var(--n-bg); border-radius: 2rem; }
[data-bs-theme="dark"] .wdw-neo-board { --n-hi: color-mix(in srgb, var(--n-bg) 88%, #fff); --n-lo: color-mix(in srgb, var(--n-bg) 35%, #000); --n-line: color-mix(in srgb, var(--n-bg) 50%, var(--bs-body-color)); }
.wdw-neo-panel { border-radius: 1.5rem; background: var(--n-bg); border: 1px solid var(--n-line); box-shadow: inset 3px 3px 8px var(--n-lo), inset -3px -3px 8px var(--n-hi); }
.wdw-neo-btn { --bs-btn-bg: var(--n-bg); --bs-btn-color: var(--bs-body-color); --bs-btn-border-color: var(--n-line); --bs-btn-hover-bg: var(--n-bg); --bs-btn-hover-color: var(--bs-primary); --bs-btn-hover-border-color: var(--n-line);
--bs-btn-active-bg: var(--n-bg); --bs-btn-active-color: var(--bs-primary); --bs-btn-active-border-color: var(--n-line);
min-height: 48px; padding: 0 1.5rem; border-radius: 50rem; font-weight: 700; box-shadow: 6px 6px 14px var(--n-lo), -6px -6px 14px var(--n-hi); transition: box-shadow .2s, color .2s; }
.wdw-neo-btn:active, .wdw-neo-btn.active, .wdw-neo-btn[aria-pressed="true"] { color: var(--bs-primary); box-shadow: inset 4px 4px 9px var(--n-lo), inset -4px -4px 9px var(--n-hi); }
.wdw-neo-btn:focus-visible { outline: 3px solid var(--bs-focus-ring-color); outline-offset: 3px; box-shadow: 6px 6px 14px var(--n-lo), -6px -6px 14px var(--n-hi); }
.wdw-neo-sq { width: 52px; height: 52px; padding: 0; border-radius: 1rem; }
.wdw-neo-in.form-control { height: 52px; border: 1px solid var(--n-line); border-radius: 50rem; padding: 0 1.5rem; background: var(--n-bg); color: var(--bs-body-color); box-shadow: inset 4px 4px 9px var(--n-lo), inset -4px -4px 9px var(--n-hi); }
.wdw-neo-in.form-control::placeholder { color: var(--bs-secondary-color); }
.wdw-neo-in.form-control:focus { background: var(--n-bg); border-color: var(--bs-primary); box-shadow: inset 4px 4px 9px var(--n-lo), inset -4px -4px 9px var(--n-hi), 0 0 0 .2rem var(--bs-focus-ring-color); }
.wdw-neo-collapse { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .3s ease, opacity .3s ease; }
.wdw-neo-collapse > div { overflow: hidden; min-height: 0; }
.wdw-neo-collapse.is-collapsed { grid-template-rows: 0fr; opacity: 0; visibility: hidden; transition: grid-template-rows .3s ease, opacity .3s ease, visibility 0s .3s; }
@media (prefers-reduced-motion: reduce) { .wdw-neo-collapse, .wdw-neo-btn { transition: none; } }
(function () {
function initNeoTabs() {
var tabs = document.querySelectorAll('.wdw-neo-tabs [data-mode]'), label = document.querySelector('#neoSubmit span');
var form = document.getElementById('neoForm'), nameWrap = document.getElementById('neoNameWrap');
var name = document.getElementById('nName'), pass = document.getElementById('nPass');
if (!tabs.length || !label || !nameWrap) return;
function setMode(mode) {
var up = mode === 'up';
tabs.forEach(function (o) { var on = o.dataset.mode === mode; o.classList.toggle('active', on); o.setAttribute('aria-pressed', on); });
label.textContent = up ? 'Create account' : 'Log in';
nameWrap.classList.toggle('is-collapsed', !up);
if (name) name.disabled = !up;
if (pass) pass.setAttribute('autocomplete', up ? 'new-password' : 'current-password');
}
tabs.forEach(function (t) { t.addEventListener('click', function () { setMode(t.dataset.mode); }); });
setMode('up');
if (form) form.addEventListener('submit', function (e) { e.preventDefault(); });
}
function initTogglePress() {
document.querySelectorAll('[data-toggle-press]').forEach(function (b) {
b.addEventListener('click', function () { b.setAttribute('aria-pressed', b.getAttribute('aria-pressed') !== 'true'); });
});
}
initNeoTabs(); initTogglePress();
})();
Built on Bootstrap 5.3.8 with plain JavaScript — no jQuery. Supports light and dark mode via data-bs-theme.