39 / 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 Aurora Night Sky Toggle Switch
A dark-mode switch with weather: flip it and three blurred aurora ribbons drift across a deep sky at different speeds while the horizon cools. Demo 18 moves objects; this one moves atmosphere, which is a different kind of quiet.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="ttg-39 relative overflow-hidden w-full min-h-svh grid place-items-center px-5 py-14 bg-ttg39-daysky font-ttg39-sans transition-colors duration-[900ms] has-checked:bg-ttg39-nightsky motion-reduce:transition-none" aria-label="Aurora night sky toggle">
<span aria-hidden="true" class="ttg39-aurora pointer-events-none absolute inset-x-0 top-0 h-2/3 opacity-0 transition-opacity duration-[900ms] -skew-y-[8deg] motion-reduce:transition-none">
<i class="absolute left-[-30%] top-[18%] w-[160%] h-20 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur1 to-transparent [animation:ttg39-drift_14s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
<i class="absolute left-[-30%] top-[34%] w-[160%] h-16 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur2 to-transparent [animation:ttg39-drift_19s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
<i class="absolute left-[-30%] top-[50%] w-[160%] h-24 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur3 to-transparent [animation:ttg39-drift_24s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
</span>
<span aria-hidden="true" class="ttg39-horizon pointer-events-none absolute inset-x-0 bottom-0 h-1/3 bg-linear-to-t from-ttg39-glow to-transparent transition-opacity duration-[900ms] motion-reduce:transition-none"></span>
<label for="ttg-39-sw" class="relative z-10 flex items-center gap-8 px-7 py-5 rounded-[22px] cursor-pointer bg-white/8 border border-white/15 backdrop-blur-xl">
<span class="flex flex-col gap-0.5">
<b class="text-[15.5px] font-semibold text-white">Night sky</b>
<span class="text-[12.5px] text-white/70">Dims the workspace and wakes the aurora</span>
</span>
<input type="checkbox" id="ttg-39-sw" role="switch" aria-label="Night sky" class="peer appearance-none shrink-0 w-[68px] h-9 rounded-full bg-white/20 relative cursor-pointer transition-colors duration-500 before:content-[''] before:absolute before:top-1 before:left-1 before:w-7 before:h-7 before:rounded-full before:bg-white before:shadow-[0_2px_8px_oklch(0_0_0/0.4)] before:transition-transform before:duration-500 before:ease-[cubic-bezier(0.3,1,0.35,1.05)] checked:bg-ttg39-aur1/60 checked:before:translate-x-8 focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-3 motion-reduce:transition-none motion-reduce:before:transition-none">
</label>
</section><section class="ttg-39 relative overflow-hidden w-full min-h-svh grid place-items-center px-5 py-14 bg-ttg39-daysky font-ttg39-sans transition-colors duration-[900ms] has-checked:bg-ttg39-nightsky motion-reduce:transition-none" aria-label="Aurora night sky toggle">
<span aria-hidden="true" class="ttg39-aurora pointer-events-none absolute inset-x-0 top-0 h-2/3 opacity-0 transition-opacity duration-[900ms] -skew-y-[8deg] motion-reduce:transition-none">
<i class="absolute left-[-30%] top-[18%] w-[160%] h-20 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur1 to-transparent [animation:ttg39-drift_14s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
<i class="absolute left-[-30%] top-[34%] w-[160%] h-16 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur2 to-transparent [animation:ttg39-drift_19s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
<i class="absolute left-[-30%] top-[50%] w-[160%] h-24 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur3 to-transparent [animation:ttg39-drift_24s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
</span>
<span aria-hidden="true" class="ttg39-horizon pointer-events-none absolute inset-x-0 bottom-0 h-1/3 bg-linear-to-t from-ttg39-glow to-transparent transition-opacity duration-[900ms] motion-reduce:transition-none"></span>
<label for="ttg-39-sw" class="relative z-10 flex items-center gap-8 px-7 py-5 rounded-[22px] cursor-pointer bg-white/8 border border-white/15 backdrop-blur-xl">
<span class="flex flex-col gap-0.5">
<b class="text-[15.5px] font-semibold text-white">Night sky</b>
<span class="text-[12.5px] text-white/70">Dims the workspace and wakes the aurora</span>
</span>
<input type="checkbox" id="ttg-39-sw" role="switch" aria-label="Night sky" class="peer appearance-none shrink-0 w-[68px] h-9 rounded-full bg-white/20 relative cursor-pointer transition-colors duration-500 before:content-[''] before:absolute before:top-1 before:left-1 before:w-7 before:h-7 before:rounded-full before:bg-white before:shadow-[0_2px_8px_oklch(0_0_0/0.4)] before:transition-transform before:duration-500 before:ease-[cubic-bezier(0.3,1,0.35,1.05)] checked:bg-ttg39-aur1/60 checked:before:translate-x-8 focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-3 motion-reduce:transition-none motion-reduce:before:transition-none">
</label>
</section>@import "tailwindcss";
@theme {
--color-ttg39-daysky: #2b3550;
--color-ttg39-daysky: oklch(0.36 0.05 265);
--color-ttg39-nightsky: #070b18;
--color-ttg39-nightsky: oklch(0.14 0.03 270);
--color-ttg39-aur1: #4ef0b0;
--color-ttg39-aur1: oklch(0.85 0.17 165);
--color-ttg39-aur2: #58c8f0;
--color-ttg39-aur2: oklch(0.8 0.13 215);
--color-ttg39-aur3: #9b7cf0;
--color-ttg39-aur3: oklch(0.7 0.16 290);
--color-ttg39-glow: #3d4a6e;
--color-ttg39-glow: oklch(0.42 0.06 265 / 0.7);
--font-ttg39-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
@keyframes ttg39-drift {
from {
transform: translateX(-6%) scaleY(1);
}
to {
transform: translateX(6%) scaleY(1.25);
}
}
.ttg-39 {
width: 100%;
min-height: 100svh;
}
.ttg-39 input[type="checkbox"] {
-webkit-appearance: none;
}
.ttg-39 label {
-webkit-backdrop-filter: blur(24px);
}
.ttg-39:has(:checked) .ttg39-aurora {
opacity: 1;
}
.ttg-39:has(:checked) .ttg39-horizon {
opacity: 0;
}@import "tailwindcss";
@theme {
--color-ttg39-daysky: #2b3550;
--color-ttg39-daysky: oklch(0.36 0.05 265);
--color-ttg39-nightsky: #070b18;
--color-ttg39-nightsky: oklch(0.14 0.03 270);
--color-ttg39-aur1: #4ef0b0;
--color-ttg39-aur1: oklch(0.85 0.17 165);
--color-ttg39-aur2: #58c8f0;
--color-ttg39-aur2: oklch(0.8 0.13 215);
--color-ttg39-aur3: #9b7cf0;
--color-ttg39-aur3: oklch(0.7 0.16 290);
--color-ttg39-glow: #3d4a6e;
--color-ttg39-glow: oklch(0.42 0.06 265 / 0.7);
--font-ttg39-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
@keyframes ttg39-drift {
from {
transform: translateX(-6%) scaleY(1);
}
to {
transform: translateX(6%) scaleY(1.25);
}
}
.ttg-39 {
width: 100%;
min-height: 100svh;
}
.ttg-39 input[type="checkbox"] {
-webkit-appearance: none;
}
.ttg-39 label {
-webkit-backdrop-filter: blur(24px);
}
.ttg-39:has(:checked) .ttg39-aurora {
opacity: 1;
}
.ttg-39:has(:checked) .ttg39-horizon {
opacity: 0;
}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-ttg39-daysky: #2b3550;
--color-ttg39-daysky: oklch(0.36 0.05 265);
--color-ttg39-nightsky: #070b18;
--color-ttg39-nightsky: oklch(0.14 0.03 270);
--color-ttg39-aur1: #4ef0b0;
--color-ttg39-aur1: oklch(0.85 0.17 165);
--color-ttg39-aur2: #58c8f0;
--color-ttg39-aur2: oklch(0.8 0.13 215);
--color-ttg39-aur3: #9b7cf0;
--color-ttg39-aur3: oklch(0.7 0.16 290);
--color-ttg39-glow: #3d4a6e;
--color-ttg39-glow: oklch(0.42 0.06 265 / 0.7);
--font-ttg39-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
@keyframes ttg39-drift {
from {
transform: translateX(-6%) scaleY(1);
}
to {
transform: translateX(6%) scaleY(1.25);
}
}
.ttg-39 {
width: 100%;
min-height: 100svh;
}
.ttg-39 input[type="checkbox"] {
-webkit-appearance: none;
}
.ttg-39 label {
-webkit-backdrop-filter: blur(24px);
}
.ttg-39:has(:checked) .ttg39-aurora {
opacity: 1;
}
.ttg-39:has(:checked) .ttg39-horizon {
opacity: 0;
}@import "tailwindcss";
@theme {
--color-ttg39-daysky: #2b3550;
--color-ttg39-daysky: oklch(0.36 0.05 265);
--color-ttg39-nightsky: #070b18;
--color-ttg39-nightsky: oklch(0.14 0.03 270);
--color-ttg39-aur1: #4ef0b0;
--color-ttg39-aur1: oklch(0.85 0.17 165);
--color-ttg39-aur2: #58c8f0;
--color-ttg39-aur2: oklch(0.8 0.13 215);
--color-ttg39-aur3: #9b7cf0;
--color-ttg39-aur3: oklch(0.7 0.16 290);
--color-ttg39-glow: #3d4a6e;
--color-ttg39-glow: oklch(0.42 0.06 265 / 0.7);
--font-ttg39-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
@keyframes ttg39-drift {
from {
transform: translateX(-6%) scaleY(1);
}
to {
transform: translateX(6%) scaleY(1.25);
}
}
.ttg-39 {
width: 100%;
min-height: 100svh;
}
.ttg-39 input[type="checkbox"] {
-webkit-appearance: none;
}
.ttg-39 label {
-webkit-backdrop-filter: blur(24px);
}
.ttg-39:has(:checked) .ttg39-aurora {
opacity: 1;
}
.ttg-39:has(:checked) .ttg39-horizon {
opacity: 0;
}<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=Plus+Jakarta+Sans: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=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Every ribbon writes its duration inside
[animation:ttg39-drift_14s_ease-in-out_infinite_alternate]rather than pairinganimate-*with a separate duration utility — the lesson demos 09 and 30 paid for, applied from the start. mix-blend-screenis what makes the crossings glow instead of muddying; it is one utility and it is the difference between aurora and three coloured smudges.- The
-skew-y-[8deg]on the ribbon container tilts all three at once, so they read as a curtain rather than as stripes — one utility on the parent instead of three on the children. - UI upgrade over demo 18: the scene is atmosphere rather than objects, which scales to any viewport instead of living in a 220px window, the control keeps solid-white copy on frosted glass at 11:1, and the switch's own on-tint reads from the same aurora token so the control belongs to the sky.
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 Aurora Night Sky Toggle Switch
Source: https://codefronts.com/components/tailwind-css-toggles-switches/tailwind-aurora-night-sky-toggle-switch/
A dark-mode switch with weather: flip it and three blurred aurora ribbons drift across a deep sky at different speeds while the horizon cools. Demo 18 moves objects; this one moves atmosphere, which is a different kind of quiet.
## HTML
```html
<section class="ttg-39 relative overflow-hidden w-full min-h-svh grid place-items-center px-5 py-14 bg-ttg39-daysky font-ttg39-sans transition-colors duration-[900ms] has-checked:bg-ttg39-nightsky motion-reduce:transition-none" aria-label="Aurora night sky toggle">
<span aria-hidden="true" class="ttg39-aurora pointer-events-none absolute inset-x-0 top-0 h-2/3 opacity-0 transition-opacity duration-[900ms] -skew-y-[8deg] motion-reduce:transition-none">
<i class="absolute left-[-30%] top-[18%] w-[160%] h-20 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur1 to-transparent [animation:ttg39-drift_14s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
<i class="absolute left-[-30%] top-[34%] w-[160%] h-16 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur2 to-transparent [animation:ttg39-drift_19s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
<i class="absolute left-[-30%] top-[50%] w-[160%] h-24 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur3 to-transparent [animation:ttg39-drift_24s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
</span>
<span aria-hidden="true" class="ttg39-horizon pointer-events-none absolute inset-x-0 bottom-0 h-1/3 bg-linear-to-t from-ttg39-glow to-transparent transition-opacity duration-[900ms] motion-reduce:transition-none"></span>
<label for="ttg-39-sw" class="relative z-10 flex items-center gap-8 px-7 py-5 rounded-[22px] cursor-pointer bg-white/8 border border-white/15 backdrop-blur-xl">
<span class="flex flex-col gap-0.5">
<b class="text-[15.5px] font-semibold text-white">Night sky</b>
<span class="text-[12.5px] text-white/70">Dims the workspace and wakes the aurora</span>
</span>
<input type="checkbox" id="ttg-39-sw" role="switch" aria-label="Night sky" class="peer appearance-none shrink-0 w-[68px] h-9 rounded-full bg-white/20 relative cursor-pointer transition-colors duration-500 before:content-[''] before:absolute before:top-1 before:left-1 before:w-7 before:h-7 before:rounded-full before:bg-white before:shadow-[0_2px_8px_oklch(0_0_0/0.4)] before:transition-transform before:duration-500 before:ease-[cubic-bezier(0.3,1,0.35,1.05)] checked:bg-ttg39-aur1/60 checked:before:translate-x-8 focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-3 motion-reduce:transition-none motion-reduce:before:transition-none">
</label>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttg39-daysky: #2b3550;
--color-ttg39-daysky: oklch(0.36 0.05 265);
--color-ttg39-nightsky: #070b18;
--color-ttg39-nightsky: oklch(0.14 0.03 270);
--color-ttg39-aur1: #4ef0b0;
--color-ttg39-aur1: oklch(0.85 0.17 165);
--color-ttg39-aur2: #58c8f0;
--color-ttg39-aur2: oklch(0.8 0.13 215);
--color-ttg39-aur3: #9b7cf0;
--color-ttg39-aur3: oklch(0.7 0.16 290);
--color-ttg39-glow: #3d4a6e;
--color-ttg39-glow: oklch(0.42 0.06 265 / 0.7);
--font-ttg39-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
@keyframes ttg39-drift {
from {
transform: translateX(-6%) scaleY(1);
}
to {
transform: translateX(6%) scaleY(1.25);
}
}
.ttg-39 {
width: 100%;
min-height: 100svh;
}
.ttg-39 input[type="checkbox"] {
-webkit-appearance: none;
}
.ttg-39 label {
-webkit-backdrop-filter: blur(24px);
}
.ttg-39:has(:checked) .ttg39-aurora {
opacity: 1;
}
.ttg-39:has(:checked) .ttg39-horizon {
opacity: 0;
}
```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 Aurora Night Sky Toggle Switch
Source: https://codefronts.com/components/tailwind-css-toggles-switches/tailwind-aurora-night-sky-toggle-switch/
A dark-mode switch with weather: flip it and three blurred aurora ribbons drift across a deep sky at different speeds while the horizon cools. Demo 18 moves objects; this one moves atmosphere, which is a different kind of quiet.
## HTML
```html
<section class="ttg-39 relative overflow-hidden w-full min-h-svh grid place-items-center px-5 py-14 bg-ttg39-daysky font-ttg39-sans transition-colors duration-[900ms] has-checked:bg-ttg39-nightsky motion-reduce:transition-none" aria-label="Aurora night sky toggle">
<span aria-hidden="true" class="ttg39-aurora pointer-events-none absolute inset-x-0 top-0 h-2/3 opacity-0 transition-opacity duration-[900ms] -skew-y-[8deg] motion-reduce:transition-none">
<i class="absolute left-[-30%] top-[18%] w-[160%] h-20 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur1 to-transparent [animation:ttg39-drift_14s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
<i class="absolute left-[-30%] top-[34%] w-[160%] h-16 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur2 to-transparent [animation:ttg39-drift_19s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
<i class="absolute left-[-30%] top-[50%] w-[160%] h-24 rounded-full blur-[42px] mix-blend-screen bg-linear-to-r from-transparent via-ttg39-aur3 to-transparent [animation:ttg39-drift_24s_ease-in-out_infinite_alternate] motion-reduce:[animation:none]"></i>
</span>
<span aria-hidden="true" class="ttg39-horizon pointer-events-none absolute inset-x-0 bottom-0 h-1/3 bg-linear-to-t from-ttg39-glow to-transparent transition-opacity duration-[900ms] motion-reduce:transition-none"></span>
<label for="ttg-39-sw" class="relative z-10 flex items-center gap-8 px-7 py-5 rounded-[22px] cursor-pointer bg-white/8 border border-white/15 backdrop-blur-xl">
<span class="flex flex-col gap-0.5">
<b class="text-[15.5px] font-semibold text-white">Night sky</b>
<span class="text-[12.5px] text-white/70">Dims the workspace and wakes the aurora</span>
</span>
<input type="checkbox" id="ttg-39-sw" role="switch" aria-label="Night sky" class="peer appearance-none shrink-0 w-[68px] h-9 rounded-full bg-white/20 relative cursor-pointer transition-colors duration-500 before:content-[''] before:absolute before:top-1 before:left-1 before:w-7 before:h-7 before:rounded-full before:bg-white before:shadow-[0_2px_8px_oklch(0_0_0/0.4)] before:transition-transform before:duration-500 before:ease-[cubic-bezier(0.3,1,0.35,1.05)] checked:bg-ttg39-aur1/60 checked:before:translate-x-8 focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-3 motion-reduce:transition-none motion-reduce:before:transition-none">
</label>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttg39-daysky: #2b3550;
--color-ttg39-daysky: oklch(0.36 0.05 265);
--color-ttg39-nightsky: #070b18;
--color-ttg39-nightsky: oklch(0.14 0.03 270);
--color-ttg39-aur1: #4ef0b0;
--color-ttg39-aur1: oklch(0.85 0.17 165);
--color-ttg39-aur2: #58c8f0;
--color-ttg39-aur2: oklch(0.8 0.13 215);
--color-ttg39-aur3: #9b7cf0;
--color-ttg39-aur3: oklch(0.7 0.16 290);
--color-ttg39-glow: #3d4a6e;
--color-ttg39-glow: oklch(0.42 0.06 265 / 0.7);
--font-ttg39-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
@keyframes ttg39-drift {
from {
transform: translateX(-6%) scaleY(1);
}
to {
transform: translateX(6%) scaleY(1.25);
}
}
.ttg-39 {
width: 100%;
min-height: 100svh;
}
.ttg-39 input[type="checkbox"] {
-webkit-appearance: none;
}
.ttg-39 label {
-webkit-backdrop-filter: blur(24px);
}
.ttg-39:has(:checked) .ttg39-aurora {
opacity: 1;
}
.ttg-39:has(:checked) .ttg39-horizon {
opacity: 0;
}
```How this works
Aurora is blurred ribbons plus screen blending. Three wide, heavily blurred gradient bars drift horizontally at 14s, 19s and 24s; where they cross, mix-blend-screen adds their light rather than stacking opacity. Different periods mean the pattern never repeats within a session.
The sky does the rest. A single deep gradient with a colder horizon, and a low glow that fades out as the aurora comes up — so turning the switch on reads as night falling, not as a colour swap.
All three durations live in the animation shorthand, because an animate-* utility applied from a parent variant resets any separate animation-duration. That constraint shapes how every staggered demo in this collection is written.
Make it yours
- Rehue the ribbons through the three aurora tokens; keep them within ~60° of each other or it reads as a rainbow.
- Calmer: double every duration and drop the ribbon opacity to 0.5.
- Add a star field with the box-shadow trick from demo 02 behind the ribbons.
- Make it a page theme: move
has-checked:to<html>and swap tokens instead of colours.
Gotchas — read before shipping
- Three 40px-blurred, screen-blended layers are the most expensive composite in this collection — keep them few, large and slow, and never animate the blur radius itself.
mix-blend-screenneeds a dark backdrop to read as light; on a pale sky it does nothing.- Infinite ambient motion must stop under
motion-reduce:, where the ribbons hold a static composed position rather than disappearing. - Put the durations in the shorthand, not in a separate utility, whenever the animation is applied from a parent variant.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Blend modes, filters and keyframes are universal in evergreen browsers; :has() (Firefox 121+) only drives the page-level sky change.