.wrap
	p Select a theme option:
	input#light(type='radio' name='theme' checked)
	label(for='light' data-ico='☀️') light
	input#dark(type='radio' name='theme')
	label(for='dark' data-ico='🌙') dark
.wrap
	label(for='dir') Swipe direction (angle):
	input#dir(type='range' value='0' max='360')
View Compiled
$line-w: 2px;

$back-0: #dbdce0; // light theme background
$back-1: #39393c; // dark theme background
$text-0: $back-1; // light theme text
$text-1: $back-0; // dark theme text
$link-0: #573cff; // light theme links + selected toggles
$link-1: #00f1fd; // light theme links + selected toggles

$track-h: 6px;
$track-r: .5*$track-h;
$thumb-d: 1em;
$thumb-r: .5*$thumb-d;
$thumb-o: -1*$thumb-r;

@mixin track {
	height: $track-h;
	border-radius: $track-r;
	background: hsl(0, 0%, 50%);
}

@mixin thumb($f: 0) {
	@if $f > 0 { margin-top: calc(#{$track-r} + #{$thumb-o}) }
	@else { border: none }
	
	width: $thumb-d; height: $thumb-d;
	border-radius: 50%;
	background: 
		linear-gradient(var(--ang), $link-1 var(--perc), $link-0 0) 
			fixed;
	cursor: ew-resize
}

@property --perc {
	syntax: '<length-percentage>';
	initial-value: 0px;
	inherits: true
}

@property --hov {
	syntax: '<number>';
	initial-value: 0;
	inherits: true
}

@property --sel {
	syntax: '<number>';
	initial-value: 0;
	inherits: true
}

* { color: #0000; font: inherit }

body {
	--dark: 0;
	--perc: calc(var(--dark, 0)*100%);
	/* Chrome stabele without flag still needs this fallback */
	--sign: calc(2*var(--dark) - 1);
	--ang: calc(var(--dir, 0)*1deg + var(--sign)*90deg);
	--full: linear-gradient(red 0 0);
	
	display: grid;
	gap: 1.5em;
	background: 
		linear-gradient(var(--ang), 
				$back-1 var(--perc), $back-0 0) fixed;
	font: 1.5em/ 1.5 sans-serif;
	text-align: center;
	transition: --perc .65s ease-out;
	
	&:has(#dark:checked) { --dark: 1 }
	
	/* if sign() is supported */
	@supports (scale: Sign(-1)) {
		--sign: sign(var(--dark) - .5)
	}
}

p, label {
	background: 
		linear-gradient(var(--ang), 
				$text-1 var(--perc), $text-0 0) text fixed
}

[type='radio'] {
	position: absolute;
	opacity: .001
}

:is([type='radio']) {
	& + label {
		--hov: 0;
		--sel: 0;
		--perc-sel: calc(var(--sel)*100%);
		--perc-hov: calc(var(--hov)*100%);
		--lght-c: color-mix(in srgb, #{$link-0} var(--perc-sel), #{$text-0});
		--dark-c: color-mix(in srgb, #{$link-1} var(--perc-sel), #{$text-1});
		position: relative;
		margin: .5em;
		padding: calc(.5em + #{$line-w});
		background: 
			linear-gradient(var(--ang), 
					var(--dark-c) var(--perc), var(--lght-c) 0) text fixed;
		transition: .35s ease-out;
		transition-property: --hov, --sel;
		cursor: pointer;
		
		&::before {
			margin-right: .5em;
			content: attr(data-ico)
		}

		/* hover/ focus outline */
		&::after {
			position: absolute;
			inset: 0;
			padding: $line-w;
			background: 
				linear-gradient(var(--ang), 
						color-mix(in srgb, var(--dark-c) var(--perc-hov), #0000) var(--perc), 
						color-mix(in srgb, var(--lght-c) var(--perc-hov), #0000) 0) fixed;
			mask: var(--full) exclude, var(--full) content-box;
			pointer-events: none;
			content: ''
		}
	}
		
		/* switch --hov to 1 in hover/ focus case */
	&:is(:hover, :focus) + label, label:hover { --hov: 1 }
	/* switch --sel to 1 if its radio button is checked */
	&:checked + label { --sel: 1 }
}

[type='range'] {
	&, &::-webkit-slider-thumb { appearance: none }
	
	display: block;
	margin: .5em auto;
	width: min(100%, 20em);
	background: #0000;
	cursor: pointer;
	
	&::-webkit-slider-runnable-track { @include track }
	&::-moz-range-track { @include track }
	
	&::-webkit-slider-thumb { @include thumb(1) }
	&::-moz-range-thumb { @include thumb }
}
View Compiled
addEventListener('input', e => {
	let _t = e.target;
	
	if(_t.type === 'range')
		document.body.style.setProperty('--dir', `${+_t.value}`)
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.