/* Scene: eye. A pixelated eye over the whole sheet, and under it, on the
   cheek, the form as a terminal window off lee's fvwm config
   (github.com/lluppi/fvwm) and its web port (github.com/lluppi/imre.al-vwm).
   Loaded after login.css. */

@font-face {
	font-family: "Tamzen";
	/* 8x15, the config's `xft:Tamzen:pixelsize=15`: every glyph whole
	   pixel squares, so at exactly 15px it sits on the pixel grid
	   (source/tamzen.py adds the password bullet) */
	src: url("/static/scenes/eye/tamzen-15.ttf") format("truetype");
	font-display: block;
}

@font-face {
	font-family: "Tamzen 16";
	/* 8x16, only for the fields on a touch screen: ios zooms under 16px */
	src: url("/static/scenes/eye/tamzen-16.ttf") format("truetype");
	font-display: block;
}

.scene[data-scene="eye"] {
	/* no paper here: the glass is black */
	--paper-opacity: 0;
	/* the vwm terminal's prompt arrow, 6x9 (real-icons' terminal-arrow) */
	--arrow-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 9' shape-rendering='crispEdges'%3E%3Cpath fill='%23000' d='M0 0h2v1H0zM1 1h2v1H1zM2 2h2v1H2zM3 3h2v1H3zM4 4h2v1H4zM3 5h2v1H3zM2 6h2v1H2zM1 7h2v1H1zM0 8h2v1H0z'/%3E%3C/svg%3E");
	--go-ink: #fffefe;
	--go-ready: #fffefe;
	--go-hover: #fffefe;
	--arrow-rest: 0.45;

	/* the window border: 5px, one ring all round - 1px dark, 2px lit, 2px
	   dark (colorset 4 focused, 3 not). the config lights 2px top and left
	   but 1px bottom and right, and its bevels lap over each other at the
	   corners; this closes them into a ring (window.js paints the same) */
	--fv-border-on: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' shape-rendering='crispEdges'%3E%3Cpath fill='%23222020' d='M0 0h11v11H0z'/%3E%3Cpath fill='%2332302c' d='M1 1h9v2H1zM1 8h9v2H1zM1 3h2v5H1zM8 3h2v5H8z'/%3E%3C/svg%3E");
	--fv-border-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' shape-rendering='crispEdges'%3E%3Cpath fill='%23494b46' d='M0 0h11v11H0z'/%3E%3Cpath fill='%23686d62' d='M1 1h9v2H1zM1 8h9v2H1zM1 3h2v5H1zM8 3h2v5H8z'/%3E%3C/svg%3E");
	/* titlebar.xpm, 3x3 */
	--fv-titlebar: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 3' shape-rendering='crispEdges'%3E%3Cpath fill='%23686d62' d='M0 0h3v3H0z'/%3E%3Cpath fill='%23777a73' d='M1 1h1v1H1z'/%3E%3C/svg%3E");
	/* the title buttons' glyphs: svg files (fv-*.svg), 7x7, used here as
	   masks in the glyph ink - light focused, near black not */
	--fv-glyph-on: #e4e3d5;
	--fv-glyph-off: #343631;
}

/* a finger held down and moved drags the gaze (eye.js), so one-finger pans
   are the page's, not the browser's - the sheet never scrolls anyway - and
   a pinch anywhere, the form's too, is the tube's zoom, not the page's: the
   login window never grows, only the eye does. so the page's touch-action
   is none. the backdrop takes touches here (login.css leaves it out of hit
   testing) and the sheet's main box lets them through to it, all but the
   form's. holding still (reduced motion) there's no zoom, and a pinch
   zooms the page again */
html:has(.scene[data-scene="eye"]),
.scene[data-scene="eye"] {
	touch-action: none;
}

.scene[data-scene="eye"] #wall {
	pointer-events: auto;
	touch-action: none;
}

.scene[data-scene="eye"] main {
	pointer-events: none;
}

.scene[data-scene="eye"] main form {
	pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
	html:has(.scene[data-scene="eye"]),
	.scene[data-scene="eye"],
	.scene[data-scene="eye"] #wall {
		touch-action: pinch-zoom;
	}
}

