09 / 17
All 17 in 17 Tailwind CSS Side Menus
- 01Tailwind Slide-In Side Menu with Animated Hamburger Icon
- 02Tailwind Sidebar Drawer with Blurred Backdrop Overlay
- 03Tailwind Off-Canvas Push Sidebar Menu
- 04Tailwind Collapsible Icon Sidebar That Expands on Hover
- 05Responsive Tailwind Sidebar with Mobile Hamburger Toggle
- 06Tailwind Sticky Sidebar Navigation with Scrolling Content
- 07Tailwind Multi-Level Dropdown Sidebar Menu (Nested Accordion)
- 08Tailwind Full-Height Flexbox Sidebar Layout
- 09Tailwind Neumorphism Sidebar Menu (Dark Mode)
- 10Tailwind Glassmorphism Sidebar with Backdrop Blur
- 11Tailwind Cyberpunk Neon Sidebar (Dark Mode)
- 12Brutalist Sidebar Navigation in Tailwind CSS
- 13Pure CSS Hamburger Menu in Tailwind (Checkbox Hack, No JS)
- 14Tailwind Sidebar Drawer That Opens on Hover
- 15Tailwind Collapsible Sidebar with Toggle Button (No JS)
- 16Tailwind Accordion Sidebar Navigation for Documentation
- 17Tailwind macOS-Style Glass Dock Sidebar with Sliding Highlight
Tailwind Neumorphism Sidebar Menu (Dark Mode)
Soft UI in the dark: links rest flat, extrude on hover and press into the surface when active, using two shadow tokens minted in @theme (shadow-tsm09-out, shadow-tsm09-in). The port fixes the illusion-breaking colour mismatch of the original — sidebar, page and cards now share one base tone — and adds the high-contrast focus ring neumorphism always needs.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tsm-09 flex w-full min-h-svh bg-tsm09-bg font-tsm09-sans text-tsm09-ink" aria-label="Neumorphism sidebar menu demo">
<nav aria-label="Main" class="flex w-56 shrink-0 flex-col py-6 shadow-[inset_-1px_0_0_oklch(1_0_0/0.04),6px_0_18px_oklch(0_0_0/0.35)]">
<div class="mx-[18px] mb-5 flex items-center gap-3 pb-5 shadow-[0_1px_0_oklch(1_0_0/0.04)]">
<span aria-hidden="true" class="grid size-[38px] place-items-center rounded-[11px] bg-tsm09-bg text-base font-bold text-tsm09-acc shadow-tsm09-out">N</span>
<p class="text-sm font-bold">Neura</p>
</div>
<ul class="grid gap-2 px-3">
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none" aria-current="page"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg><span class="flex-1">Dashboard</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg><span class="flex-1">Analytics</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></svg><span class="flex-1">Calendar</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12z"/></svg><span class="flex-1">Messages</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li aria-hidden="true" class="mx-2 my-1 h-px bg-linear-to-r from-transparent via-white/8 to-transparent"></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h9"/><path d="M19 6h1"/><circle cx="16" cy="6" r="2.5"/><path d="M4 12h2"/><path d="M12 12h8"/><circle cx="9" cy="12" r="2.5"/><path d="M4 18h11"/><circle cx="18" cy="18" r="2.5"/></svg><span class="flex-1">Settings</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
</ul>
<div class="mx-3 mt-auto flex items-center gap-2.5 rounded-2xl bg-tsm09-bg p-3.5 shadow-tsm09-in">
<span aria-hidden="true" class="grid size-8 shrink-0 place-items-center rounded-full bg-linear-135 from-tsm09-acc to-tsm09-acc2 text-xs font-bold text-tsm09-bg shadow-[3px_3px_8px_oklch(0_0_0/0.5)]">PB</span>
<div><p class="text-xs font-bold">P. Blake</p><p class="text-[10px] text-tsm09-mut">Designer</p></div>
</div>
</nav>
<div class="min-w-0 flex-1 p-6">
<div class="mx-auto max-w-3xl">
<h1 class="text-lg font-bold">Dashboard</h1>
<p class="mt-1.5 mb-6 max-w-prose text-[13px] leading-relaxed text-tsm09-mut text-pretty">Hover a link to raise it; the active page is pressed into the surface. Tab through to see the focus ring neumorphism needs.</p>
<div class="grid grid-cols-2 gap-4 md:grid-cols-4">
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">3,091</p><p class="mt-1 text-[11px] text-tsm09-mut">Sessions</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">71%</p><p class="mt-1 text-[11px] text-tsm09-mut">Engagement</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">$6.3k</p><p class="mt-1 text-[11px] text-tsm09-mut">Revenue</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">521</p><p class="mt-1 text-[11px] text-tsm09-mut">Sign-ups</p></div>
</div>
</div>
</div>
</section><section class="tsm-09 flex w-full min-h-svh bg-tsm09-bg font-tsm09-sans text-tsm09-ink" aria-label="Neumorphism sidebar menu demo">
<nav aria-label="Main" class="flex w-56 shrink-0 flex-col py-6 shadow-[inset_-1px_0_0_oklch(1_0_0/0.04),6px_0_18px_oklch(0_0_0/0.35)]">
<div class="mx-[18px] mb-5 flex items-center gap-3 pb-5 shadow-[0_1px_0_oklch(1_0_0/0.04)]">
<span aria-hidden="true" class="grid size-[38px] place-items-center rounded-[11px] bg-tsm09-bg text-base font-bold text-tsm09-acc shadow-tsm09-out">N</span>
<p class="text-sm font-bold">Neura</p>
</div>
<ul class="grid gap-2 px-3">
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none" aria-current="page"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg><span class="flex-1">Dashboard</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg><span class="flex-1">Analytics</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></svg><span class="flex-1">Calendar</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12z"/></svg><span class="flex-1">Messages</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li aria-hidden="true" class="mx-2 my-1 h-px bg-linear-to-r from-transparent via-white/8 to-transparent"></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h9"/><path d="M19 6h1"/><circle cx="16" cy="6" r="2.5"/><path d="M4 12h2"/><path d="M12 12h8"/><circle cx="9" cy="12" r="2.5"/><path d="M4 18h11"/><circle cx="18" cy="18" r="2.5"/></svg><span class="flex-1">Settings</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
</ul>
<div class="mx-3 mt-auto flex items-center gap-2.5 rounded-2xl bg-tsm09-bg p-3.5 shadow-tsm09-in">
<span aria-hidden="true" class="grid size-8 shrink-0 place-items-center rounded-full bg-linear-135 from-tsm09-acc to-tsm09-acc2 text-xs font-bold text-tsm09-bg shadow-[3px_3px_8px_oklch(0_0_0/0.5)]">PB</span>
<div><p class="text-xs font-bold">P. Blake</p><p class="text-[10px] text-tsm09-mut">Designer</p></div>
</div>
</nav>
<div class="min-w-0 flex-1 p-6">
<div class="mx-auto max-w-3xl">
<h1 class="text-lg font-bold">Dashboard</h1>
<p class="mt-1.5 mb-6 max-w-prose text-[13px] leading-relaxed text-tsm09-mut text-pretty">Hover a link to raise it; the active page is pressed into the surface. Tab through to see the focus ring neumorphism needs.</p>
<div class="grid grid-cols-2 gap-4 md:grid-cols-4">
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">3,091</p><p class="mt-1 text-[11px] text-tsm09-mut">Sessions</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">71%</p><p class="mt-1 text-[11px] text-tsm09-mut">Engagement</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">$6.3k</p><p class="mt-1 text-[11px] text-tsm09-mut">Revenue</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">521</p><p class="mt-1 text-[11px] text-tsm09-mut">Sign-ups</p></div>
</div>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tsm09-bg: #1e1e35;
--color-tsm09-bg: oklch(0.247 0.043 282.8);
--color-tsm09-acc: #8e98fa;
--color-tsm09-acc: oklch(0.713 0.143 277.7);
--color-tsm09-acc2: #c084fc;
--color-tsm09-acc2: oklch(0.722 0.177 305.5);
--color-tsm09-ink: #e2e8f0;
--color-tsm09-ink: oklch(0.929 0.013 255.5);
--color-tsm09-mut: #a3a9c2;
--color-tsm09-mut: oklch(0.738 0.037 274.8);
--font-tsm09-sans: 'Poppins', system-ui, sans-serif;
--shadow-tsm09-out: 5px 5px 12px oklch(0 0 0 / 0.55), -3px -3px 9px oklch(1 0 0 / 0.05);
--shadow-tsm09-in: inset 4px 4px 9px oklch(0 0 0 / 0.6), inset -3px -3px 8px oklch(1 0 0 / 0.05);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tsm-09 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tsm09-bg: #1e1e35;
--color-tsm09-bg: oklch(0.247 0.043 282.8);
--color-tsm09-acc: #8e98fa;
--color-tsm09-acc: oklch(0.713 0.143 277.7);
--color-tsm09-acc2: #c084fc;
--color-tsm09-acc2: oklch(0.722 0.177 305.5);
--color-tsm09-ink: #e2e8f0;
--color-tsm09-ink: oklch(0.929 0.013 255.5);
--color-tsm09-mut: #a3a9c2;
--color-tsm09-mut: oklch(0.738 0.037 274.8);
--font-tsm09-sans: 'Poppins', system-ui, sans-serif;
--shadow-tsm09-out: 5px 5px 12px oklch(0 0 0 / 0.55), -3px -3px 9px oklch(1 0 0 / 0.05);
--shadow-tsm09-in: inset 4px 4px 9px oklch(0 0 0 / 0.6), inset -3px -3px 8px oklch(1 0 0 / 0.05);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tsm-09 {
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-tsm09-bg: #1e1e35;
--color-tsm09-bg: oklch(0.247 0.043 282.8);
--color-tsm09-acc: #8e98fa;
--color-tsm09-acc: oklch(0.713 0.143 277.7);
--color-tsm09-acc2: #c084fc;
--color-tsm09-acc2: oklch(0.722 0.177 305.5);
--color-tsm09-ink: #e2e8f0;
--color-tsm09-ink: oklch(0.929 0.013 255.5);
--color-tsm09-mut: #a3a9c2;
--color-tsm09-mut: oklch(0.738 0.037 274.8);
--font-tsm09-sans: 'Poppins', system-ui, sans-serif;
--shadow-tsm09-out: 5px 5px 12px oklch(0 0 0 / 0.55), -3px -3px 9px oklch(1 0 0 / 0.05);
--shadow-tsm09-in: inset 4px 4px 9px oklch(0 0 0 / 0.6), inset -3px -3px 8px oklch(1 0 0 / 0.05);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tsm-09 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tsm09-bg: #1e1e35;
--color-tsm09-bg: oklch(0.247 0.043 282.8);
--color-tsm09-acc: #8e98fa;
--color-tsm09-acc: oklch(0.713 0.143 277.7);
--color-tsm09-acc2: #c084fc;
--color-tsm09-acc2: oklch(0.722 0.177 305.5);
--color-tsm09-ink: #e2e8f0;
--color-tsm09-ink: oklch(0.929 0.013 255.5);
--color-tsm09-mut: #a3a9c2;
--color-tsm09-mut: oklch(0.738 0.037 274.8);
--font-tsm09-sans: 'Poppins', system-ui, sans-serif;
--shadow-tsm09-out: 5px 5px 12px oklch(0 0 0 / 0.55), -3px -3px 9px oklch(1 0 0 / 0.05);
--shadow-tsm09-in: inset 4px 4px 9px oklch(0 0 0 / 0.6), inset -3px -3px 8px oklch(1 0 0 / 0.05);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tsm-09 {
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=Poppins:wght@400;500;600;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=Poppins:wght@400;500;600;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Five hand-written shadow pairs collapsed into two
@themetokens,--shadow-tsm09-outand--shadow-tsm09-in, applied throughhover:andaria-[current=page]:variants. - UI upgrade from the CSS original: the page, sidebar and cards now share one base colour — the original's two near-identical navies broke the soft-extrusion illusion at every card edge.
- UI upgrade: a 2px focus ring on every link (pressed/raised alone was the original's documented WCAG gap), plus SVG icons and 44px targets.
- UI upgrade: muted text went from
#64748b(3.2:1) to#a3a9c2(6.6:1) and the accent was lifted to#8e98fafor 5.5:1.
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 Neumorphism Sidebar Menu (Dark Mode)
Source: https://codefronts.com/navigation/tailwind-css-side-menus/tailwind-neumorphism-sidebar-menu-dark-mode/
Soft UI in the dark: links rest flat, extrude on hover and press into the surface when active, using two shadow tokens minted in @theme (shadow-tsm09-out, shadow-tsm09-in). The port fixes the illusion-breaking colour mismatch of the original — sidebar, page and cards now share one base tone — and adds the high-contrast focus ring neumorphism always needs.
## HTML
```html
<section class="tsm-09 flex w-full min-h-svh bg-tsm09-bg font-tsm09-sans text-tsm09-ink" aria-label="Neumorphism sidebar menu demo">
<nav aria-label="Main" class="flex w-56 shrink-0 flex-col py-6 shadow-[inset_-1px_0_0_oklch(1_0_0/0.04),6px_0_18px_oklch(0_0_0/0.35)]">
<div class="mx-[18px] mb-5 flex items-center gap-3 pb-5 shadow-[0_1px_0_oklch(1_0_0/0.04)]">
<span aria-hidden="true" class="grid size-[38px] place-items-center rounded-[11px] bg-tsm09-bg text-base font-bold text-tsm09-acc shadow-tsm09-out">N</span>
<p class="text-sm font-bold">Neura</p>
</div>
<ul class="grid gap-2 px-3">
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none" aria-current="page"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg><span class="flex-1">Dashboard</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg><span class="flex-1">Analytics</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></svg><span class="flex-1">Calendar</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12z"/></svg><span class="flex-1">Messages</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li aria-hidden="true" class="mx-2 my-1 h-px bg-linear-to-r from-transparent via-white/8 to-transparent"></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h9"/><path d="M19 6h1"/><circle cx="16" cy="6" r="2.5"/><path d="M4 12h2"/><path d="M12 12h8"/><circle cx="9" cy="12" r="2.5"/><path d="M4 18h11"/><circle cx="18" cy="18" r="2.5"/></svg><span class="flex-1">Settings</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
</ul>
<div class="mx-3 mt-auto flex items-center gap-2.5 rounded-2xl bg-tsm09-bg p-3.5 shadow-tsm09-in">
<span aria-hidden="true" class="grid size-8 shrink-0 place-items-center rounded-full bg-linear-135 from-tsm09-acc to-tsm09-acc2 text-xs font-bold text-tsm09-bg shadow-[3px_3px_8px_oklch(0_0_0/0.5)]">PB</span>
<div><p class="text-xs font-bold">P. Blake</p><p class="text-[10px] text-tsm09-mut">Designer</p></div>
</div>
</nav>
<div class="min-w-0 flex-1 p-6">
<div class="mx-auto max-w-3xl">
<h1 class="text-lg font-bold">Dashboard</h1>
<p class="mt-1.5 mb-6 max-w-prose text-[13px] leading-relaxed text-tsm09-mut text-pretty">Hover a link to raise it; the active page is pressed into the surface. Tab through to see the focus ring neumorphism needs.</p>
<div class="grid grid-cols-2 gap-4 md:grid-cols-4">
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">3,091</p><p class="mt-1 text-[11px] text-tsm09-mut">Sessions</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">71%</p><p class="mt-1 text-[11px] text-tsm09-mut">Engagement</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">$6.3k</p><p class="mt-1 text-[11px] text-tsm09-mut">Revenue</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">521</p><p class="mt-1 text-[11px] text-tsm09-mut">Sign-ups</p></div>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsm09-bg: #1e1e35;
--color-tsm09-bg: oklch(0.247 0.043 282.8);
--color-tsm09-acc: #8e98fa;
--color-tsm09-acc: oklch(0.713 0.143 277.7);
--color-tsm09-acc2: #c084fc;
--color-tsm09-acc2: oklch(0.722 0.177 305.5);
--color-tsm09-ink: #e2e8f0;
--color-tsm09-ink: oklch(0.929 0.013 255.5);
--color-tsm09-mut: #a3a9c2;
--color-tsm09-mut: oklch(0.738 0.037 274.8);
--font-tsm09-sans: 'Poppins', system-ui, sans-serif;
--shadow-tsm09-out: 5px 5px 12px oklch(0 0 0 / 0.55), -3px -3px 9px oklch(1 0 0 / 0.05);
--shadow-tsm09-in: inset 4px 4px 9px oklch(0 0 0 / 0.6), inset -3px -3px 8px oklch(1 0 0 / 0.05);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tsm-09 {
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 Neumorphism Sidebar Menu (Dark Mode)
Source: https://codefronts.com/navigation/tailwind-css-side-menus/tailwind-neumorphism-sidebar-menu-dark-mode/
Soft UI in the dark: links rest flat, extrude on hover and press into the surface when active, using two shadow tokens minted in @theme (shadow-tsm09-out, shadow-tsm09-in). The port fixes the illusion-breaking colour mismatch of the original — sidebar, page and cards now share one base tone — and adds the high-contrast focus ring neumorphism always needs.
## HTML
```html
<section class="tsm-09 flex w-full min-h-svh bg-tsm09-bg font-tsm09-sans text-tsm09-ink" aria-label="Neumorphism sidebar menu demo">
<nav aria-label="Main" class="flex w-56 shrink-0 flex-col py-6 shadow-[inset_-1px_0_0_oklch(1_0_0/0.04),6px_0_18px_oklch(0_0_0/0.35)]">
<div class="mx-[18px] mb-5 flex items-center gap-3 pb-5 shadow-[0_1px_0_oklch(1_0_0/0.04)]">
<span aria-hidden="true" class="grid size-[38px] place-items-center rounded-[11px] bg-tsm09-bg text-base font-bold text-tsm09-acc shadow-tsm09-out">N</span>
<p class="text-sm font-bold">Neura</p>
</div>
<ul class="grid gap-2 px-3">
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none" aria-current="page"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg><span class="flex-1">Dashboard</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg><span class="flex-1">Analytics</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></svg><span class="flex-1">Calendar</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12z"/></svg><span class="flex-1">Messages</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
<li aria-hidden="true" class="mx-2 my-1 h-px bg-linear-to-r from-transparent via-white/8 to-transparent"></li>
<li><a href="#" class="group/l flex min-h-11 items-center gap-3 rounded-xl px-3.5 text-[13px] font-semibold text-tsm09-mut transition-[color,box-shadow] duration-200 hover:text-tsm09-ink hover:shadow-tsm09-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tsm09-acc aria-[current=page]:text-tsm09-acc aria-[current=page]:shadow-tsm09-in motion-reduce:transition-none"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h9"/><path d="M19 6h1"/><circle cx="16" cy="6" r="2.5"/><path d="M4 12h2"/><path d="M12 12h8"/><circle cx="9" cy="12" r="2.5"/><path d="M4 18h11"/><circle cx="18" cy="18" r="2.5"/></svg><span class="flex-1">Settings</span><span aria-hidden="true" class="size-[7px] rounded-full bg-tsm09-acc opacity-0 shadow-[0_0_8px_var(--color-tsm09-acc)] transition-opacity group-aria-[current=page]/l:opacity-100"></span></a></li>
</ul>
<div class="mx-3 mt-auto flex items-center gap-2.5 rounded-2xl bg-tsm09-bg p-3.5 shadow-tsm09-in">
<span aria-hidden="true" class="grid size-8 shrink-0 place-items-center rounded-full bg-linear-135 from-tsm09-acc to-tsm09-acc2 text-xs font-bold text-tsm09-bg shadow-[3px_3px_8px_oklch(0_0_0/0.5)]">PB</span>
<div><p class="text-xs font-bold">P. Blake</p><p class="text-[10px] text-tsm09-mut">Designer</p></div>
</div>
</nav>
<div class="min-w-0 flex-1 p-6">
<div class="mx-auto max-w-3xl">
<h1 class="text-lg font-bold">Dashboard</h1>
<p class="mt-1.5 mb-6 max-w-prose text-[13px] leading-relaxed text-tsm09-mut text-pretty">Hover a link to raise it; the active page is pressed into the surface. Tab through to see the focus ring neumorphism needs.</p>
<div class="grid grid-cols-2 gap-4 md:grid-cols-4">
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">3,091</p><p class="mt-1 text-[11px] text-tsm09-mut">Sessions</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">71%</p><p class="mt-1 text-[11px] text-tsm09-mut">Engagement</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">$6.3k</p><p class="mt-1 text-[11px] text-tsm09-mut">Revenue</p></div>
<div class="rounded-2xl bg-tsm09-bg p-4 shadow-tsm09-out"><p class="text-[22px] font-bold tabular-nums text-tsm09-acc">521</p><p class="mt-1 text-[11px] text-tsm09-mut">Sign-ups</p></div>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsm09-bg: #1e1e35;
--color-tsm09-bg: oklch(0.247 0.043 282.8);
--color-tsm09-acc: #8e98fa;
--color-tsm09-acc: oklch(0.713 0.143 277.7);
--color-tsm09-acc2: #c084fc;
--color-tsm09-acc2: oklch(0.722 0.177 305.5);
--color-tsm09-ink: #e2e8f0;
--color-tsm09-ink: oklch(0.929 0.013 255.5);
--color-tsm09-mut: #a3a9c2;
--color-tsm09-mut: oklch(0.738 0.037 274.8);
--font-tsm09-sans: 'Poppins', system-ui, sans-serif;
--shadow-tsm09-out: 5px 5px 12px oklch(0 0 0 / 0.55), -3px -3px 9px oklch(1 0 0 / 0.05);
--shadow-tsm09-in: inset 4px 4px 9px oklch(0 0 0 / 0.6), inset -3px -3px 8px oklch(1 0 0 / 0.05);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.tsm-09 {
width: 100%;
min-height: 100svh;
}
```How this works
Shadows as tokens. A neumorphic state is always a pair — dark shadow bottom-right, light highlight top-left. Declared once in @theme, each pair becomes a utility:
--shadow-tsm09-out: 5px 5px 12px oklch(0 0 0 / .55),
-3px -3px 9px oklch(1 0 0 / .05);
--shadow-tsm09-in: inset 4px 4px 9px oklch(0 0 0 / .6),
inset -3px -3px 8px oklch(1 0 0 / .05);The surface must be continuous. The original used #1a1a2e for the page and #1e1e35 for the nav, so the raised cards had visibly different backgrounds from their parent — the very mismatch its own gotchas warned about. Every surface here is bg-tsm09-bg; depth comes from shadow alone.
transition-[color,box-shadow] morphs smoothly between flat, raised and pressed.
Make it yours
- Softer depth: lower the blur radii in both shadow tokens (12px → 8px).
- Light neumorphism: set
--color-tsm09-bgto#e0e5ecand the shadow colours to white /oklch(0.7 0.03 260 / .6). - Glow on active: append
, 0 0 14px oklch(0.68 0.15 280 / .25)to--shadow-tsm09-in. - Accent: edit
--color-tsm09-acc; the active text, dot and focus ring follow.
Gotchas — read before shipping
- Neumorphic states have low contrast by nature — keep the visible focus ring and an
aria-currentcolour change, not shadow alone. - Never put a raised element on a different-coloured parent; the highlight shadow reveals the seam.
- Many animated box-shadows are paint-heavy; animate only interactive elements.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Multiple and inset box-shadow are universal; the floor is v4's own sheet.