Two factor and sign in
Sign in, centered
A centered sign in card on a soft backdrop: passkey first, then email and password, the flow progress, and a footer link. Composes the card shell with the native form fields; needs monsoon.js only for the reveal button.
Needs monsoon.js. The styles work on their own, and the behavior comes from the optional interactive layer: add <script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script> or import 'monsooncss/js'. See the interactive layer.
Example
<div class="auth-layout">
<form class="auth-card" action="#" onsubmit="event.preventDefault()">
<ol class="auth-flow" aria-label="Sign in progress">
<li class="auth-flow-step" aria-current="step"><span class="auth-flow-label">Password</span></li>
<li class="auth-flow-step"><span class="auth-flow-label">Verify</span></li>
<li class="auth-flow-step"><span class="auth-flow-label">Done</span></li>
</ol>
<header class="auth-header">
<span class="auth-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5" y="10.5" width="14" height="10" rx="2.5"/><path d="M8 10.5V8a4 4 0 0 1 8 0v2.5"/><path d="M12 14.5v2"/></svg></span>
<h2 class="auth-title">Sign in to Example</h2>
<p class="auth-description">Welcome back. Use a passkey or your email and password.</p>
</header>
<button type="button" class="btn btn-outline btn-block"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9.5" cy="8" r="3.5"/><path d="M3.5 20a6 6 0 0 1 9.4-4.9"/><circle cx="17.5" cy="12.5" r="2.5"/><path d="M17.5 15v6l1.6-1.3M17.5 18l1.4 1"/></svg> Continue with a passkey</button>
<div class="divider my-0">or</div>
<div class="grid gap-4">
<div class="field">
<label class="label" for="signin-email">Email</label>
<input id="signin-email" class="input" type="email" name="email" autocomplete="username webauthn" placeholder="you@example.com">
</div>
<div class="field">
<div class="flex items-center justify-between"><label class="label" for="signin-password">Password</label><a class="link link-primary text-sm" href="#forgot">Forgot it?</a></div>
<div class="password-field" data-m-auth-password>
<input id="signin-password" class="input" type="password" name="password" autocomplete="current-password">
<button type="button" class="password-field-toggle" aria-pressed="false" aria-label="Show password"></button>
</div>
</div>
</div>
<button class="btn btn-primary btn-block">Continue</button>
<footer class="auth-footer">New here? <a class="link link-primary" href="#signup">Create an account</a></footer>
</form>
</div>Classes
7 classes. Click a name to copy it. Utilities on the same element always win over component defaults, so any of them can be adjusted with plain utility classes.
| Class | Type | What it does |
|---|---|---|
| Part | Part of the sign in, centered. On a <div> in the example. Sets grid display, alignment, height, padding and background.CSS |
|
| Base | Base class of the sign in, centered. On a <form> in the example. Sets grid display, gap, width, padding, text color and background, and 4 custom properties.CSS |
|
| Part | Part of the sign in, centered. On a <header> in the example. Sets grid display, alignment, gap and text style.CSS |
|
| Part | Part of the sign in, centered. On a <span> in the example. Sets grid display, alignment, width, height, margin and text color, and --tone.CSS |
|
| Part | Part of the sign in, centered. On a <h2> in the example. Sets margin, text size, font weight and text style.CSS |
|
| Part | Part of the sign in, centered. On a <p> in the example. Sets width, margin, text size, text style and text color.CSS |
|
| Part | Part of the sign in, centered. On a <footer> in the example. Sets margin, padding, text size, text style, text color and background.CSS |
Usage
The styles ship inside the same stylesheet as the utilities, and the behavior comes from the optional monsoon.js script, which enhances any element with a matching data-m attribute, including markup added later.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">
<script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script>
<!-- Sign in, centered: start from the base class, then add modifiers -->
<div class="auth-layout">
<form class="auth-card" action="#" onsubmit="event.preventDefault()">
<ol class="auth-flow" aria-label="Sign in progress">
<li class="auth-flow-step" aria-current="step"><span class="auth-flow-label">Password</span></li>
<li class="auth-flow-step"><span class="auth-flow-label">Verify</span></li>
<li class="auth-flow-step"><span class="auth-flow-label">Done</span></li>
</ol>
<header class="auth-header">
<span class="auth-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5" y="10.5" width="14" height="10" rx="2.5"/><path d="M8 10.5V8a4 4 0 0 1 8 0v2.5"/><path d="M12 14.5v2"/></svg></span>
<h2 class="auth-title">Sign in to Example</h2>
<p class="auth-description">Welcome back. Use a passkey or your email and password.</p>
</header>
<button type="button" class="btn btn-outline btn-block"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9.5" cy="8" r="3.5"/><path d="M3.5 20a6 6 0 0 1 9.4-4.9"/><circle cx="17.5" cy="12.5" r="2.5"/><path d="M17.5 15v6l1.6-1.3M17.5 18l1.4 1"/></svg> Continue with a passkey</button>
<div class="divider my-0">or</div>
<!-- the full example is in the Code tab above -->Theme it with --seed on any ancestor, for example style="--seed: #0d9488", and force a scheme with class="dark" or class="light" on a wrapper.
Accessibility
- Give every control a visible
labellinked withfor, or anaria-labelwhen the purpose is obvious from context. Link help and error text witharia-describedby; invalid styles use:user-invalid, so they appear only after the user interacts. - Use
buttonfor actions andafor navigation. Icon only buttons need anaria-label; decorative icons carryaria-hidden="true". - Every interactive part shows a visible focus ring with
:focus-visible, and tone colors pair with-foregroundtokens that keep text at 4.5:1 or better in light and dark mode.