- let num = 4, ang = 90, cx = 50, cy = 50, col = '#9c82da';

body(style=`--num: ${num}; --ang: ${ang}deg; --cx: ${cx}%; --cy: ${cy}%; --col: ${col}`)
	svg(width='0' height='0' aria-hidden='true')
		filter#grad-xor(color-interpolation-filters='sRGB')
			feColorMatrix(values=`0 0 0 0 0 
			                      0 0 0 0 0 
														0 0 0 0 0 
														0 1 0 0 0` result='mode')
			feColorMatrix(in='SourceGraphic'
			              values=`0 0 0 0 0 
			                      0 0 0 0 0 
														0 0 0 0 0 
														1 0 0 0 0` result='xbck')
			feColorMatrix(in='SourceGraphic'
			              values=`0 0 0 0 0 
			                      0 0 0 0 0 
														0 0 0 0 0 
														0 0 1 0 0` result='xgrd')
			feFlood(flood-color='var(--grad-0)')
			feComposite(in2='xgrd' operator='in' 
			            result='basexgrd')
			feFlood(flood-color='var(--link-0)')
			feComposite(in2='xbck' operator='in')
			feBlend(in='basexgrd' result='base_xor')
			feFlood(flood-color='var(--xtra-0)')
			feComposite(in2='xbck' operator='in')
			feBlend(in='base_xor')
			feComposite(in2='mode' operator='out' 
			            result='basemode')
			
			feFlood(flood-color='var(--grad-1)')
			feComposite(in2='xgrd' operator='in' 
			            result='darkxgrd')
			feFlood(flood-color='var(--link-1)')
			feComposite(in2='xbck' operator='in')
			feBlend(in='darkxgrd' result='dark_xor')
			feFlood(flood-color='var(--xtra-1)')
			feComposite(in2='xbck' operator='in')
			feBlend(in='dark_xor')
			feComposite(in2='mode' operator='in')
			feBlend(in='basemode')
			
			feComposite(in2='SourceAlpha' operator='in')
			
	header: h1 I am a heading contrasting with the background

	main
		section
			time(datetime='2022-10-19') 19th of October 2022
			p Sadly, 
				a(href='https://www.patreon.com/anatudor' target='_blank') links
				|  here need to be made either 
				code inline-block
				|  and use absolutely positioned pseudos that fully cover them or have their text content wrapped in a 
				code span
				|  if we want 
				a.deco(href='https://ko-fi.com/anatudor' target='_blank') underlines
				| .
			p This is due to a Firefox 
				a.fxor(href='https://bugzilla.mozilla.org/show_bug.cgi?id=1481498' target='_blank') bug
				|  old enough to go to school. Note this link has a XOR effect on 
				code :hover
				| / 
				code :focus
				| , which, due to the way the swipe effect works, requires an SVG 
				code filter
				| ... which 
				em could have been simpler
				|  
				strong if
				|  browsers were consistent!
			p Both the 
				code inline-block
				|  method and the extra 
				code span
				|  one have their disadvantages.
			p But going from a plain XOR effect to a 
				a.grad(href='#') gradient
				|  one is straightforward - we replace the solid 
				code background
				|  with a gradient, also clipped to 
				code text
				|  (then inherited by a pseudo creating the underline that grows to a full coverage rectangle XOR-ed with the text on 
				code :hover
				| / 
				code :focus
				| ).
			p It's the same situation for most other elements that need to have both their text and 
				i background
				| / 
				b border
				| / 
				u decoration
				|  change from one theme to the other.
			p Text looking as if 
				mark: span highlighted
				|  with a marker, for example. In theory, it's 
				del super
				ins reasonably 
				|  easy to do without pseudos or nested spans. In practice, Firefox says 
				q(cite='https://bugzilla.mozilla.org/show_bug.cgi?id=1481498') can't do that
				| . It doesn't scream to say 
				samp Error
				| , but you get the idea.
			p Or buttons! Plain buttons need the nested 
				code span
				|  approach if we don't want to bother with SVG filters.
			button: span button
			p Gradient buttons require an SVG 
				code filter
				| anyway (as anything with gradients does for a this kind of swipe theme switch), so we can do without any kind of nesting here.
			button.grad gradient button
			p We can also create buttons using 
				code input[type=button]
				| . Since we cannot have any kind of nesting in this case, we take the SVG 
				code filter
				|  approach.
			input(type='button' value='[type=button]')
			input.grad(type='button' value='[type=button]')
			p Now the page heading was a special one interacting with its backdrop.
			h2 A normal heading
			h3 Lists
			h4 Unordered list
			ul
				li Leopard
				li Jaguar
				li Lion
				li Tiger
			h4 Ordered list
			ol
				li Leopard
				li Jaguar
				li Lion
				li Tiger
			h4 Description list
			dl
				dt Tiger (
					i Panthera tigris
					| )
				dd A member of the genus 
					b Panthera
					|  and the largest living cat species.
				dt Snow leopard (
					i Panthera uncia
					| )
				dd A species of large cat in the genus 
					b Panthera
					|  of the family 
					b Felidae
					| .
			h3 Some other things you may find on a page
			//figure
				img(src='https://images.unsplash.com/photo-1603123495144-59fa702e8dd0?&w=400' alt='tiger')
				figcaption tiger
			//p Let's try another image, this time with a gradient border.
			//figure.grad
				img(src='https://images.unsplash.com/photo-1603123495144-59fa702e8dd0?&w=400' alt='tiger')
				figcaption tiger
			//video(src='https://i.imgur.com/8sOjFCw.mp4' controls)
			blockquote
				p We bring the people of the world together so you can watch them tear each other apart.
				cite social media
			hr
			p The basic 
				abbr(title='Cascading Style Sheets') CSS
				|  idea in this demo is the following:
			pre(data-lang='CSS')
				code
					| body { --dark: 0 }
					| body:has(#dark:checked) { --dark: 1 }
			p Then we use 
				code --dark
				|  inside animated gradients to produce this effect. You may find out more via 
				kbd Ctrl + Shift + C
				| .
			p Some stuff I code may be a bit Mathy, so I need variables 
				var x
				|  and I may need need to use exponents 
				var e
					sup x
				| . I've been toying with 
				dfn: attr(title='Scalable Vector Graphics') SVG
				|  lately, so that's a lot of playing with input 
				var R
					sub i
				|  and output channels.
				// Speaking of mathy stuff...
			//math
				mi c
				mo =
				msqrt
					msup
						mi a
						mn 2
					mo +
					msup
						mi b
						mn 2
		
		aside.theme-controls
			h2 Swipe effect controls
			form
				fieldset
					legend Type of swipe
					.wrap
						input#lin(type='radio' name='typ' checked)
						label(for='lin') linear
						input#rad(type='radio' name='typ')
						label(for='rad') radial
						input#con(type='radio' name='typ')
						label(for='con') conic					
					//.wrap
						input#rep(type='checkbox')
						label(for='rep') repeating
				
				.wrap.wrap--1x(style=`--max: 360`)
					label(for='ang') Angle
					.cont
						input#ang(type='range' value=ang max='360' 
						          style=`--unit: deg`)
						output(for='ang' style=`--unit: '°'; --val: ${ang}`) #{ang}

				fieldset#pos(style=`--unit: %`)
					legend Position
					.wrap
						.wrap.wrap--1x(style=`--max: 100`)
							label(for='cx') x
							.cont
								input#cx(type='range' min='0' value=cx max='100')
								output(for='cx' style=`--unit: '%'; --val: ${cx}`) #{cx}
						.wrap.wrap--1x(style=`--max: 100`)
							label(for='cy') y
							.cont
								input#cy(type='range' min='0' value=cy max='100')
								output(for='cy' style=`--unit: '%'; --val: ${cy}`) #{cy}
				
				//.wrap
					label(for='num') Repetitions
					input#num(type='number' min='2' value=num max='20' required data-default=num)
					output(for='num')
				
				fieldset
					legend Custom palette
					.wrap
						small You can't possibly expect me to let you to mess with more than this border...
						.wrap
							input#col(type='color' value=col)
							output(for='col') #{col}

	footer

	aside.theme-switch
		.wrap(role='group' aria-label='Theme')
			input#auto(type='radio' name='theme' checked)
			label(for='auto' data-ico='🖥️') auto
			input#light(type='radio' name='theme')
			label(for='light' data-ico='☀️') light
			input#dark(type='radio' name='theme')
			label(for='dark' data-ico='🌙') dark