.scene[data-scene="eye"] #wall {
	overflow: hidden;
	background: #000;
}

/* the desktop's wallpaper (wallpaper.js), very dark, at the back: its
   canvas a device pixel to a device pixel, so nothing may scale it */
.eye-wall {
	position: absolute;
	top: 0;
	left: 0;
	display: block;
	image-rendering: pixelated;
	image-rendering: crisp-edges;
	pointer-events: none;
}

/* the eye is light: it adds to the wallpaper rather than covering it, so
   where it's black the wallpaper shows */
.eye-canvas {
	position: absolute;
	display: block;
	mix-blend-mode: screen;
	image-rendering: pixelated;
	image-rendering: crisp-edges;
	transform-origin: 50% 50%;
}

/* the second pass's labels: yellow chips, black mono type */
.eye-tags {
	position: absolute;
	inset: 0;
	z-index: 1;
	/* the labels are the screen's own light, not a layer over the page: a
	   tap goes through them to the form, even mid-strobe */
	pointer-events: none;
	/* and the phosphor keeps its light: rather than snapping off with the
	   cut back to green, the layer fades (eye.js sets the time from the
	   tube's phosphor) */
	transition: opacity 70ms linear;
}

.eye-tags.eye-fade {
	opacity: 0;
	transition-duration: var(--tag-linger, 0ms);
}

.eye-tag {
	position: absolute;
	top: 0;
	left: 0;
	padding: 0 calc(4 * var(--px, 1px));
	background: #f0e000;
	color: #000;
	/* the window's type (Tamzen 15, window.js's pixel), a pixel above and
	   below it in the chip */
	font:
		calc(15 * var(--px, 1px)) / calc(17 * var(--px, 1px)) "Tamzen",
		ui-monospace,
		monospace;
	white-space: nowrap;
	/* the type's ghost trails right of the box (below): clipped to the chip,
	   so only its smear over the glyphs shows, never a sliver past its edge */
	overflow: hidden;
	overflow: clip;
}

/* No halo round the chips, lit or going: a glow trailing off to the right of
   every one of them swamped the frame, and off its right edge alone it read
   as an artifact rather than a trail. The phosphor shows in how they hold
   their light (the fade above) and in the trail on the type (below). */

/* The trail on the type itself. The type is black on yellow, so a shadow
   behind it would never show: this is a ghost of it painted over the glyphs,
   offset by the video line's trail and in the trail's colour. */
.eye-tag::after {
	content: attr(data-text);
	position: absolute;
	inset: 0;
	padding: inherit;
	color: var(--tag-ghost, transparent);
	transform: translateX(var(--tag-dx, 0px));
	filter: blur(0.5px);
	pointer-events: none;
}

.eye-tag[hidden] {
	display: none;
}

.eye-blank {
	width: calc(7 * var(--px, 1px));
	padding: 0;
	height: calc(17 * var(--px, 1px));
}

/* The form sits low, on the cheek, clear of the eye: a terminal window
   under lee's fvwm decor, and in it a linux console's login.

   The frame is the config's, measured off its own screenshot: the 5px
   border (above), the 25px titlebar (TitleStyle Height 25) tiled with
   titlebar.xpm, the name right-justified 93px in, every button a 25px
   square with its 7x7 glyph (fv-*.svg) 9px in, no line under the bar, and
   picom's shadow. window.js paints that frame into a canvas on the device
   pixel grid; the css frame here is what a page with no script gets. The
   body is the vwm terminal (github.com/lluppi/imre.al-vwm): its translucent
   #282828, 10px 12px in, its colours, its block caret - holding agetty's
   prompts (window.js: the issue line, the no-echo password).

   Every size is a count of `--px`, the window's pixel: a whole number of
   device pixels, the nearest to a css px (window.js sets it; 1px without
   script). So a 1px bevel is never a pixel and a quarter, and 15px type in
   21px rows lands 3 pixels down, whole. */
.scene[data-scene="eye"] main {
	place-items: end center;
	padding-bottom: max(3rem, 9vh);
	padding-bottom: max(3rem, 9svh);
}

