16 / 47
All 47 in 47 Tailwind CSS Toggles & Switches
- 01Tailwind iOS-Style Toggle Switch with appearance-none
- 02Tailwind Dark Mode Sun / Moon Theme Switcher
- 03Tailwind Neumorphic Soft-UI Pill Toggle
- 04Tailwind Gooey Liquid Morphing Switch with SVG Filter
- 05Tailwind Bouncy Elastic Physics Toggle (Overshoot Cubic-Bezier)
- 06Tailwind ON / OFF Text Switch with Labels Inside the Track
- 07Tailwind SaaS Pricing Toggle — Monthly / Annually Segmented Pill
- 08Tailwind Mechanical Keycap Toggles with Haptic Feedback
- 09Tailwind Waveform Mute Toggle with Animated EQ Bars
- 10Tailwind Timed Auto-Off Toggle with Conic Countdown Ring
- 11Tailwind Press-and-Hold to Confirm Toggle (Fingerprint Scan)
- 12Tailwind Split-Flap Departure Board Toggle (3D Flip)
- 13Tailwind Permission Toggle Group with :has() Live Status Badge
- 14Tailwind Material Design 3 Switch with State Layer
- 15Tailwind Skeuomorphic Wall Light Switch with Room Relight
- 16Tailwind Neon Cyberpunk Toggle with Clipped Corners
- 17Tailwind Brutalist Snap Toggle with Hard Offset Shadow
- 18Tailwind Day / Night Landscape Scene Switch
- 19Tailwind 3D Flip Card Toggle (rotateY Switch)
- 20Tailwind Sliding Pill Toggle with Label Inside the Thumb
- 21Tailwind Glassmorphism Frosted Toggle with backdrop-blur
- 22Tailwind Rotary Knob Toggle with Brushed-Metal Conic Gradient
- 23Tailwind iOS Settings List with Grouped Toggle Rows
- 24Tailwind Minimal Outline Toggle Drawn in currentColor
- 25Tailwind Squash-and-Stretch Pebble Toggle
- 26Tailwind Industrial Rocker I/O Power Switch
- 27Tailwind Accessible role=switch Toggle with forced-colors Support
- 28Tailwind Macro-Pad Toggle Grid with RGB Underglow
- 29Tailwind Radial VU Meter Mute Toggle
- 30Tailwind Segmented Pip Countdown Auto-Off Toggle
- 31Tailwind Slide-to-Confirm Toggle Rail (Drag or Arrow Keys)
- 32Tailwind Odometer Roll ON / OFF Toggle
- 33Tailwind Master Toggle with Indeterminate Tri-State
- 34Tailwind iOS Control Centre Tile Toggles
- 35Tailwind Material 3 Connected Icon Toggle Buttons
- 36Tailwind Two-Gang Wall Plate with Cumulative Room Light
- 37Tailwind Neon Toggle with Animated Conic Border Light
- 38Tailwind Brutalist Rubber-Stamp Toggle
- 39Tailwind Aurora Night Sky Toggle Switch
- 40Tailwind 3D Rotating Cube Toggle
- 41Tailwind Three-Position Off / Auto / On Selector
- 42Tailwind Liquid Glass Toggle with Specular Highlight
- 43Tailwind Three-Detent Rotary Selector Knob
- 44Tailwind Hardware Slide Switch with Knurled Grip
- 45Tailwind Battery Saver Toggle with Live Fill Meter
- 46Tailwind Morphing Sun-to-Moon Icon Toggle (SVG Stroke)
- 47Tailwind Guarded Kill Switch Under a Flip-Up Safety Cover
Tailwind Neon Cyberpunk Toggle with Clipped Corners
A clipped-corner neon tube for dark dashboards and game UIs: magenta standby snaps to cyan on engage, and the LIVE legend strikes like a gas tube warming up. Every glow is layered box-shadow and text-shadow — no images, no filters.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="ttg-16 w-full min-h-svh flex flex-col items-center justify-center gap-8 px-5 py-14 bg-ttg16-bg font-ttg16-mono" aria-label="Neon cyberpunk toggle">
<label for="ttg-16-sw" class="flex items-center gap-6 px-7 py-5 cursor-pointer bg-ttg16-panel [clip-path:polygon(10px_0,100%_0,100%_calc(100%-10px),calc(100%-10px)_100%,0_100%,0_10px)] has-checked:[&_.ttg16-stby]:opacity-0 has-checked:[&_.ttg16-live]:opacity-100 has-checked:[&_.ttg16-live]:animate-ttg16-strike motion-reduce:has-checked:[&_.ttg16-live]:animate-none">
<span aria-hidden="true" class="text-[14px] font-bold tracking-[0.3em] text-ttg16-dim">PWR</span>
<span class="relative w-23 h-10 bg-ttg16-tube border border-ttg16-standby transition-[border-color,box-shadow] duration-300 shadow-[0_0_1px_var(--color-ttg16-standby),inset_0_0_10px_color-mix(in_oklab,var(--color-ttg16-standby)_25%,transparent)] [clip-path:polygon(8px_0,100%_0,100%_calc(100%-8px),calc(100%-8px)_100%,0_100%,0_8px)] has-checked:border-ttg16-live has-checked:shadow-[0_0_1px_var(--color-ttg16-live),inset_0_0_12px_color-mix(in_oklab,var(--color-ttg16-live)_30%,transparent)] has-checked:[&_.ttg16-thumb]:translate-x-[50px] has-checked:[&_.ttg16-thumb]:bg-ttg16-live has-checked:[&_.ttg16-thumb]:shadow-[0_0_10px_var(--color-ttg16-live)]">
<input type="checkbox" id="ttg-16-sw" role="switch" aria-label="Power" class="appearance-none absolute inset-0 w-full h-full z-10 bg-transparent cursor-pointer focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-[6px]">
<span aria-hidden="true" class="ttg16-thumb pointer-events-none absolute top-1.5 left-1.5 w-7 h-6.5 bg-ttg16-standby shadow-[0_0_8px_var(--color-ttg16-standby)] transition-[transform,background-color,box-shadow] duration-300 ease-[cubic-bezier(0.6,0,0.3,1.2)] [clip-path:polygon(5px_0,100%_0,100%_calc(100%-5px),calc(100%-5px)_100%,0_100%,0_5px)] motion-reduce:duration-150"></span>
</span>
<span aria-hidden="true" class="relative w-13 h-[18px] text-[13px] font-bold tracking-[0.18em]">
<i class="ttg16-stby absolute inset-0 not-italic transition-opacity duration-250 text-ttg16-standby [text-shadow:0_0_6px_var(--color-ttg16-standby),0_0_16px_color-mix(in_oklab,var(--color-ttg16-standby)_55%,transparent)]">STBY</i>
<i class="ttg16-live absolute inset-0 not-italic opacity-0 transition-opacity duration-250 text-ttg16-live [text-shadow:0_0_6px_var(--color-ttg16-live),0_0_16px_color-mix(in_oklab,var(--color-ttg16-live)_55%,transparent)]">LIVE</i>
</span>
</label>
<p class="text-[11px] tracking-[0.2em] uppercase text-ttg16-dim">Magenta standby → cyan engage</p>
</section><section class="ttg-16 w-full min-h-svh flex flex-col items-center justify-center gap-8 px-5 py-14 bg-ttg16-bg font-ttg16-mono" aria-label="Neon cyberpunk toggle">
<label for="ttg-16-sw" class="flex items-center gap-6 px-7 py-5 cursor-pointer bg-ttg16-panel [clip-path:polygon(10px_0,100%_0,100%_calc(100%-10px),calc(100%-10px)_100%,0_100%,0_10px)] has-checked:[&_.ttg16-stby]:opacity-0 has-checked:[&_.ttg16-live]:opacity-100 has-checked:[&_.ttg16-live]:animate-ttg16-strike motion-reduce:has-checked:[&_.ttg16-live]:animate-none">
<span aria-hidden="true" class="text-[14px] font-bold tracking-[0.3em] text-ttg16-dim">PWR</span>
<span class="relative w-23 h-10 bg-ttg16-tube border border-ttg16-standby transition-[border-color,box-shadow] duration-300 shadow-[0_0_1px_var(--color-ttg16-standby),inset_0_0_10px_color-mix(in_oklab,var(--color-ttg16-standby)_25%,transparent)] [clip-path:polygon(8px_0,100%_0,100%_calc(100%-8px),calc(100%-8px)_100%,0_100%,0_8px)] has-checked:border-ttg16-live has-checked:shadow-[0_0_1px_var(--color-ttg16-live),inset_0_0_12px_color-mix(in_oklab,var(--color-ttg16-live)_30%,transparent)] has-checked:[&_.ttg16-thumb]:translate-x-[50px] has-checked:[&_.ttg16-thumb]:bg-ttg16-live has-checked:[&_.ttg16-thumb]:shadow-[0_0_10px_var(--color-ttg16-live)]">
<input type="checkbox" id="ttg-16-sw" role="switch" aria-label="Power" class="appearance-none absolute inset-0 w-full h-full z-10 bg-transparent cursor-pointer focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-[6px]">
<span aria-hidden="true" class="ttg16-thumb pointer-events-none absolute top-1.5 left-1.5 w-7 h-6.5 bg-ttg16-standby shadow-[0_0_8px_var(--color-ttg16-standby)] transition-[transform,background-color,box-shadow] duration-300 ease-[cubic-bezier(0.6,0,0.3,1.2)] [clip-path:polygon(5px_0,100%_0,100%_calc(100%-5px),calc(100%-5px)_100%,0_100%,0_5px)] motion-reduce:duration-150"></span>
</span>
<span aria-hidden="true" class="relative w-13 h-[18px] text-[13px] font-bold tracking-[0.18em]">
<i class="ttg16-stby absolute inset-0 not-italic transition-opacity duration-250 text-ttg16-standby [text-shadow:0_0_6px_var(--color-ttg16-standby),0_0_16px_color-mix(in_oklab,var(--color-ttg16-standby)_55%,transparent)]">STBY</i>
<i class="ttg16-live absolute inset-0 not-italic opacity-0 transition-opacity duration-250 text-ttg16-live [text-shadow:0_0_6px_var(--color-ttg16-live),0_0_16px_color-mix(in_oklab,var(--color-ttg16-live)_55%,transparent)]">LIVE</i>
</span>
</label>
<p class="text-[11px] tracking-[0.2em] uppercase text-ttg16-dim">Magenta standby → cyan engage</p>
</section>@import "tailwindcss";
@theme {
--color-ttg16-bg: #09070f;
--color-ttg16-bg: oklch(0.14 0.02 300);
--color-ttg16-panel: #130f1f;
--color-ttg16-panel: oklch(0.19 0.03 300);
--color-ttg16-tube: #0c0a15;
--color-ttg16-tube: oklch(0.16 0.025 300);
--color-ttg16-standby: #ff5fd0;
--color-ttg16-standby: oklch(0.74 0.23 340);
--color-ttg16-live: #5fe4ff;
--color-ttg16-live: oklch(0.85 0.14 200);
--color-ttg16-dim: #7b7395;
--color-ttg16-dim: oklch(0.58 0.04 300);
--font-ttg16-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
--animate-ttg16-strike: ttg16-strike 0.5s steps(1, end);
}
@keyframes ttg16-strike {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
30% {
opacity: 0.2;
}
45% {
opacity: 1;
}
55% {
opacity: 0.4;
}
70% {
opacity: 1;
}
}
.ttg-16 {
width: 100%;
min-height: 100svh;
}
.ttg-16 input[type="checkbox"] {
-webkit-appearance: none;
}@import "tailwindcss";
@theme {
--color-ttg16-bg: #09070f;
--color-ttg16-bg: oklch(0.14 0.02 300);
--color-ttg16-panel: #130f1f;
--color-ttg16-panel: oklch(0.19 0.03 300);
--color-ttg16-tube: #0c0a15;
--color-ttg16-tube: oklch(0.16 0.025 300);
--color-ttg16-standby: #ff5fd0;
--color-ttg16-standby: oklch(0.74 0.23 340);
--color-ttg16-live: #5fe4ff;
--color-ttg16-live: oklch(0.85 0.14 200);
--color-ttg16-dim: #7b7395;
--color-ttg16-dim: oklch(0.58 0.04 300);
--font-ttg16-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
--animate-ttg16-strike: ttg16-strike 0.5s steps(1, end);
}
@keyframes ttg16-strike {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
30% {
opacity: 0.2;
}
45% {
opacity: 1;
}
55% {
opacity: 0.4;
}
70% {
opacity: 1;
}
}
.ttg-16 {
width: 100%;
min-height: 100svh;
}
.ttg-16 input[type="checkbox"] {
-webkit-appearance: none;
}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-ttg16-bg: #09070f;
--color-ttg16-bg: oklch(0.14 0.02 300);
--color-ttg16-panel: #130f1f;
--color-ttg16-panel: oklch(0.19 0.03 300);
--color-ttg16-tube: #0c0a15;
--color-ttg16-tube: oklch(0.16 0.025 300);
--color-ttg16-standby: #ff5fd0;
--color-ttg16-standby: oklch(0.74 0.23 340);
--color-ttg16-live: #5fe4ff;
--color-ttg16-live: oklch(0.85 0.14 200);
--color-ttg16-dim: #7b7395;
--color-ttg16-dim: oklch(0.58 0.04 300);
--font-ttg16-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
--animate-ttg16-strike: ttg16-strike 0.5s steps(1, end);
}
@keyframes ttg16-strike {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
30% {
opacity: 0.2;
}
45% {
opacity: 1;
}
55% {
opacity: 0.4;
}
70% {
opacity: 1;
}
}
.ttg-16 {
width: 100%;
min-height: 100svh;
}
.ttg-16 input[type="checkbox"] {
-webkit-appearance: none;
}@import "tailwindcss";
@theme {
--color-ttg16-bg: #09070f;
--color-ttg16-bg: oklch(0.14 0.02 300);
--color-ttg16-panel: #130f1f;
--color-ttg16-panel: oklch(0.19 0.03 300);
--color-ttg16-tube: #0c0a15;
--color-ttg16-tube: oklch(0.16 0.025 300);
--color-ttg16-standby: #ff5fd0;
--color-ttg16-standby: oklch(0.74 0.23 340);
--color-ttg16-live: #5fe4ff;
--color-ttg16-live: oklch(0.85 0.14 200);
--color-ttg16-dim: #7b7395;
--color-ttg16-dim: oklch(0.58 0.04 300);
--font-ttg16-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
--animate-ttg16-strike: ttg16-strike 0.5s steps(1, end);
}
@keyframes ttg16-strike {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
30% {
opacity: 0.2;
}
45% {
opacity: 1;
}
55% {
opacity: 0.4;
}
70% {
opacity: 1;
}
}
.ttg-16 {
width: 100%;
min-height: 100svh;
}
.ttg-16 input[type="checkbox"] {
-webkit-appearance: none;
}<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;800&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;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The glow trio reads
var(--color-ttg16-standby)directly inside arbitrary shadow values rather than being duplicated as literals, so a rehue is a one-line change in@theme— the same discipline as demo 03, applied to light instead of shade. - Both clip-paths stay arbitrary properties. A chamfer is geometry, not a design-scale value, and minting a
clip-chamferutility would hide the corner size from the element that has it. has-checked:appears on two ancestors here (the label and the tube) because two different scopes react — the legend swap and the tube rehue. That is the correct shape: each container states what it does when something inside it is on.- UI change from the CSS original: the 'PWR' and caption inks lifted from
#4c4761/#3f3a52tooklch(0.58 0.04 300), taking them from 2.1:1 (invisible) to 5.4:1, and both neons were pushed lighter so the legends clear 7:1 on the panel rather than relying on their own bloom to be legible.
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 Neon Cyberpunk Toggle with Clipped Corners
Source: https://codefronts.com/components/tailwind-css-toggles-switches/tailwind-neon-cyberpunk-toggle-clipped-corners/
A clipped-corner neon tube for dark dashboards and game UIs: magenta standby snaps to cyan on engage, and the LIVE legend strikes like a gas tube warming up. Every glow is layered box-shadow and text-shadow — no images, no filters.
## HTML
```html
<section class="ttg-16 w-full min-h-svh flex flex-col items-center justify-center gap-8 px-5 py-14 bg-ttg16-bg font-ttg16-mono" aria-label="Neon cyberpunk toggle">
<label for="ttg-16-sw" class="flex items-center gap-6 px-7 py-5 cursor-pointer bg-ttg16-panel [clip-path:polygon(10px_0,100%_0,100%_calc(100%-10px),calc(100%-10px)_100%,0_100%,0_10px)] has-checked:[&_.ttg16-stby]:opacity-0 has-checked:[&_.ttg16-live]:opacity-100 has-checked:[&_.ttg16-live]:animate-ttg16-strike motion-reduce:has-checked:[&_.ttg16-live]:animate-none">
<span aria-hidden="true" class="text-[14px] font-bold tracking-[0.3em] text-ttg16-dim">PWR</span>
<span class="relative w-23 h-10 bg-ttg16-tube border border-ttg16-standby transition-[border-color,box-shadow] duration-300 shadow-[0_0_1px_var(--color-ttg16-standby),inset_0_0_10px_color-mix(in_oklab,var(--color-ttg16-standby)_25%,transparent)] [clip-path:polygon(8px_0,100%_0,100%_calc(100%-8px),calc(100%-8px)_100%,0_100%,0_8px)] has-checked:border-ttg16-live has-checked:shadow-[0_0_1px_var(--color-ttg16-live),inset_0_0_12px_color-mix(in_oklab,var(--color-ttg16-live)_30%,transparent)] has-checked:[&_.ttg16-thumb]:translate-x-[50px] has-checked:[&_.ttg16-thumb]:bg-ttg16-live has-checked:[&_.ttg16-thumb]:shadow-[0_0_10px_var(--color-ttg16-live)]">
<input type="checkbox" id="ttg-16-sw" role="switch" aria-label="Power" class="appearance-none absolute inset-0 w-full h-full z-10 bg-transparent cursor-pointer focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-[6px]">
<span aria-hidden="true" class="ttg16-thumb pointer-events-none absolute top-1.5 left-1.5 w-7 h-6.5 bg-ttg16-standby shadow-[0_0_8px_var(--color-ttg16-standby)] transition-[transform,background-color,box-shadow] duration-300 ease-[cubic-bezier(0.6,0,0.3,1.2)] [clip-path:polygon(5px_0,100%_0,100%_calc(100%-5px),calc(100%-5px)_100%,0_100%,0_5px)] motion-reduce:duration-150"></span>
</span>
<span aria-hidden="true" class="relative w-13 h-[18px] text-[13px] font-bold tracking-[0.18em]">
<i class="ttg16-stby absolute inset-0 not-italic transition-opacity duration-250 text-ttg16-standby [text-shadow:0_0_6px_var(--color-ttg16-standby),0_0_16px_color-mix(in_oklab,var(--color-ttg16-standby)_55%,transparent)]">STBY</i>
<i class="ttg16-live absolute inset-0 not-italic opacity-0 transition-opacity duration-250 text-ttg16-live [text-shadow:0_0_6px_var(--color-ttg16-live),0_0_16px_color-mix(in_oklab,var(--color-ttg16-live)_55%,transparent)]">LIVE</i>
</span>
</label>
<p class="text-[11px] tracking-[0.2em] uppercase text-ttg16-dim">Magenta standby → cyan engage</p>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttg16-bg: #09070f;
--color-ttg16-bg: oklch(0.14 0.02 300);
--color-ttg16-panel: #130f1f;
--color-ttg16-panel: oklch(0.19 0.03 300);
--color-ttg16-tube: #0c0a15;
--color-ttg16-tube: oklch(0.16 0.025 300);
--color-ttg16-standby: #ff5fd0;
--color-ttg16-standby: oklch(0.74 0.23 340);
--color-ttg16-live: #5fe4ff;
--color-ttg16-live: oklch(0.85 0.14 200);
--color-ttg16-dim: #7b7395;
--color-ttg16-dim: oklch(0.58 0.04 300);
--font-ttg16-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
--animate-ttg16-strike: ttg16-strike 0.5s steps(1, end);
}
@keyframes ttg16-strike {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
30% {
opacity: 0.2;
}
45% {
opacity: 1;
}
55% {
opacity: 0.4;
}
70% {
opacity: 1;
}
}
.ttg-16 {
width: 100%;
min-height: 100svh;
}
.ttg-16 input[type="checkbox"] {
-webkit-appearance: none;
}
```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 Neon Cyberpunk Toggle with Clipped Corners
Source: https://codefronts.com/components/tailwind-css-toggles-switches/tailwind-neon-cyberpunk-toggle-clipped-corners/
A clipped-corner neon tube for dark dashboards and game UIs: magenta standby snaps to cyan on engage, and the LIVE legend strikes like a gas tube warming up. Every glow is layered box-shadow and text-shadow — no images, no filters.
## HTML
```html
<section class="ttg-16 w-full min-h-svh flex flex-col items-center justify-center gap-8 px-5 py-14 bg-ttg16-bg font-ttg16-mono" aria-label="Neon cyberpunk toggle">
<label for="ttg-16-sw" class="flex items-center gap-6 px-7 py-5 cursor-pointer bg-ttg16-panel [clip-path:polygon(10px_0,100%_0,100%_calc(100%-10px),calc(100%-10px)_100%,0_100%,0_10px)] has-checked:[&_.ttg16-stby]:opacity-0 has-checked:[&_.ttg16-live]:opacity-100 has-checked:[&_.ttg16-live]:animate-ttg16-strike motion-reduce:has-checked:[&_.ttg16-live]:animate-none">
<span aria-hidden="true" class="text-[14px] font-bold tracking-[0.3em] text-ttg16-dim">PWR</span>
<span class="relative w-23 h-10 bg-ttg16-tube border border-ttg16-standby transition-[border-color,box-shadow] duration-300 shadow-[0_0_1px_var(--color-ttg16-standby),inset_0_0_10px_color-mix(in_oklab,var(--color-ttg16-standby)_25%,transparent)] [clip-path:polygon(8px_0,100%_0,100%_calc(100%-8px),calc(100%-8px)_100%,0_100%,0_8px)] has-checked:border-ttg16-live has-checked:shadow-[0_0_1px_var(--color-ttg16-live),inset_0_0_12px_color-mix(in_oklab,var(--color-ttg16-live)_30%,transparent)] has-checked:[&_.ttg16-thumb]:translate-x-[50px] has-checked:[&_.ttg16-thumb]:bg-ttg16-live has-checked:[&_.ttg16-thumb]:shadow-[0_0_10px_var(--color-ttg16-live)]">
<input type="checkbox" id="ttg-16-sw" role="switch" aria-label="Power" class="appearance-none absolute inset-0 w-full h-full z-10 bg-transparent cursor-pointer focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-[6px]">
<span aria-hidden="true" class="ttg16-thumb pointer-events-none absolute top-1.5 left-1.5 w-7 h-6.5 bg-ttg16-standby shadow-[0_0_8px_var(--color-ttg16-standby)] transition-[transform,background-color,box-shadow] duration-300 ease-[cubic-bezier(0.6,0,0.3,1.2)] [clip-path:polygon(5px_0,100%_0,100%_calc(100%-5px),calc(100%-5px)_100%,0_100%,0_5px)] motion-reduce:duration-150"></span>
</span>
<span aria-hidden="true" class="relative w-13 h-[18px] text-[13px] font-bold tracking-[0.18em]">
<i class="ttg16-stby absolute inset-0 not-italic transition-opacity duration-250 text-ttg16-standby [text-shadow:0_0_6px_var(--color-ttg16-standby),0_0_16px_color-mix(in_oklab,var(--color-ttg16-standby)_55%,transparent)]">STBY</i>
<i class="ttg16-live absolute inset-0 not-italic opacity-0 transition-opacity duration-250 text-ttg16-live [text-shadow:0_0_6px_var(--color-ttg16-live),0_0_16px_color-mix(in_oklab,var(--color-ttg16-live)_55%,transparent)]">LIVE</i>
</span>
</label>
<p class="text-[11px] tracking-[0.2em] uppercase text-ttg16-dim">Magenta standby → cyan engage</p>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttg16-bg: #09070f;
--color-ttg16-bg: oklch(0.14 0.02 300);
--color-ttg16-panel: #130f1f;
--color-ttg16-panel: oklch(0.19 0.03 300);
--color-ttg16-tube: #0c0a15;
--color-ttg16-tube: oklch(0.16 0.025 300);
--color-ttg16-standby: #ff5fd0;
--color-ttg16-standby: oklch(0.74 0.23 340);
--color-ttg16-live: #5fe4ff;
--color-ttg16-live: oklch(0.85 0.14 200);
--color-ttg16-dim: #7b7395;
--color-ttg16-dim: oklch(0.58 0.04 300);
--font-ttg16-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
--animate-ttg16-strike: ttg16-strike 0.5s steps(1, end);
}
@keyframes ttg16-strike {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
30% {
opacity: 0.2;
}
45% {
opacity: 1;
}
55% {
opacity: 0.4;
}
70% {
opacity: 1;
}
}
.ttg-16 {
width: 100%;
min-height: 100svh;
}
.ttg-16 input[type="checkbox"] {
-webkit-appearance: none;
}
```How this works
Neon is three shadows of one hue. A 1px ring for the tube wall, an 8px bloom for the discharge, a 22px wash for the room. On text the same trio becomes text-shadow. Both read from one custom property, so engaging the switch swaps magenta for cyan everywhere by changing a single value rather than six utilities.
The flicker only fires on engage. A steps(1,end) opacity keyframe plays once when LIVE appears — on, off, on, off, on. Stepped timing is essential: a smoothly interpolated flicker looks like a fade, not a gas tube striking.
Strobing is a vestibular trigger. Under motion-reduce: the strike is removed entirely and LIVE simply appears. That is not a nicety; a 500ms strobe is exactly the pattern reduced-motion users are protecting themselves from.
Make it yours
- Rehue both states through
--color-ttg16-standbyand--color-ttg16-live— any oklch hue works, and the glows follow. - Deepen the chamfer from 10px to 16px in the two clip-paths for a harder sci-fi read.
- Short legends only: EN/GAGED, ARM/SAFE, PWR/OFF.
- Add a faint idle flicker by looping a 2% opacity dip every 4s — but leave it out of the reduced-motion path.
Gotchas — read before shipping
- Neon needs a dark ground. Above roughly 20% background lightness the bloom stops reading as glow and starts reading as blur.
clip-pathclipsbox-shadowtoo. The glow must live on an inner element, or on the same element's inset shadow — never as an outer shadow on the clipped box.- Use
steps()for the flicker and gate it behindmotion-reduce:. - Neon colours are saturated and light; keep body copy in a plain ink, because a glowing paragraph is unreadable at any contrast ratio.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
clip-path: polygon() and layered shadows are universal in modern browsers; :has() (Firefox 121+) drives the legend swap.