View Compiled
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400..900&family=Red+Hat+Mono:ital,wght@0,300..700;1,300..700&family=Grandstander:ital,wght@0,100..900;1,100..900&family=Oxanium:wght@200..800&family=REM:ital,wght@0,100..900;1,100..900&display=swap');

/* Palette #1 *
$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+ sel toggles
$link-1: #00f1fd; // dark theme links+ sel toggles
$grad-0: #c50055;
$grad-1: #f67280;
/**/

/* Palette #2 *
$back-0: #ecf1f7; // light theme background
$back-1: #262c33; // dark theme background
$text-0: $back-1; // light theme text
$text-1: $back-0; // dark theme text
$link-0: #163289; // light theme links+ sel toggles
$link-1: #9fe7c1; // dark theme links+ sel toggles
$grad-0: #8f4f09;
$grad-1: #f9c039;
/**/

/* Palette #3 */
$back-0: #e8e8e8; // light theme background
$back-1: #2b2b2f; // dark theme background
$text-0: $back-1; // light theme text
$text-1: $back-0; // dark theme text
$link-0: #006a6a; // light theme links+ sel toggles
$link-1: #adfffe; // dark theme links+ sel toggles
$grad-0: #79226a;
$grad-1: #ef88d5;
/**/

/* Palette #4 *
$back-0: #d9e0fd; // light theme background
$back-1: #041c40; // dark theme background
$text-0: $back-1; // light theme text
$text-1: $back-0; // dark theme text
$link-0: #610c78; // light theme links+ sel toggles
$link-1: #fbdcfc; // dark theme links+ sel toggles
$grad-0: #012f8d;
$grad-1: #b7cff9;
/**/