.scene[data-scene="eye"] form {
	--px: 1px;
	--fv-border: var(--fv-border-off);
	--fv-glyph: var(--fv-glyph-off);
	--line: calc(15 * var(--px));
	--row: calc(21 * var(--px));
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	align-items: center;
	gap: 0;
	width: min(100%, calc(344 * var(--px)));
	/* the titlebar's 25px, then the vwm terminal's 10px 12px */
	padding: calc(35 * var(--px)) calc(12 * var(--px)) calc(10 * var(--px));
	border: calc(5 * var(--px)) solid transparent;
	border-image: var(--fv-border) 5 / calc(5 * var(--px)) stretch;
	background: rgba(40, 40, 40, 0.9) padding-box;
	/* picom's, fitted to the screenshot's falloff */
	box-shadow: calc(2 * var(--px)) calc(2 * var(--px)) calc(6.5 * var(--px))
		rgba(0, 0, 0, 0.66);
	color: #efefe7;
	font:
		calc(15 * var(--px)) / var(--line) "Tamzen",
		ui-monospace,
		monospace;
	text-align: left;
	-webkit-font-smoothing: none;
}

/* focused: ClickToFocus (window.js), or a field holding the focus */
.scene[data-scene="eye"] form:focus-within,
.scene[data-scene="eye"] form.fv-focused {
	--fv-border: var(--fv-border-on);
	--fv-glyph: var(--fv-glyph-on);
}

/* the spaz (eye.js `.eye-spaz`): the window's dark scheme. window.js
   grains the frame and the client's ground over to it and back; the type
   steps along - white, its prompts the name's light grey - as quick each
   way */
.scene[data-scene="eye"] form.fv-drawn,
.scene[data-scene="eye"] form.fv-drawn .field::before,
.scene[data-scene="eye"] form.fv-drawn .field input,
.scene[data-scene="eye"] form.fv-drawn .eye-caret {
	transition:
		color 60ms steps(1, end),
		background-color 60ms steps(1, end);
}

.scene[data-scene="eye"].eye-spaz form {
	color: #fff;
}

.scene[data-scene="eye"].eye-spaz .field::before {
	color: #b2b2b2;
}

.scene[data-scene="eye"].eye-spaz .field input {
	color: #fff;
}

.scene[data-scene="eye"].eye-spaz .field input:autofill {
	-webkit-text-fill-color: #fff;
}

.scene[data-scene="eye"].eye-spaz .eye-caret {
	background: #fff;
}

@media (prefers-reduced-motion: reduce) {
	.scene[data-scene="eye"] form.fv-drawn,
	.scene[data-scene="eye"] form.fv-drawn * {
		transition: none;
	}
}

/* the css titlebar (no script): the stipple from 25px in, the name
   right-justified 93px in, its ascenders 6px down the bar (a pixel above
   the config's, centred) */
.scene[data-scene="eye"] form::before {
	content: "login";
	position: absolute;
	top: 0;
	right: 0;
	left: 0;
	box-sizing: border-box;
	height: calc(25 * var(--px));
	padding: calc(3 * var(--px)) calc(93 * var(--px)) 0 0;
	background:
		var(--fv-titlebar) calc(25 * var(--px)) 0 / calc(3 * var(--px))
		calc(3 * var(--px)) repeat;
	color: #e4e3d5;
	font:
		calc(15 * var(--px)) / calc(15 * var(--px)) "Tamzen",
		ui-monospace,
		monospace;
	text-align: right;
	pointer-events: none;
}

/* and its one button, window ops on the left: the glyph ink through its
   svg, 9px into its 25px square. no buttons on the right */
.scene[data-scene="eye"] form::after {
	--g: calc(7 * var(--px));
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	left: 0;
	height: calc(25 * var(--px));
	background: var(--fv-glyph);
	-webkit-mask:
		url("/static/scenes/eye/fv-ops.svg") calc(9 * var(--px)) calc(9 * var(--px))
		/ var(--g) var(--g) no-repeat;
	mask:
		url("/static/scenes/eye/fv-ops.svg") calc(9 * var(--px)) calc(9 * var(--px))
		/ var(--g) var(--g) no-repeat;
	pointer-events: none;
}

