15 / 23
All 23 in 23 Tailwind CSS Dark Mode UI
- 01Fix the Dark Mode Flash (FOUC) in Tailwind CSS with an Inline Head Script
- 02Tailwind CSS Dark Mode with prefers-color-scheme (System Theme)
- 03Tailwind Dark Mode Toggle with data-theme Attribute Override
- 04Tailwind v4 Dark Mode Design Tokens with color-mix()
- 05Tailwind CSS light-dark() Dark Mode Without Media Queries
- 06Tailwind Dark Mode Sidebar Navigation Component
- 07Tailwind Dark Mode Dashboard Cards with Sparklines
- 08Tailwind Dark Mode Modal Dialog with Blurred Backdrop
- 09Accessible Tailwind Dark Mode Login Form with Focus Rings
- 10Tailwind Three-State Theme Switcher (System / Light / Dark)
- 11Tailwind Dark Mode Code Editor UI with Syntax Highlighting
- 12Tailwind OLED True Black Dark Mode Product Card
- 13Minimalist Tailwind Dark Mode Settings Panel
- 14Tailwind Dark Mode Delete Confirmation Dialog (Editorial)
- 15Tailwind Terminal UI Component — Retro Dark Console
- 16Tailwind Warm Dark Mode Writing Editor (Mocha Theme)
- 17Tailwind Dark Mode Blog Article Reading Layout
- 18Tailwind Dark Mode Elevation Layers — Layered Surface Card
- 19Tailwind Dark Mode File Manager Table
- 20Tailwind Dark Mode Vertical Timeline Changelog
- 21Tailwind Glowing Button Dark Mode Countdown Card
- 22Tailwind Aurora Gradient Dark Hero Section
- 23Tailwind Dark Mode Alert Card — Payment Failed Notification
Tailwind Terminal UI Component — Retro Dark Console
A terminal with prompt history, streamed output and a live input line — phosphor green on black, a 3% scanline overlay and a blinking block caret. The retro reference is deliberate, the contrast is not: the green measures 13:1 on the substrate, dim output still clears 6:1, and warnings carry a glyph as well as amber. Output lines stream in on load with starting: and staggered delays — no script.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<div class="tdm-14 scheme-only-dark grid w-full min-h-svh place-items-center bg-tdm14-void bg-[radial-gradient(90%_70%_at_50%_0%,#08141a,transparent_70%)] px-4 py-12 font-tdm14-mono text-tdm14-ink antialiased">
<section aria-label="Terminal" class="relative w-full max-w-3xl overflow-hidden rounded-2xl border border-tdm14-hair bg-tdm14-panel shadow-[0_0_0_1px_rgb(0_0_0),0_40px_120px_-30px_var(--color-tdm14-glow)]">
<span aria-hidden="true" class="pointer-events-none absolute inset-0 z-10 bg-[repeating-linear-gradient(0deg,rgb(255_255_255/.03)_0_1px,transparent_1px_3px)]"></span>
<header class="flex items-center gap-3 border-b border-tdm14-hair bg-tdm14-bar px-4 py-3 text-xs">
<span class="flex gap-1.5" aria-hidden="true"><i class="size-3 rounded-full bg-tdm14-hair"></i><i class="size-3 rounded-full bg-tdm14-hair"></i><i class="size-3 rounded-full bg-tdm14-hair"></i></span>
<p class="flex-1 truncate text-center text-tdm14-dim">alex@meridian — ~/apps/web</p>
<span class="inline-flex items-center gap-2 rounded-full border border-tdm14-hair px-2.5 py-1 text-tdm14-phosphor"><span class="size-1.5 rounded-full bg-tdm14-phosphor shadow-[0_0_8px_var(--color-tdm14-phosphor)] animate-tdm14-pulse motion-reduce:animate-none" aria-hidden="true"></span>connected</span>
</header>
<div class="grid gap-1.5 px-5 py-5 text-[13.5px]/6 sm:px-6">
<p class="flex gap-3 text-tdm14-ink font-medium transition duration-500 ease-out delay-[0ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">$</span></span><span class="min-w-0 break-words">pnpm build --filter web</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[120ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Resolving 412 packages … done in 1.8s</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[240ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Compiled 96 routes with the edge runtime</span></p>
<p class="flex gap-3 text-tdm14-amber transition duration-500 ease-out delay-[360ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-amber">!</span></span><span class="min-w-0 break-words"><span class="sr-only">Warning: </span>theme.css: 3 selectors exceed specificity budget</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[480ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Bundle 184 kB gzip (−12 kB from main)</span></p>
<p class="flex gap-3 text-tdm14-phosphor transition duration-500 ease-out delay-[600ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">✓</span></span><span class="min-w-0 break-words">Build succeeded in 14.2s</span></p>
<p class="flex gap-3 text-tdm14-ink font-medium mt-3 transition duration-500 ease-out delay-[720ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">$</span></span><span class="min-w-0 break-words">node scripts/audit-contrast.mjs</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[840ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Checked 148 token pairs against WCAG AA</span></p>
<p class="flex gap-3 text-tdm14-phosphor transition duration-500 ease-out delay-[960ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">✓</span></span><span class="min-w-0 break-words">All pairs pass — lowest ratio 4.71:1</span></p>
</div>
<form onsubmit="return false" class="flex items-center gap-3 border-t border-tdm14-hair bg-tdm14-bar px-5 py-3 text-[13.5px] sm:px-6">
<label for="tdm-14-input" class="sr-only">Terminal command</label>
<span aria-hidden="true" class="text-tdm14-phosphor">$</span>
<input id="tdm-14-input" type="text" autocomplete="off" spellcheck="false" placeholder="git switch -c theme/tokens" class="min-h-11 flex-1 bg-transparent text-tdm14-ink caret-tdm14-phosphor outline-none [caret-shape:block] placeholder:text-tdm14-dim/70">
<kbd class="hidden rounded-md border border-tdm14-hair px-2 py-1 text-[11px] text-tdm14-dim sm:inline">⏎ run</kbd>
</form>
</section>
</div><div class="tdm-14 scheme-only-dark grid w-full min-h-svh place-items-center bg-tdm14-void bg-[radial-gradient(90%_70%_at_50%_0%,#08141a,transparent_70%)] px-4 py-12 font-tdm14-mono text-tdm14-ink antialiased">
<section aria-label="Terminal" class="relative w-full max-w-3xl overflow-hidden rounded-2xl border border-tdm14-hair bg-tdm14-panel shadow-[0_0_0_1px_rgb(0_0_0),0_40px_120px_-30px_var(--color-tdm14-glow)]">
<span aria-hidden="true" class="pointer-events-none absolute inset-0 z-10 bg-[repeating-linear-gradient(0deg,rgb(255_255_255/.03)_0_1px,transparent_1px_3px)]"></span>
<header class="flex items-center gap-3 border-b border-tdm14-hair bg-tdm14-bar px-4 py-3 text-xs">
<span class="flex gap-1.5" aria-hidden="true"><i class="size-3 rounded-full bg-tdm14-hair"></i><i class="size-3 rounded-full bg-tdm14-hair"></i><i class="size-3 rounded-full bg-tdm14-hair"></i></span>
<p class="flex-1 truncate text-center text-tdm14-dim">alex@meridian — ~/apps/web</p>
<span class="inline-flex items-center gap-2 rounded-full border border-tdm14-hair px-2.5 py-1 text-tdm14-phosphor"><span class="size-1.5 rounded-full bg-tdm14-phosphor shadow-[0_0_8px_var(--color-tdm14-phosphor)] animate-tdm14-pulse motion-reduce:animate-none" aria-hidden="true"></span>connected</span>
</header>
<div class="grid gap-1.5 px-5 py-5 text-[13.5px]/6 sm:px-6">
<p class="flex gap-3 text-tdm14-ink font-medium transition duration-500 ease-out delay-[0ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">$</span></span><span class="min-w-0 break-words">pnpm build --filter web</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[120ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Resolving 412 packages … done in 1.8s</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[240ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Compiled 96 routes with the edge runtime</span></p>
<p class="flex gap-3 text-tdm14-amber transition duration-500 ease-out delay-[360ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-amber">!</span></span><span class="min-w-0 break-words"><span class="sr-only">Warning: </span>theme.css: 3 selectors exceed specificity budget</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[480ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Bundle 184 kB gzip (−12 kB from main)</span></p>
<p class="flex gap-3 text-tdm14-phosphor transition duration-500 ease-out delay-[600ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">✓</span></span><span class="min-w-0 break-words">Build succeeded in 14.2s</span></p>
<p class="flex gap-3 text-tdm14-ink font-medium mt-3 transition duration-500 ease-out delay-[720ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">$</span></span><span class="min-w-0 break-words">node scripts/audit-contrast.mjs</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[840ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Checked 148 token pairs against WCAG AA</span></p>
<p class="flex gap-3 text-tdm14-phosphor transition duration-500 ease-out delay-[960ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">✓</span></span><span class="min-w-0 break-words">All pairs pass — lowest ratio 4.71:1</span></p>
</div>
<form onsubmit="return false" class="flex items-center gap-3 border-t border-tdm14-hair bg-tdm14-bar px-5 py-3 text-[13.5px] sm:px-6">
<label for="tdm-14-input" class="sr-only">Terminal command</label>
<span aria-hidden="true" class="text-tdm14-phosphor">$</span>
<input id="tdm-14-input" type="text" autocomplete="off" spellcheck="false" placeholder="git switch -c theme/tokens" class="min-h-11 flex-1 bg-transparent text-tdm14-ink caret-tdm14-phosphor outline-none [caret-shape:block] placeholder:text-tdm14-dim/70">
<kbd class="hidden rounded-md border border-tdm14-hair px-2 py-1 text-[11px] text-tdm14-dim sm:inline">⏎ run</kbd>
</form>
</section>
</div>@import "tailwindcss";
@theme {
--color-tdm14-void: #03050a;
--color-tdm14-panel: #070b0f;
--color-tdm14-bar: #0a1015;
--color-tdm14-hair: rgb(126 255 168 / .16);
--color-tdm14-phosphor: #7effa8;
--color-tdm14-dim: #93bba4;
--color-tdm14-amber: #ffc866;
--color-tdm14-ink: #dcffe8;
--color-tdm14-glow: rgb(126 255 168 / .16);
--font-tdm14-mono: 'JetBrains Mono', ui-monospace, monospace;
--animate-tdm14-pulse: tdm14-pulse 2.4s ease-in-out infinite;
@keyframes tdm14-pulse {
50% {
opacity: 0.35;
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is sized
in the moment before the browser build has compiled. */
.tdm-14 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tdm14-void: #03050a;
--color-tdm14-panel: #070b0f;
--color-tdm14-bar: #0a1015;
--color-tdm14-hair: rgb(126 255 168 / .16);
--color-tdm14-phosphor: #7effa8;
--color-tdm14-dim: #93bba4;
--color-tdm14-amber: #ffc866;
--color-tdm14-ink: #dcffe8;
--color-tdm14-glow: rgb(126 255 168 / .16);
--font-tdm14-mono: 'JetBrains Mono', ui-monospace, monospace;
--animate-tdm14-pulse: tdm14-pulse 2.4s ease-in-out infinite;
@keyframes tdm14-pulse {
50% {
opacity: 0.35;
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is sized
in the moment before the browser build has compiled. */
.tdm-14 {
width: 100%;
min-height: 100vh;
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-tdm14-void: #03050a;
--color-tdm14-panel: #070b0f;
--color-tdm14-bar: #0a1015;
--color-tdm14-hair: rgb(126 255 168 / .16);
--color-tdm14-phosphor: #7effa8;
--color-tdm14-dim: #93bba4;
--color-tdm14-amber: #ffc866;
--color-tdm14-ink: #dcffe8;
--color-tdm14-glow: rgb(126 255 168 / .16);
--font-tdm14-mono: 'JetBrains Mono', ui-monospace, monospace;
--animate-tdm14-pulse: tdm14-pulse 2.4s ease-in-out infinite;
@keyframes tdm14-pulse {
50% {
opacity: 0.35;
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is sized
in the moment before the browser build has compiled. */
.tdm-14 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tdm14-void: #03050a;
--color-tdm14-panel: #070b0f;
--color-tdm14-bar: #0a1015;
--color-tdm14-hair: rgb(126 255 168 / .16);
--color-tdm14-phosphor: #7effa8;
--color-tdm14-dim: #93bba4;
--color-tdm14-amber: #ffc866;
--color-tdm14-ink: #dcffe8;
--color-tdm14-glow: rgb(126 255 168 / .16);
--font-tdm14-mono: 'JetBrains Mono', ui-monospace, monospace;
--animate-tdm14-pulse: tdm14-pulse 2.4s ease-in-out infinite;
@keyframes tdm14-pulse {
50% {
opacity: 0.35;
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is sized
in the moment before the browser build has compiled. */
.tdm-14 {
width: 100%;
min-height: 100vh;
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=JetBrains+Mono:wght@400;500;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=JetBrains+Mono:wght@400;500;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The
::beforescanline rule became anaria-hiddenoverlay span with an arbitraryrepeating-linear-gradient— visible in the markup, removable in one deletion. - Per-type line classes (
.line--cmd/--warn/--ok) collapsed into one generated class list keyed by type. - UI upgrade from the CSS original: output now streams in on load via
starting:+ staggered delays, warnings announce a hidden "Warning:" prefix, and the fake caret span was replaced by a real phosphor caret on the input. - UI upgrade: a pulsing connection dot, a ⏎ run hint, a 44px input line, and dim output lifted to
#93bba4(8.9: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 Terminal UI Component — Retro Dark Console
Source: https://codefronts.com/design-styles/tailwind-css-dark-mode-ui/tailwind-terminal-ui-component/
A terminal with prompt history, streamed output and a live input line — phosphor green on black, a 3% scanline overlay and a blinking block caret. The retro reference is deliberate, the contrast is not: the green measures 13:1 on the substrate, dim output still clears 6:1, and warnings carry a glyph as well as amber. Output lines stream in on load with starting: and staggered delays — no script.
## HTML
```html
<div class="tdm-14 scheme-only-dark grid w-full min-h-svh place-items-center bg-tdm14-void bg-[radial-gradient(90%_70%_at_50%_0%,#08141a,transparent_70%)] px-4 py-12 font-tdm14-mono text-tdm14-ink antialiased">
<section aria-label="Terminal" class="relative w-full max-w-3xl overflow-hidden rounded-2xl border border-tdm14-hair bg-tdm14-panel shadow-[0_0_0_1px_rgb(0_0_0),0_40px_120px_-30px_var(--color-tdm14-glow)]">
<span aria-hidden="true" class="pointer-events-none absolute inset-0 z-10 bg-[repeating-linear-gradient(0deg,rgb(255_255_255/.03)_0_1px,transparent_1px_3px)]"></span>
<header class="flex items-center gap-3 border-b border-tdm14-hair bg-tdm14-bar px-4 py-3 text-xs">
<span class="flex gap-1.5" aria-hidden="true"><i class="size-3 rounded-full bg-tdm14-hair"></i><i class="size-3 rounded-full bg-tdm14-hair"></i><i class="size-3 rounded-full bg-tdm14-hair"></i></span>
<p class="flex-1 truncate text-center text-tdm14-dim">alex@meridian — ~/apps/web</p>
<span class="inline-flex items-center gap-2 rounded-full border border-tdm14-hair px-2.5 py-1 text-tdm14-phosphor"><span class="size-1.5 rounded-full bg-tdm14-phosphor shadow-[0_0_8px_var(--color-tdm14-phosphor)] animate-tdm14-pulse motion-reduce:animate-none" aria-hidden="true"></span>connected</span>
</header>
<div class="grid gap-1.5 px-5 py-5 text-[13.5px]/6 sm:px-6">
<p class="flex gap-3 text-tdm14-ink font-medium transition duration-500 ease-out delay-[0ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">$</span></span><span class="min-w-0 break-words">pnpm build --filter web</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[120ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Resolving 412 packages … done in 1.8s</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[240ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Compiled 96 routes with the edge runtime</span></p>
<p class="flex gap-3 text-tdm14-amber transition duration-500 ease-out delay-[360ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-amber">!</span></span><span class="min-w-0 break-words"><span class="sr-only">Warning: </span>theme.css: 3 selectors exceed specificity budget</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[480ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Bundle 184 kB gzip (−12 kB from main)</span></p>
<p class="flex gap-3 text-tdm14-phosphor transition duration-500 ease-out delay-[600ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">✓</span></span><span class="min-w-0 break-words">Build succeeded in 14.2s</span></p>
<p class="flex gap-3 text-tdm14-ink font-medium mt-3 transition duration-500 ease-out delay-[720ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">$</span></span><span class="min-w-0 break-words">node scripts/audit-contrast.mjs</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[840ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Checked 148 token pairs against WCAG AA</span></p>
<p class="flex gap-3 text-tdm14-phosphor transition duration-500 ease-out delay-[960ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">✓</span></span><span class="min-w-0 break-words">All pairs pass — lowest ratio 4.71:1</span></p>
</div>
<form onsubmit="return false" class="flex items-center gap-3 border-t border-tdm14-hair bg-tdm14-bar px-5 py-3 text-[13.5px] sm:px-6">
<label for="tdm-14-input" class="sr-only">Terminal command</label>
<span aria-hidden="true" class="text-tdm14-phosphor">$</span>
<input id="tdm-14-input" type="text" autocomplete="off" spellcheck="false" placeholder="git switch -c theme/tokens" class="min-h-11 flex-1 bg-transparent text-tdm14-ink caret-tdm14-phosphor outline-none [caret-shape:block] placeholder:text-tdm14-dim/70">
<kbd class="hidden rounded-md border border-tdm14-hair px-2 py-1 text-[11px] text-tdm14-dim sm:inline">⏎ run</kbd>
</form>
</section>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tdm14-void: #03050a;
--color-tdm14-panel: #070b0f;
--color-tdm14-bar: #0a1015;
--color-tdm14-hair: rgb(126 255 168 / .16);
--color-tdm14-phosphor: #7effa8;
--color-tdm14-dim: #93bba4;
--color-tdm14-amber: #ffc866;
--color-tdm14-ink: #dcffe8;
--color-tdm14-glow: rgb(126 255 168 / .16);
--font-tdm14-mono: 'JetBrains Mono', ui-monospace, monospace;
--animate-tdm14-pulse: tdm14-pulse 2.4s ease-in-out infinite;
@keyframes tdm14-pulse {
50% {
opacity: 0.35;
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is sized
in the moment before the browser build has compiled. */
.tdm-14 {
width: 100%;
min-height: 100vh;
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 Terminal UI Component — Retro Dark Console
Source: https://codefronts.com/design-styles/tailwind-css-dark-mode-ui/tailwind-terminal-ui-component/
A terminal with prompt history, streamed output and a live input line — phosphor green on black, a 3% scanline overlay and a blinking block caret. The retro reference is deliberate, the contrast is not: the green measures 13:1 on the substrate, dim output still clears 6:1, and warnings carry a glyph as well as amber. Output lines stream in on load with starting: and staggered delays — no script.
## HTML
```html
<div class="tdm-14 scheme-only-dark grid w-full min-h-svh place-items-center bg-tdm14-void bg-[radial-gradient(90%_70%_at_50%_0%,#08141a,transparent_70%)] px-4 py-12 font-tdm14-mono text-tdm14-ink antialiased">
<section aria-label="Terminal" class="relative w-full max-w-3xl overflow-hidden rounded-2xl border border-tdm14-hair bg-tdm14-panel shadow-[0_0_0_1px_rgb(0_0_0),0_40px_120px_-30px_var(--color-tdm14-glow)]">
<span aria-hidden="true" class="pointer-events-none absolute inset-0 z-10 bg-[repeating-linear-gradient(0deg,rgb(255_255_255/.03)_0_1px,transparent_1px_3px)]"></span>
<header class="flex items-center gap-3 border-b border-tdm14-hair bg-tdm14-bar px-4 py-3 text-xs">
<span class="flex gap-1.5" aria-hidden="true"><i class="size-3 rounded-full bg-tdm14-hair"></i><i class="size-3 rounded-full bg-tdm14-hair"></i><i class="size-3 rounded-full bg-tdm14-hair"></i></span>
<p class="flex-1 truncate text-center text-tdm14-dim">alex@meridian — ~/apps/web</p>
<span class="inline-flex items-center gap-2 rounded-full border border-tdm14-hair px-2.5 py-1 text-tdm14-phosphor"><span class="size-1.5 rounded-full bg-tdm14-phosphor shadow-[0_0_8px_var(--color-tdm14-phosphor)] animate-tdm14-pulse motion-reduce:animate-none" aria-hidden="true"></span>connected</span>
</header>
<div class="grid gap-1.5 px-5 py-5 text-[13.5px]/6 sm:px-6">
<p class="flex gap-3 text-tdm14-ink font-medium transition duration-500 ease-out delay-[0ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">$</span></span><span class="min-w-0 break-words">pnpm build --filter web</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[120ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Resolving 412 packages … done in 1.8s</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[240ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Compiled 96 routes with the edge runtime</span></p>
<p class="flex gap-3 text-tdm14-amber transition duration-500 ease-out delay-[360ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-amber">!</span></span><span class="min-w-0 break-words"><span class="sr-only">Warning: </span>theme.css: 3 selectors exceed specificity budget</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[480ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Bundle 184 kB gzip (−12 kB from main)</span></p>
<p class="flex gap-3 text-tdm14-phosphor transition duration-500 ease-out delay-[600ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">✓</span></span><span class="min-w-0 break-words">Build succeeded in 14.2s</span></p>
<p class="flex gap-3 text-tdm14-ink font-medium mt-3 transition duration-500 ease-out delay-[720ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">$</span></span><span class="min-w-0 break-words">node scripts/audit-contrast.mjs</span></p>
<p class="flex gap-3 text-tdm14-dim transition duration-500 ease-out delay-[840ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-dim">·</span></span><span class="min-w-0 break-words">Checked 148 token pairs against WCAG AA</span></p>
<p class="flex gap-3 text-tdm14-phosphor transition duration-500 ease-out delay-[960ms] starting:translate-y-1 starting:opacity-0 motion-reduce:transition-none"><span aria-hidden="true" class="w-3 flex-none text-center"><span class="text-tdm14-phosphor">✓</span></span><span class="min-w-0 break-words">All pairs pass — lowest ratio 4.71:1</span></p>
</div>
<form onsubmit="return false" class="flex items-center gap-3 border-t border-tdm14-hair bg-tdm14-bar px-5 py-3 text-[13.5px] sm:px-6">
<label for="tdm-14-input" class="sr-only">Terminal command</label>
<span aria-hidden="true" class="text-tdm14-phosphor">$</span>
<input id="tdm-14-input" type="text" autocomplete="off" spellcheck="false" placeholder="git switch -c theme/tokens" class="min-h-11 flex-1 bg-transparent text-tdm14-ink caret-tdm14-phosphor outline-none [caret-shape:block] placeholder:text-tdm14-dim/70">
<kbd class="hidden rounded-md border border-tdm14-hair px-2 py-1 text-[11px] text-tdm14-dim sm:inline">⏎ run</kbd>
</form>
</section>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tdm14-void: #03050a;
--color-tdm14-panel: #070b0f;
--color-tdm14-bar: #0a1015;
--color-tdm14-hair: rgb(126 255 168 / .16);
--color-tdm14-phosphor: #7effa8;
--color-tdm14-dim: #93bba4;
--color-tdm14-amber: #ffc866;
--color-tdm14-ink: #dcffe8;
--color-tdm14-glow: rgb(126 255 168 / .16);
--font-tdm14-mono: 'JetBrains Mono', ui-monospace, monospace;
--animate-tdm14-pulse: tdm14-pulse 2.4s ease-in-out infinite;
@keyframes tdm14-pulse {
50% {
opacity: 0.35;
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is sized
in the moment before the browser build has compiled. */
.tdm-14 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
}
```How this works
Entry animation without a timeline. Each output line has a transition and a starting style; the browser animates from @starting-style to the resting state on first render:
<p class="transition duration-500 delay-[480ms]
starting:opacity-0 starting:translate-y-1">Delays step by 120ms per line, so the build log appears to stream. Under motion-reduce: the transition is removed and every line is simply there.
Scanlines as an overlay. A pointer-events-none span with a 3px repeating gradient sits above the text at 3% opacity — strong enough to read as CRT, weak enough to cost no contrast.
Make it yours
- Amber terminal: swap
--color-tdm14-phosphorto#ffb000anddimto#c99a4a. - Remove the scanline span for a clean modern terminal.
- Speed the stream by shortening the per-line delay step from 120ms.
Gotchas — read before shipping
caret-shapeis Chromium-only today; elsewhere you get a phosphor-coloured bar caret.@starting-styleruns once per element insertion — re-rendering a framework list will replay it, which is usually what you want.- Keep the prompt glyph
aria-hidden; the input has a real (visually hidden) label.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 117+ | 17.5+ | 129+ | 117+ |
@starting-style sets the floor; older engines show the final state with no stream.