// other constants
$dots-s: 1em;
$main-w: min(100%, 65em);
$line-w: 2px;
$rect-r: 5px;
$s: .5em;
$t: .65s;

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

// mixins
@mixin thumb($f: 0) {
	@if $f == 0 { border: none }
	
	width: $thumb-d; height: $thumb-d;
	border-radius: 50%;
	background: var(--func) fixed;
	cursor: ew-resize
}

/* ====== CSS vars declarations ====== */
@property --perc-ani {
	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
}

/* ====== GENERIC COMPONENTS ====== */
* {
	margin: 0;
	padding: 0;
	background: none;
	color: inherit;
	font: inherit
}

*, ::before {
	--c0: 
		color-mix(in srgb, 
			var(--comp-1) var(--perc-fix), 
			var(--comp-0));
	--c1: 
		color-mix(in srgb, 
			var(--comp-1), 
			var(--comp-0) var(--perc-fix))
}

::after {
	--c0: rgb(0%, var(--perc-fix), 0%);
	--c1: rgb(0%, calc(100% - var(--perc-fix)), 0%)
}

/* ------ big page components ------ */
html, body, header, dl, aside, form, fieldset { display: grid }

html { min-height: 100% }

body {
	/* initial case: light theme case, --dark is 0 */
	--dark: 0;
	/* Chrome stable without Experimental Web Platform 
	 * features flag still needs this fallback */
	--sign: calc(2*var(--dark) - 1);
	/* changes instantly between 0% & 100% and back */
	--perc-fix: calc(var(--dark)*100%);
	/* smoothly animates between 0% & 100% and back */
	--perc-ani: calc(var(--dark)*100%);
	/* swipe gradient position, always from 0% to 100%, 
	 * whether switch is from light to dark or not */
	--perc: 
		calc(100% - var(--perc-fix) + 
			   var(--sign)*var(--perc-ani));
	
	--xtra-0: #{lighten($back-0, 5%)};
	--xtra-1: #{darken($back-1, 5%)};
	--text-0: #{$text-0};
	--text-1: #{$text-1};
	--link-0: #{$link-0};
	--link-1: #{$link-1};
	--grad-0: #{$grad-0};
	--grad-1: #{$grad-1};
	/* the two body background options we go between 
	 * during a swipe (buggy in Epiphany) */
	--comp-0: #{$back-0};
	--comp-1: #{$back-1};
	
	--grad: 
		linear-gradient(to right top, #00f, #f00);
	--full: linear-gradient(red 0 0);
	
	grid-template-rows: 
		repeat(2, max-content) 1fr max-content;
	background: 
		radial-gradient($line-w, 
				hsla(0, 0%, 100%, .1) calc(100% - 1px), transparent) 
			0/ #{$dots-s $dots-s}, 
		var(--func) fixed;
	background-blend-mode: difference;
	font: 300 
		Round(clamp(1em, 1.5vw + .5vh, 1.5em), 4px)/ 1.25 
		rem, sans-serif;
	transition: --perc-ani $t ease-out;
	
	/* wish we had functions so we didn't have to 
	 * resort to this abomination */
	&, & *, & ::before, & ::after {
		--args: var(--set, var(--ang), ) 
			var(--c0) var(--p0, var(--perc)), 
			var(--c1) var(--p1, 0%);
		--func: linear-gradient(var(--args));
	}
	
	/* if there's a dark theme preference, 
	 * but we want to force the light theme */
	&:has(#light:checked) { --dark: 0 }
	/* cases in which we switch --dark to 1 */
	/* if there's a dark theme preference */
	@media (prefers-color-scheme: dark) { --dark: 1 }
	/* if we select the dark theme option */
	&:has(#dark:checked) { --dark: 1 }
	
	/* repeating */
	&:has(#rep:checked) {
		--calc: var(--perc)/var(--num);
		--p0: 0% calc(var(--calc));
		--p1: 0% calc(100%/var(--num));
		
		//&, & * { --edge-correct: var(--c1) 0px,  }
	}
	
	/* linear AND repeating */
	&:has(#lin:checked):has(#rep:checked) {
		&, & *, & ::before, & ::after {
			--func: repeating-linear-gradient(var(--args))
		}
	}
	
	/* radial */
	&:has(#rad:checked) {
		--set: circle at var(--cx) var(--cy), ;
		
		&, & *, & ::before, & ::after {
			--func: radial-gradient(var(--args))
		}
		
		/* radial AND repeating */
		&:has(#rep:checked) {
			&, & *, & ::before, & ::after {
				--func: repeating-radial-gradient(var(--args)) 
			}
		}
	}
	
	/* conic */
	&:has(#con:checked) {
		--set: from var(--ang) at var(--cx) var(--cy), ;
		
		&, & *, & ::before, & ::after {
			--func: conic-gradient(var(--args))
		}
		
		/* conic AND repeating */
		&:has(#rep:checked) {
			&, & *, & ::before, & ::after {
				--func: repeating-conic-gradient(var(--args))
			}
		}
	}
}

/* functionally the same as a style element, 
 * take it out of document flow */
svg[aria-hidden='true'] { position: fixed }

header, main, footer, section, aside, fieldset {
	padding: $s
}

header, aside {
	grid-gap: $s;
	grid-template-columns: $main-w;
	justify-content: center
}

header {
	--c0: hsl(0, 0%, calc(100% - var(--perc-fix)));
	--c1: hsl(0, 0%, var(--perc-fix));
	justify-self: stretch;
	background: 
		var(--func) fixed,
		linear-gradient(45deg, $back-1 calc(50% - 5em), 
				$back-0 0 calc(50% + 5em), $back-1 0), 
		url(https://images.unsplash.com/photo-1635070041078-e363dbe005cb?w=2400) 
			50%/ cover $back-1;
	background-blend-mode: difference, difference, multiply;
	text-align: center
}

h1 {
	place-self: center;
	color: #fff;
	font-size: 3em;
	font-weight: 900;
	line-height: Round(up, 1.25em, 1px);
	text-wrap: balance;
	mix-blend-mode: difference
}

main, footer {
	box-sizing: border-box;
	justify-self: center;
	width: $main-w
}

main, label, li {
	display: flex;
	align-items: center;
	gap: $s
}

main {
	flex-wrap: wrap-reverse;
	align-items: flex-end;
	
	> * { border-radius: calc(#{$s} + #{$rect-r}) }
}

section, aside {
	--comp-0: var(--xtra-0);
	--comp-1: var(--xtra-1);
	box-shadow: 2px 2px 5px 
		rgba(0, 0, 0, calc(.3 + var(--dark)*.5));
	background: var(--func) fixed
}

section { flex: 3 3 21.75em }

aside {
	box-sizing: border-box;
	position: sticky;
	z-index: 2;
	top: 0
}

dl, form, fieldset { grid-gap: $s }

h2, h3, h4, time, p, a, button span, q, samp, legend, input, label, output, small, li, dl, figcaption, cite, pre code, sub, sup {
	--comp-0: #{$text-0};
	--comp-1: #{$text-1};
	color: #0000;
	background: var(--func) text fixed
}

h2, h3, h4, h5, h5 { padding: .5*$s 0 }

h2 { font-size: 2em }
h3 { font-size: 1.5em }
h4 { font-size: 1.25em }
h5 { font-size: 1.125em }

time {
	font-size: calc(1em - 4px);
	font-family: orbitron, sans-serif
}

p {
	padding: $s 0;
	isolation: isolate;
	
	code {
		padding: 0 $line-w;
		background: rgba(grey, .1)
	}
}

code, samp, output {
	font-family: red hat mono, monospace;
	font-weight: 500
}

b, strong { font-weight: 600 }
i, em { font-style: italic }
u { text-decoration: underline double grey }

mark {
	&:has(span) {
		--comp-0: var(--grad-1);
		--comp-1: var(--grad-0);
		padding: 0 $line-w;
		background: #ed9831;
		background: var(--func) fixed
	}
	
	span {
		--comp-0: var(--text-0);
		--comp-1: var(--text-1);
		background: var(--func) text fixed
	}
}

ul, ol, dl { margin: $s 0 }

ol { counter-reset: c }

ol li::before {
	width: 1em;
	text-align: right;
	counter-increment: c;
	content: counter(c) '.'
}

ul li::before {
	box-sizing: border-box;
	padding: $line-w;
	width: $s; height: $s;
	border-radius: 50%;
	background: inherit;
	background-clip: border-box;
	mask: var(--full) content-box exclude, 
		var(--full) padding-box;
	content: ''
}

dd, blockquote, pre {
	padding: $s;
	background: rgba(grey, .1)
}

dt { font-weight: 700 }

dd { margin: 0 0 0 $s }

blockquote { margin: $s 0 }

blockquote p { font-family: grandstander, serif }

cite {
	display: block;
	font-style: italic;
	text-align: right
}

figure, img, video, embed, iframe { max-width: 100% }

sub, sup {
	--off: Round(-.5em, 1px);
	position: relative;
	vertical-align: hanging;
	font-size: Max(.5rem, .625em);
	line-height: 1;
}

sup { top: var(--off) }

sub {
	bottom: var(--off);
	vertical-align: baseline
}

legend {
	padding: 0 $s;
	font-weight: 400
}

/* ------ text highlight components ------ */
a, samp, q, ins, del { font-weight: 400 }

del, ins {
	display: inline-block;
	background: var(--func) text fixed
}

:is(del, ins)::before { vertical-align: middle }

del {
	--comp-0: var(--grad-0);
	--comp-1: var(--grad-1);
	position: relative;
	
	&::before { content: '✘' }
	
	&::after {
		position: absolute;
		inset: 50% 0 calc(50% - #{$line-w}) .75em;
		background: inherit;
		background-clip: border-box;
		pointer-events: none;
		content: ''
	}
}

ins {
	--comp-0: var(--link-0);
	--comp-1: var(--link-1);
	
	&::before { content: '✔' }
}

q {
	--comp-0: #00287d;
	--comp-1: #b6c4ff;
}

samp {
	--comp-0: #895100;
	--comp-1: #ffb86d;
}

/* ------ interactive components ------ */
:is(a, button, input, input + [for]) {
	--hov: 0;
	--sel: 0;
	--perc-sel: calc(var(--sel)*100%);
	transition: $t;
	transition-property: --hov, --sel
}

:is(a, button, input, label):is(:hover, :focus), 
input:is(:hover, :focus) + [for] { --hov: 1 }

:is(a, button, [type='button'], [type='range']):active, 
:is([type='radio'], [type='checkbox']):checked, 
:is([type='radio'], [type='checkbox']):checked + label { 
	--sel: 1
}

a {
	--comp-0: #{$link-0};
	--comp-1: #{$link-1};
	text-decoration: none;
	
	&[class] {
		--y: calc(100% - #{$line-w});
		display: inline-block;
		position: relative;
		padding: 0 $line-w;
		background-clip: text;
		
		&::before, &::after {
			position: absolute;
			inset: -1px 0;
			pointer-events: none
		}
		
		&::before {
			background: inherit;
			background-clip: border-box;
			clip-path: 
				inset(var(--dty, var(--y)) 0 0);
			content: ''
		}
	}
}

button, 
[type='button'], [type='range'], [type='color'], 
input + label { cursor: pointer }

button, [type='button'] {
	margin: $line-w;
	border: none;
	padding: $s 2*$s;
	border-radius: 1lh;
	font-weight: 400
}

button {
	&:not([class]) {
		&:has(span) {
			--comp-0: var(--link-0);
			--comp-1: var(--link-1);
			background: var(--func) fixed
		}
	}
	
	&[class] {
		--c0: rgb(0%, var(--perc-fix), 0%);
		--c1: rgb(0%, calc(100% - var(--perc-fix)), 0%);
		--mode: , var(--func) fixed;
		background-blend-mode: lighten;
		color: #000
	}
	
	span {
		--comp-0: var(--xtra-0);
		--comp-1: var(--xtra-1)
	}
}

input:not([name='theme']) + [for] {
	filter: Saturate(calc(var(--sel) + var(--hov)))
}

[type='button'] {
	--c0: rgb(100%, var(--perc-fix), 0%);
	--c1: rgb(100%, calc(100% - var(--perc-fix)), 0%);
	color: #000;
	
	&:not([class]) {
		background: var(--func) fixed;
		filter: url(#grad-xor)
	}
	
	&[class] {
		--mode: , var(--func) fixed;
		background-blend-mode: lighten
	}
}

:is([type='radio'], [type='checkbox']) {
	position: absolute;
	opacity: .001;
	
	&:not([name='theme']) + label {
		--comp-0: var(--link-0);
		--comp-1: var(--link-1);
		
		&::before {
			box-sizing: border-box;
			border: solid $line-w #0000;
			padding: Max(#{$line-w}, Round(.2em, 1px));
			width: 1lh;
			aspect-ratio: 1;
			background: var(--func) fixed;
			mask: 
				linear-gradient(
						rgba(0, 0, 0, var(--sel)) 0 0) 
					content-box exclude, 
				var(--full) padding-box exclude, 
				var(--full);
			content: ''
		}
	}
}

[type='checkbox'] + label {
	display: grid;
	grid-auto-flow: column;
	place-items: center;
	
	&::before, &::after { grid-area: 1/ 1 }
	
	&::after {		
		--c0: hsl(0, 0%, calc(100% - var(--perc-fix)));
		--c1: hsl(0, 0%, var(--perc-fix));
		z-index: 2;
		opacity: var(--sel);
		background: var(--func) text fixed;
		content: '✔';
		
		@supports (content: '✔'/ '') { content: '✔'/ '' }
	}
}

[type='radio'] + label::before {
	border-radius: 50%
}

[type='range'] {
	&, &::-webkit-slider-thumb { appearance: none }
	
	--comp-0: var(--link-0);
	--comp-1: var(--link-1);
	width: 100cqw;
	height: $track-h;
	border-radius: $track-r;
	background: grey;
	cursor: pointer;
	
	&::-webkit-slider-thumb { @include thumb(1) }
	&::-moz-range-thumb { @include thumb }
	&::slider-thumb { @include thumb }
	
	&, & + output { grid-area: 1/ 1 }
	
	& + output {
		--pos: calc(#{$thumb-r} + var(--val)/var(--max)*(100cqw - #{$thumb-d}) + -50%);
		position: relative;
		place-self: start;
		border: solid $s #0000;
		padding: $line-w;
		min-width: 2em;
		border-radius: calc(#{$s} + 2*#{$line-w});
		transform-origin: 50% 100%;
		translate: var(--pos) -100%;
		scale: var(--hov);
		background: 
			color-mix(in srgb, var(--link-1) var(--perc-ani), var(--link-0));
		color: 
			color-mix(in srgb, var(--xtra-1) var(--perc-ani), var(--xtra-0));
		font-size: .8em;
		text-align: center;
		mask: var(--full) padding-box, 
			conic-gradient(from -45deg at 50% 100%, 
					red 25%, #0000 0) 
				50% 100%/ 50% 50% no-repeat border-box
	}
}

[type='number'] {
	border: solid $line-w grey;
	padding: 0 $s;
	border-radius: 1lh;
	font-family: red hat mono, monospace;
	text-align: right;
	
	&::-webkit-textfield-decoration-container {
		-webkt-user-modify: read-write !important;
		//background: red;
	}
	
	&::-webkit-inner-spin-button {
		-webkt-user-modify: read-write !important;
		appearance: none;
	}
	
	&:invalid { background: crimson; }
}

[type='color'] {
	flex: 0 0 1lh;
	border: solid $line-w grey;
	padding: $line-w;
	height: 1lh;
	border-radius: 50%;
	
	&::-webkit-color-swatch {
		border: none;
		margin: -4px -2px;
		border-radius: 50%
	}
	
	&::-moz-color-swatch {
		border: none;
		border-radius: 50%;
	}
}

output {
	&::after { content: var(--unit, ) }
}

/* ====== SPECIFIC COMPONENTS ====== */
.fxor, .grad {
	isolation: isolate;
	filter: url(#grad-xor);
	
	&::before, &::after { mix-blend-mode: difference }
	&::before { --dty: calc((1 - var(--hov))*var(--y)) }
	
	&::after {
		background: var(--func) fixed;
		content: ''
	}
}

.fxor { background: #f00 text }

.grad {
	background: var(--grad) 
		var(--mode, #{unquote(' ')})
}

.wrap {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: $s;
	
	&[class*='x'] {
		display: grid;
		grid-template-columns: max-content 1fr;
		flex: 1 1 min(50%, 10em);
		padding: $s 0;
	}
}

.cont {
	display: grid;
	grid-template-rows: 100%;
	align-items: center;
	container-type: inline-size;
	width: 100%;
	height: 1lh;
}

.theme-switch {
	grid-area: 1/ 1;
	justify-items: end
}

[name='theme'] + [for] {
	position: relative;
	padding: 0 2*$s;
	color: #0000;
	background: var(--func) text fixed;
	font: 
		Round(Max(.625rem, .75em), 1px)/ 2 
		orbitron, sans-serif;
	cursor: pointer;
	
	&::before {
		--comp-0: var(--link-1);
		--comp-1: var(--link-0);
		position: absolute;
		z-index: -1;
		inset: 0;
		border-radius: 1lh;
		opacity: min(1, var(--hov) + var(--sel));
		background: var(--func) fixed;
		filter: Saturate(calc(var(--sel)*.5));
		content: ''
	}
	
	&::after { content: attr(data-ico) }
}

.theme-controls {
	top: 2.5lh;
	flex: 1 2 14.5em;
	border: solid $s var(--col);
	border-radius: calc(#{$s} + 2*#{$line-w});
	
	h2 { font-size: 1.25em }
	
	&:has(#lin:checked) #pos, 
	&:has(#rad:checked) .wrap:has(#ang), 
	&:has(#rep:not(:checked)) .wrap:has(#num) { display: none }
}
View Compiled
addEventListener('input', e => {
	let _t = e.target, v = _t.value, id = _t.id, 
			_o = _t.nextElementSibling, t = _t.type;
	
	if(['range', 'color', 'number'].indexOf(t) > -1) {
		switch(t) {
			case 'range':
				_o.style.setProperty('--val', v);
			case 'color':
				_o.textContent = v;
				break;
			case 'number':
				if(!(v.length && v.match(/[0-9]{1,2}/) && +_t.min <= +v && +_t.max >= +v))
					_t.value = v = _t.dataset.default
		}

		document.body.style.setProperty(
			`--${id}`, 
			`${v}${getComputedStyle(_t).getPropertyValue('--unit') || ''}`)
	}
})
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.