/* window.js paints the frame - border, titlebar, glyphs, name - into one
   canvas on the device pixel grid, and the css frame above stands down.
   the canvas lies over the border box, under everything the window holds */
.fv-frame {
	position: absolute;
	z-index: -1;
	top: 0;
	left: 0;
	pointer-events: none;
	image-rendering: pixelated;
	image-rendering: crisp-edges;
}

/* and the 5px the border held becomes padding: chromium floors a border's
   width to whole device pixels, and at 1.5 took 5 x 1.333 px (9.99997
   device) down to 9, a pixel short of the frame painted over it. padding
   it leaves alone */
.scene[data-scene="eye"] form.fv-drawn {
	border: 0;
	padding: calc(40 * var(--px)) calc(17 * var(--px)) calc(15 * var(--px));
	/* the canvas paints the client's ground too, so it can grain it */
	background: none;
}

.scene[data-scene="eye"] form.fv-drawn::before,
.scene[data-scene="eye"] form.fv-drawn::after {
	content: none;
}

/* moving (window.js): fvwm's move cursor over everything, and nothing
   selected on the way */
html.fv-moving,
html.fv-moving * {
	cursor: move !important;
	user-select: none !important;
}

/* agetty's issue line (window.js), and the blank line after it */
.tty-issue {
	margin: 0 0 var(--row);
	line-height: var(--row);
	white-space: pre;
}

/* a prompt line: the prompt, then what's typed */
.scene[data-scene="eye"] .field {
	display: flex;
	align-items: center;
	height: var(--row);
	cursor: text;
}

.scene[data-scene="eye"] .field::before {
	content: "imre.al login:";
	flex: none;
	/* and the space after it, a cell */
	padding-right: calc(8 * var(--px));
	/* a console's prompts are its output: the one white */
	color: #efefe7;
	line-height: var(--line);
	white-space: pre;
}

.scene[data-scene="eye"] .field:has(#password)::before {
	content: "Password:";
}

.scene[data-scene="eye"] .field input {
	flex: 1;
	height: 100%;
	padding: 0;
	background: transparent;
	color: #a7b4a9;
	caret-color: #efefe7;
	font-size: inherit;
	line-height: var(--line);
	letter-spacing: 0;
}

/* the password's prompt waits for the login (window.js `.tty-pass`), its
   row held so nothing moves when it's printed */
.scene[data-scene="eye"] form.tty:not(.tty-pass) .field:has(#password) {
	visibility: hidden;
}

/* a browser filling a field in: window.js hears this and prints the
   password's prompt, so a password manager has somewhere to put it */
@keyframes fv-autofill {
	from {
		opacity: 1;
	}
	to {
		opacity: 1;
	}
}

.scene[data-scene="eye"] form.tty .field input:autofill {
	animation: fv-autofill 1ms;
}

/* a console never echoes the password (window.js keeps its caret put) */
.scene[data-scene="eye"] form.tty #password,
.scene[data-scene="eye"] form.tty #password:autofill {
	color: transparent;
	-webkit-text-fill-color: transparent;
}

.scene[data-scene="eye"] form.tty #password::selection {
	color: transparent;
	background: transparent;
}

/* window.js draws the terminal's block caret instead */
.scene[data-scene="eye"] form.eye-block .field input {
	caret-color: transparent;
}

/* the vwm terminal's `.caret`: 7x14, #efefe7, 2px after the text */
.eye-caret {
	position: absolute;
	z-index: 3;
	top: calc(3 * var(--px));
	left: 0;
	width: calc(7 * var(--px));
	height: calc(14 * var(--px));
	background: #efefe7;
	pointer-events: none;
}

.eye-caret[hidden] {
	display: none;
}

.scene[data-scene="eye"] .field input::selection {
	color: #282828;
	background: #a7b4a9;
}

.scene[data-scene="eye"] .field input:autofill {
	-webkit-text-fill-color: #a7b4a9;
	caret-color: #efefe7;
}

.scene[data-scene="eye"] form.eye-block .field input:autofill {
	caret-color: transparent;
}

/* the server's word, as console output */
.scene[data-scene="eye"] .err {
	margin: 0;
	padding: 0;
	color: #efefe7;
	font-size: inherit;
	line-height: var(--row);
}

