23 / 30
All 30 in 30 Tailwind CSS Login Forms
- 01Tailwind Split-Screen Brand Hero Login Form
- 02Tailwind Multi-Tenant Workspace Account Switcher
- 03Tailwind Floating Label Login Form with peer Variants
- 04Tailwind Web3 Wallet Connect Login Grid
- 05Tailwind Minimalist Fintech Login Card with Layered Shadow
- 06Tailwind OAuth Social Login Form with Brand SVG Buttons
- 07Tailwind Passwordless Magic Link Login with data-state Machine
- 08Tailwind Aurora Glow Login Card with Drifting Blur Blobs
- 09Tailwind Neon Synthwave Arcade Login Form
- 10Tailwind Sliding Login and Sign Up Panel with peer-checked
- 11Tailwind 3D Flip Login Card with Password Reset Back Face
- 12Tailwind Terminal CLI Prompt Login Form
- 13Tailwind Floating Pill Login Widget Docked Over App Content
- 14Tailwind Gradient Border Login Card with background-clip
- 15Tailwind Slide-Over Side Panel Login without JavaScript
- 16Tailwind Social-First Sign Up with Brand-Compliant Buttons
- 17Tailwind Animated Mascot Login that Covers Its Eyes
- 18Tailwind Accessible Compact Login Modal with Scale-In
- 19Tailwind Glassmorphism Login Card with backdrop-filter
- 20Tailwind Multi-Step Login Wizard with Radio-Driven Track
- 21Tailwind Animated Conic Gradient Border Login Card
- 22Tailwind Secure Vault Login with user-invalid Error State
- 23Tailwind Neo-Brutalist Login Form with Hard Offset Shadow
- 24Tailwind Show Hide Password Toggle with aria-pressed
- 25Tailwind OTP Code Input Grid with Auto-Advance
- 26Tailwind Password Strength Meter with data-score Variants
- 27Tailwind Numeric PIN Pad Login for Kiosks and POS
- 28Tailwind Inline Form Validation with user-valid and user-invalid
- 29Tailwind Particle Constellation Login over Canvas
- 30Tailwind Biometric Face ID Prompt with Pulse Ripples
Tailwind Neo-Brutalist Login Form with Hard Offset Shadow
Raw neo-brutalism for agencies and portfolios: thick black borders, zero-blur offset shadows, monospace type and a press that slams the button flush onto its own shadow. The port is a good reminder that arbitrary values are not always the answer — shadow-[9px_9px_0_#0a0a0a] is the design, and it deserves to be a @theme shadow token used by four elements.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tlf-23 w-full min-h-svh grid place-items-center bg-tlf23-stage font-tlf23-mono p-6">
<form novalidate class="relative w-[min(380px,100%)] flex flex-col gap-4 p-8 bg-white rounded-none border-[3px] border-tlf23-ink shadow-tlf23-hard">
<span aria-hidden="true" class="absolute -top-3.5 right-4 px-3 py-1 rotate-[4deg] bg-tlf23-acc border-[3px] border-tlf23-ink text-xs font-bold tracking-[0.12em] text-tlf23-ink">MEMBERS</span>
<h1 class="text-[32px] font-tlf23-display tracking-tight text-tlf23-ink">LOG IN</h1>
<label class="flex flex-col gap-1.5"><span class="text-xs font-bold tracking-[0.1em] text-tlf23-ink">EMAIL</span>
<input type="email" autocomplete="email" placeholder="you@studio.co" required class="h-13 px-3.5 rounded-none font-tlf23-mono text-[15px] text-tlf23-ink bg-white border-[3px] border-tlf23-ink transition-shadow duration-100 placeholder:text-tlf23-ph focus-visible:outline-none focus-visible:shadow-[5px_5px_0_var(--color-tlf23-acc),0_0_0_3px_var(--color-tlf23-ink)]"></label>
<label class="flex flex-col gap-1.5"><span class="text-xs font-bold tracking-[0.1em] text-tlf23-ink">PASSWORD</span>
<input type="password" autocomplete="current-password" placeholder="••••••••" required class="h-13 px-3.5 rounded-none font-tlf23-mono text-[15px] text-tlf23-ink bg-white border-[3px] border-tlf23-ink transition-shadow duration-100 placeholder:text-tlf23-ph focus-visible:outline-none focus-visible:shadow-[5px_5px_0_var(--color-tlf23-acc),0_0_0_3px_var(--color-tlf23-ink)]"></label>
<button type="submit" class="h-13 mt-1 rounded-none cursor-pointer bg-tlf23-acc border-[3px] border-tlf23-ink text-tlf23-ink font-tlf23-display text-base tracking-[0.04em] shadow-tlf23-press transition-[translate,box-shadow] duration-100 hover:-translate-x-px hover:-translate-y-px hover:shadow-[6px_6px_0_var(--color-tlf23-ink)] active:translate-x-[5px] active:translate-y-[5px] active:shadow-none focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-tlf23-ink motion-reduce:transition-none motion-reduce:hover:translate-x-0 motion-reduce:hover:translate-y-0">ENTER →</button>
<p class="text-center text-xs text-tlf23-ink">NO ACCOUNT? <a href="#" class="font-bold underline decoration-[3px] underline-offset-2 decoration-tlf23-acc hover:bg-tlf23-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tlf23-ink">GET ONE</a></p>
</form>
</section><section class="tlf-23 w-full min-h-svh grid place-items-center bg-tlf23-stage font-tlf23-mono p-6">
<form novalidate class="relative w-[min(380px,100%)] flex flex-col gap-4 p-8 bg-white rounded-none border-[3px] border-tlf23-ink shadow-tlf23-hard">
<span aria-hidden="true" class="absolute -top-3.5 right-4 px-3 py-1 rotate-[4deg] bg-tlf23-acc border-[3px] border-tlf23-ink text-xs font-bold tracking-[0.12em] text-tlf23-ink">MEMBERS</span>
<h1 class="text-[32px] font-tlf23-display tracking-tight text-tlf23-ink">LOG IN</h1>
<label class="flex flex-col gap-1.5"><span class="text-xs font-bold tracking-[0.1em] text-tlf23-ink">EMAIL</span>
<input type="email" autocomplete="email" placeholder="you@studio.co" required class="h-13 px-3.5 rounded-none font-tlf23-mono text-[15px] text-tlf23-ink bg-white border-[3px] border-tlf23-ink transition-shadow duration-100 placeholder:text-tlf23-ph focus-visible:outline-none focus-visible:shadow-[5px_5px_0_var(--color-tlf23-acc),0_0_0_3px_var(--color-tlf23-ink)]"></label>
<label class="flex flex-col gap-1.5"><span class="text-xs font-bold tracking-[0.1em] text-tlf23-ink">PASSWORD</span>
<input type="password" autocomplete="current-password" placeholder="••••••••" required class="h-13 px-3.5 rounded-none font-tlf23-mono text-[15px] text-tlf23-ink bg-white border-[3px] border-tlf23-ink transition-shadow duration-100 placeholder:text-tlf23-ph focus-visible:outline-none focus-visible:shadow-[5px_5px_0_var(--color-tlf23-acc),0_0_0_3px_var(--color-tlf23-ink)]"></label>
<button type="submit" class="h-13 mt-1 rounded-none cursor-pointer bg-tlf23-acc border-[3px] border-tlf23-ink text-tlf23-ink font-tlf23-display text-base tracking-[0.04em] shadow-tlf23-press transition-[translate,box-shadow] duration-100 hover:-translate-x-px hover:-translate-y-px hover:shadow-[6px_6px_0_var(--color-tlf23-ink)] active:translate-x-[5px] active:translate-y-[5px] active:shadow-none focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-tlf23-ink motion-reduce:transition-none motion-reduce:hover:translate-x-0 motion-reduce:hover:translate-y-0">ENTER →</button>
<p class="text-center text-xs text-tlf23-ink">NO ACCOUNT? <a href="#" class="font-bold underline decoration-[3px] underline-offset-2 decoration-tlf23-acc hover:bg-tlf23-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tlf23-ink">GET ONE</a></p>
</form>
</section>@import "tailwindcss";
@theme {
--color-tlf23-stage: #f0efe9;
--color-tlf23-stage: oklch(0.95 0.008 95);
--color-tlf23-ink: #0a0a0a;
--color-tlf23-ink: oklch(0.14 0 0);
--color-tlf23-acc: #ffe600;
--color-tlf23-acc: oklch(0.92 0.2 105);
--color-tlf23-ph: #8a8a80;
--color-tlf23-ph: oklch(0.6 0.01 95);
--shadow-tlf23-hard: 9px 9px 0 oklch(0.14 0 0);
--shadow-tlf23-press: 5px 5px 0 oklch(0.14 0 0);
--font-tlf23-display: 'Archivo Black', system-ui, sans-serif;
--font-tlf23-mono: 'Space Mono', ui-monospace, Menlo, monospace;
}
.tlf-23 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tlf23-stage: #f0efe9;
--color-tlf23-stage: oklch(0.95 0.008 95);
--color-tlf23-ink: #0a0a0a;
--color-tlf23-ink: oklch(0.14 0 0);
--color-tlf23-acc: #ffe600;
--color-tlf23-acc: oklch(0.92 0.2 105);
--color-tlf23-ph: #8a8a80;
--color-tlf23-ph: oklch(0.6 0.01 95);
--shadow-tlf23-hard: 9px 9px 0 oklch(0.14 0 0);
--shadow-tlf23-press: 5px 5px 0 oklch(0.14 0 0);
--font-tlf23-display: 'Archivo Black', system-ui, sans-serif;
--font-tlf23-mono: 'Space Mono', ui-monospace, Menlo, monospace;
}
.tlf-23 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tlf23-stage: #f0efe9;
--color-tlf23-stage: oklch(0.95 0.008 95);
--color-tlf23-ink: #0a0a0a;
--color-tlf23-ink: oklch(0.14 0 0);
--color-tlf23-acc: #ffe600;
--color-tlf23-acc: oklch(0.92 0.2 105);
--color-tlf23-ph: #8a8a80;
--color-tlf23-ph: oklch(0.6 0.01 95);
--shadow-tlf23-hard: 9px 9px 0 oklch(0.14 0 0);
--shadow-tlf23-press: 5px 5px 0 oklch(0.14 0 0);
--font-tlf23-display: 'Archivo Black', system-ui, sans-serif;
--font-tlf23-mono: 'Space Mono', ui-monospace, Menlo, monospace;
}
.tlf-23 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tlf23-stage: #f0efe9;
--color-tlf23-stage: oklch(0.95 0.008 95);
--color-tlf23-ink: #0a0a0a;
--color-tlf23-ink: oklch(0.14 0 0);
--color-tlf23-acc: #ffe600;
--color-tlf23-acc: oklch(0.92 0.2 105);
--color-tlf23-ph: #8a8a80;
--color-tlf23-ph: oklch(0.6 0.01 95);
--shadow-tlf23-hard: 9px 9px 0 oklch(0.14 0 0);
--shadow-tlf23-press: 5px 5px 0 oklch(0.14 0 0);
--font-tlf23-display: 'Archivo Black', system-ui, sans-serif;
--font-tlf23-mono: 'Space Mono', ui-monospace, Menlo, monospace;
}
.tlf-23 {
width: 100%;
min-height: 100svh;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo+Black&family=Space+Mono:wght@400;700&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo+Black&family=Space+Mono:wght@400;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
--shadow-*is a first-class@themenamespace in v4, so a hard shadow that appears on four elements becomesshadow-tlf23-hard— the opposite lesson from demo 14, where the value was genuinely single-use.hover:-translate-x-pxthenactive:translate-x-[5px]on the same element works because Tailwind emits:activeafter:hoverin its variant order — worth knowing before hand-writing the specificity.- Archivo Black + Space Mono is the port's biggest single visual upgrade: the original ran the whole aesthetic on a system monospace, and brutalism is a typographic style before it is a shadow style.
- UI change from the CSS original: real display type, fields and button at 52px (was 52px but without a matched hit area on the link), the placeholder darkened from
#9a9a90tooklch(0.6 0.01 95), and a sign-up line with a thick yellow underline was added — the original card had no way out.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Neo-Brutalist Login Form with Hard Offset Shadow
Source: https://codefronts.com/components/tailwind-css-login-forms/tailwind-neo-brutalist-login-form-hard-shadow/
Raw neo-brutalism for agencies and portfolios: thick black borders, zero-blur offset shadows, monospace type and a press that slams the button flush onto its own shadow. The port is a good reminder that arbitrary values are not always the answer — shadow-[9px_9px_0_#0a0a0a] is the design, and it deserves to be a @theme shadow token used by four elements.
## HTML
```html
<section class="tlf-23 w-full min-h-svh grid place-items-center bg-tlf23-stage font-tlf23-mono p-6">
<form novalidate class="relative w-[min(380px,100%)] flex flex-col gap-4 p-8 bg-white rounded-none border-[3px] border-tlf23-ink shadow-tlf23-hard">
<span aria-hidden="true" class="absolute -top-3.5 right-4 px-3 py-1 rotate-[4deg] bg-tlf23-acc border-[3px] border-tlf23-ink text-xs font-bold tracking-[0.12em] text-tlf23-ink">MEMBERS</span>
<h1 class="text-[32px] font-tlf23-display tracking-tight text-tlf23-ink">LOG IN</h1>
<label class="flex flex-col gap-1.5"><span class="text-xs font-bold tracking-[0.1em] text-tlf23-ink">EMAIL</span>
<input type="email" autocomplete="email" placeholder="you@studio.co" required class="h-13 px-3.5 rounded-none font-tlf23-mono text-[15px] text-tlf23-ink bg-white border-[3px] border-tlf23-ink transition-shadow duration-100 placeholder:text-tlf23-ph focus-visible:outline-none focus-visible:shadow-[5px_5px_0_var(--color-tlf23-acc),0_0_0_3px_var(--color-tlf23-ink)]"></label>
<label class="flex flex-col gap-1.5"><span class="text-xs font-bold tracking-[0.1em] text-tlf23-ink">PASSWORD</span>
<input type="password" autocomplete="current-password" placeholder="••••••••" required class="h-13 px-3.5 rounded-none font-tlf23-mono text-[15px] text-tlf23-ink bg-white border-[3px] border-tlf23-ink transition-shadow duration-100 placeholder:text-tlf23-ph focus-visible:outline-none focus-visible:shadow-[5px_5px_0_var(--color-tlf23-acc),0_0_0_3px_var(--color-tlf23-ink)]"></label>
<button type="submit" class="h-13 mt-1 rounded-none cursor-pointer bg-tlf23-acc border-[3px] border-tlf23-ink text-tlf23-ink font-tlf23-display text-base tracking-[0.04em] shadow-tlf23-press transition-[translate,box-shadow] duration-100 hover:-translate-x-px hover:-translate-y-px hover:shadow-[6px_6px_0_var(--color-tlf23-ink)] active:translate-x-[5px] active:translate-y-[5px] active:shadow-none focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-tlf23-ink motion-reduce:transition-none motion-reduce:hover:translate-x-0 motion-reduce:hover:translate-y-0">ENTER →</button>
<p class="text-center text-xs text-tlf23-ink">NO ACCOUNT? <a href="#" class="font-bold underline decoration-[3px] underline-offset-2 decoration-tlf23-acc hover:bg-tlf23-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tlf23-ink">GET ONE</a></p>
</form>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tlf23-stage: #f0efe9;
--color-tlf23-stage: oklch(0.95 0.008 95);
--color-tlf23-ink: #0a0a0a;
--color-tlf23-ink: oklch(0.14 0 0);
--color-tlf23-acc: #ffe600;
--color-tlf23-acc: oklch(0.92 0.2 105);
--color-tlf23-ph: #8a8a80;
--color-tlf23-ph: oklch(0.6 0.01 95);
--shadow-tlf23-hard: 9px 9px 0 oklch(0.14 0 0);
--shadow-tlf23-press: 5px 5px 0 oklch(0.14 0 0);
--font-tlf23-display: 'Archivo Black', system-ui, sans-serif;
--font-tlf23-mono: 'Space Mono', ui-monospace, Menlo, monospace;
}
.tlf-23 {
width: 100%;
min-height: 100svh;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Neo-Brutalist Login Form with Hard Offset Shadow
Source: https://codefronts.com/components/tailwind-css-login-forms/tailwind-neo-brutalist-login-form-hard-shadow/
Raw neo-brutalism for agencies and portfolios: thick black borders, zero-blur offset shadows, monospace type and a press that slams the button flush onto its own shadow. The port is a good reminder that arbitrary values are not always the answer — shadow-[9px_9px_0_#0a0a0a] is the design, and it deserves to be a @theme shadow token used by four elements.
## HTML
```html
<section class="tlf-23 w-full min-h-svh grid place-items-center bg-tlf23-stage font-tlf23-mono p-6">
<form novalidate class="relative w-[min(380px,100%)] flex flex-col gap-4 p-8 bg-white rounded-none border-[3px] border-tlf23-ink shadow-tlf23-hard">
<span aria-hidden="true" class="absolute -top-3.5 right-4 px-3 py-1 rotate-[4deg] bg-tlf23-acc border-[3px] border-tlf23-ink text-xs font-bold tracking-[0.12em] text-tlf23-ink">MEMBERS</span>
<h1 class="text-[32px] font-tlf23-display tracking-tight text-tlf23-ink">LOG IN</h1>
<label class="flex flex-col gap-1.5"><span class="text-xs font-bold tracking-[0.1em] text-tlf23-ink">EMAIL</span>
<input type="email" autocomplete="email" placeholder="you@studio.co" required class="h-13 px-3.5 rounded-none font-tlf23-mono text-[15px] text-tlf23-ink bg-white border-[3px] border-tlf23-ink transition-shadow duration-100 placeholder:text-tlf23-ph focus-visible:outline-none focus-visible:shadow-[5px_5px_0_var(--color-tlf23-acc),0_0_0_3px_var(--color-tlf23-ink)]"></label>
<label class="flex flex-col gap-1.5"><span class="text-xs font-bold tracking-[0.1em] text-tlf23-ink">PASSWORD</span>
<input type="password" autocomplete="current-password" placeholder="••••••••" required class="h-13 px-3.5 rounded-none font-tlf23-mono text-[15px] text-tlf23-ink bg-white border-[3px] border-tlf23-ink transition-shadow duration-100 placeholder:text-tlf23-ph focus-visible:outline-none focus-visible:shadow-[5px_5px_0_var(--color-tlf23-acc),0_0_0_3px_var(--color-tlf23-ink)]"></label>
<button type="submit" class="h-13 mt-1 rounded-none cursor-pointer bg-tlf23-acc border-[3px] border-tlf23-ink text-tlf23-ink font-tlf23-display text-base tracking-[0.04em] shadow-tlf23-press transition-[translate,box-shadow] duration-100 hover:-translate-x-px hover:-translate-y-px hover:shadow-[6px_6px_0_var(--color-tlf23-ink)] active:translate-x-[5px] active:translate-y-[5px] active:shadow-none focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-tlf23-ink motion-reduce:transition-none motion-reduce:hover:translate-x-0 motion-reduce:hover:translate-y-0">ENTER →</button>
<p class="text-center text-xs text-tlf23-ink">NO ACCOUNT? <a href="#" class="font-bold underline decoration-[3px] underline-offset-2 decoration-tlf23-acc hover:bg-tlf23-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tlf23-ink">GET ONE</a></p>
</form>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tlf23-stage: #f0efe9;
--color-tlf23-stage: oklch(0.95 0.008 95);
--color-tlf23-ink: #0a0a0a;
--color-tlf23-ink: oklch(0.14 0 0);
--color-tlf23-acc: #ffe600;
--color-tlf23-acc: oklch(0.92 0.2 105);
--color-tlf23-ph: #8a8a80;
--color-tlf23-ph: oklch(0.6 0.01 95);
--shadow-tlf23-hard: 9px 9px 0 oklch(0.14 0 0);
--shadow-tlf23-press: 5px 5px 0 oklch(0.14 0 0);
--font-tlf23-display: 'Archivo Black', system-ui, sans-serif;
--font-tlf23-mono: 'Space Mono', ui-monospace, Menlo, monospace;
}
.tlf-23 {
width: 100%;
min-height: 100svh;
}
```How this works
The press must match the shadow exactly. A 5px shadow and a 5px translate mean the element lands flush with zero gap. Off by a pixel and it reads as a rendering glitch rather than a physical stamp — which is why both numbers come from the same token pair.
Zero blur, always. 9px 9px 0. Any blur radius turns brutalism into ordinary material depth, and the whole aesthetic collapses.
Focus is hard-edged too. A soft ring would look borrowed from another design system; the fields get an offset accent slab plus a 3px ink outline, which is the same visual grammar as everything else on the card.
Make it yours
- Shout colour:
--color-tlf23-acc(the yellow) drives the badge, the button and every focus slab. - Offset:
--shadow-tlf23-hardand the matchingactive:translate-*values — change both. - Type:
--font-tlf23-displayand--font-tlf23-mono. - Add a second rotated badge;
rotate-[-3deg]keeps it from looking aligned by accident.
Gotchas — read before shipping
- Keep contrast honest. Yellow-on-black and black-on-yellow both pass here; yellow on white does not, which is why the button ink is
#0a0a0a. - Any
blurin the shadow kills it. rounded-noneis the default, but say it explicitly if the surrounding page sets a radius — a 4px radius is enough to make the whole card look apologetic.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Hard shadows, transforms and :active/:focus-visible are universally supported; the floor is Tailwind v4's generated sheet.