/* the submit: a console has none, enter logs in. the button stays for the
   phone keyboard's go and for screen readers, out of sight (and, with
   script, out of the tab order) */
.scene[data-scene="eye"] #go {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* touch: the window as it is everywhere else, but what's typed is 16px
   (ios zooms in on a field under that). Tamzen 16 in the same 21px row,
   3px down like the prompt, so the two share a baseline: the 16px cut's
   ascent is the 15px's, 12px */
@media (pointer: coarse) {
	.scene[data-scene="eye"] .field input {
		box-sizing: border-box;
		padding: calc(3 * var(--px)) 0 calc(2 * var(--px));
		font:
			calc(16 * var(--px)) / calc(16 * var(--px)) "Tamzen 16",
			"Tamzen",
			ui-monospace,
			monospace;
	}
}

/* The desktop round the login window (desk.js), off the vwm desktop
   (github.com/lluppi/imre.al-vwm): a column of icons, top left, 30px down
   and 20px in as the port has it, and the earth window they open. Script
   only: there's nothing to open without it. Sizes in window pixels
   (`--px`, window.js sets it on the sheet). desk.js places each icon on
   the device pixel grid itself, so the column takes no presses, only they
   do */
.eye-desk {
	position: absolute;
	top: 0;
	left: 0;
	pointer-events: none;
}

.eye-icon {
	position: absolute;
	top: 0;
	left: 0;
	pointer-events: auto;
	appearance: none;
	-webkit-appearance: none;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: calc(4 * var(--px, 1px));
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	color: #e4e3d5;
	font:
		calc(15 * var(--px, 1px)) / calc(15 * var(--px, 1px)) "Tamzen",
		ui-monospace,
		monospace;
	-webkit-font-smoothing: none;
	cursor: default;
	user-select: none;
	-webkit-user-select: none;
	-webkit-touch-callout: none;
}

/* the port's 96px icon: desk.js paints it a device pixel to a device
   pixel, every icon pixel a whole block of them, and sizes the canvas to
   match, so nothing may scale it */
.eye-icon canvas {
	display: block;
	image-rendering: pixelated;
	image-rendering: crisp-edges;
	pointer-events: none;
}

.eye-icon span {
	padding: calc(2 * var(--px, 1px)) calc(4 * var(--px, 1px)) 0;
	line-height: calc(16 * var(--px, 1px));
}

/* selected (a press on it): the port's highlight, in the selection blue
   the icon's highlight wears (#24539c, source/icon.py) */
.eye-icon.eye-lit span {
	background: rgba(36, 83, 156, 0.55);
	color: #fffefe;
	outline: calc(1 * var(--px, 1px)) dotted rgba(255, 254, 254, 0.5);
}

.eye-icon:focus {
	outline: none;
}

.eye-icon:focus-visible span {
	outline: calc(1 * var(--px, 1px)) dotted rgba(255, 254, 254, 0.5);
}

/* where the window opens (desk.js sets it, in the middle of the screen);
   window.js moves the window off it by `left` / `top`, as it does the
   login. its box stays where the window opened, so it takes no presses:
   the window does */
.eye-earth-home {
	position: absolute;
	top: 0;
	left: 0;
	pointer-events: none;
}

/* the earth window: the login's frame (window.js paints it), a square
   client the picture fills edge to edge */
.eye-earth {
	--px: 1px;
	position: relative;
	pointer-events: auto;
	isolation: isolate;
	padding: calc(30 * var(--px)) calc(5 * var(--px)) calc(5 * var(--px));
	box-shadow: calc(2 * var(--px)) calc(2 * var(--px)) calc(6.5 * var(--px))
		rgba(0, 0, 0, 0.66);
}

/* the globe in hand (komputer/globe.js handSpin), on whole device pixels
   (desk.js trues it up by `left` / `top`) */
.eye-earth-pic {
	position: relative;
	cursor: grab;
	touch-action: none;
	user-select: none;
	-webkit-user-select: none;
}

.eye-earth-pic.kp-held {
	cursor: grabbing;
}

.eye-earth-pic canvas {
	display: block;
}
