/* ontheism.org skin. Vanilla CSS.

   Two layouts share one stage: a desktop one (the disc at 30% of the width, the text to its right)
   and a phone one, below. The phone layout applies in portrait, or below 820px wide unless the
   screen is short (a landscape phone, where the disc would fall below the fold and the desktop
   layout reads better). The same query is in main.js (PHONE_Q) and on the <picture> in index.html. */

/* Typst's default text face, Libertinus Serif (OFL; Latin, Greek and polytonic Greek in one family). */
@font-face {
	font-family: "Libertinus Serif";
	src: url("fonts/LibertinusSerif-Regular.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: block;
}
@font-face {
	font-family: "Libertinus Serif";
	src: url("fonts/LibertinusSerif-Italic.woff2") format("woff2");
	font-weight: 400;
	font-style: italic;
	font-display: block;
}

:root {
	--bg:      #05070c;
	--ink:     #e8edf8;                 /* body text */
	--muted:   #aab5cf;                 /* muted line */
	--logo:    #e6ecff;                 /* symbol and wordmark: pale blue-white */
	--glow:    #4152f5;                 /* brand blue (#1a237e), lifted to read on black */
	--glow-lo: rgba(120, 140, 255, .65);
	--cyan:    #00e5ff;
	--magenta: #ff1fd0;
	--rule:    rgba(104, 122, 240, .32); /* hairline, brand-blue tint */
	--scan:    rgba(255, 255, 255, .035);

	/* Stage: 16:9 and always covering the viewport. The disc is laid at --hf of the image width
	   and --vf of its height, and that point is placed at (--hx, --hy). With W >= 100vw the left
	   edge is at or beyond 0 and the right edge at or beyond 100vw; with W >= 177.78vh the height
	   covers 100vh. */
	--W:  max(112vw, 177.78vh);
	--H:  calc(var(--W) * 9 / 16);
	--hf: .30;
	--vf: .50;
	--hx: 30vw;
	--hy: 50vh;
	--R:  calc(var(--W) * .1125);       /* disc radius on screen: 0.2 x the stage height */
	--u:  1cqw;                          /* lockup unit: 1% of the stage width, larger on a phone */
	--dy: calc(var(--u) * .14);          /* lockup nudged so its ink centres in the disc (measured) */

	/* Corner links (Image credits, The Order, Made with AI): plate height, distance from the page bottom, and the
	   room the page reserves for the row so that nothing can lie under it. */
	--cl-h:    28px;
	--cl-b:    max(1.2vh, 10px, env(safe-area-inset-bottom, 0px));
	--cl-room: calc(var(--cl-h) + var(--cl-b) + 14px);
}

* { box-sizing: border-box; }

html {
	background: var(--bg);
	font-synthesis: none;               /* never a synthetic oblique or bold */
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	min-height: 100vh;
	-webkit-tap-highlight-color: transparent;
	position: relative;                 /* the corner links are placed against the bottom of the page */
	display: flex;
	align-items: center;
	/* The panel takes the room to the right of the ring: 1.5 radii from the disc centre, and a gap.
	   Top and bottom are equal, so the panel stays centred on the disc's line, and each holds the
	   corner links' row. */
	padding: var(--cl-room) 3vw var(--cl-room) calc(var(--hx) + var(--R) * 1.5 + 2.4vw);
	background: var(--bg);
	color: var(--ink);
	font-family: "Libertinus Serif", "Times New Roman", Times, serif;
	font-weight: 400;
	overflow-x: hidden;
}
@supports (height: 1svh) {
	body { min-height: 100svh; }        /* the small viewport, so the corner links are never below the fold */
}

/* ---------- stage and lockup ---------- */

.stage {
	position: fixed;
	z-index: 0;
	left: calc(var(--hx) - var(--W) * var(--hf));
	top:  calc(var(--hy) - var(--H) * var(--vf));
	width: var(--W);
	height: var(--H);
	container-type: inline-size;        /* children size in cqw: 1cqw = 1% of the stage width */
	background: var(--bg);
	pointer-events: none;
}
.stage .bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
	user-select: none;
}
/* A faint cool shade, heavier away from the disc, to calm the montage. */
.shade {
	position: absolute;
	inset: 0;
	background:
		radial-gradient(ellipse calc(var(--u) * 34) calc(var(--u) * 19) at calc(var(--hf) * 100%) calc(var(--vf) * 100%), rgba(5, 7, 12, 0) 55%, rgba(5, 7, 12, .30) 100%),
		linear-gradient(rgba(5, 7, 12, .10), rgba(5, 7, 12, .10));
}

.lockup {
	position: absolute;
	left: calc(var(--hf) * 100%);       /* the disc centre */
	top: calc(var(--vf) * 100%);
	transform: translate(-50%, calc(-50% + var(--dy, 0px)));
	display: grid;                      /* every layer shares one cell, so all align exactly */
	isolation: isolate;
}
.layer {
	grid-area: 1 / 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: calc(var(--u) * 1.8);
	color: var(--logo);
}
.sym {
	display: block;
	height: calc(var(--u) * 8.8);
	width: calc(var(--u) * 8.8 * 60.912 / 74.91);
	fill: currentColor;
	overflow: visible;
}
.wm {
	margin: 0;
	padding-left: .38em;                /* balances the trailing letter-space so the ink centres */
	font-size: calc(var(--u) * 1.75);
	font-weight: 400;
	line-height: 1;
	letter-spacing: .38em;
	text-transform: uppercase;
	white-space: nowrap;
}

.base .sym { filter: drop-shadow(0 0 calc(var(--u) * .32) var(--glow-lo)); }
.base .wm  { text-shadow: 0 0 calc(var(--u) * .5) var(--glow-lo); }

.glow {
	color: var(--glow);
	filter: blur(calc(var(--u) * .85));
	opacity: 0;
}
.rgb, .slice { opacity: 0; visibility: hidden; }
.rgb   { mix-blend-mode: screen; }
.rgb.c { color: var(--cyan); }
.rgb.m { color: var(--magenta); }

/* Logo states, driven by main.js. */
.js .base { opacity: 0; }
.js.booted .glow { animation: glowin 1.4s ease-out both, pulse 7s 1.4s ease-in-out infinite; }
html:not(.js) .glow { opacity: .6; }
@keyframes glowin { from { opacity: 0; } to { opacity: .55; } }
@keyframes pulse  { 0%, 100% { opacity: .55; } 50% { opacity: .85; } }

/* ---------- text panel ---------- */

.panel {
	position: relative;
	z-index: 1;
	flex: none;
	margin: 0 auto;                     /* centred in the room right of the ring */
	width: min(36em, 100%);             /* wide enough for the two links side by side, equal */
	font-size: clamp(16px, min(calc(.8vw + 6.7px), 2.35vh), 30px);
	padding: 1.8em 2.1em 1.7em;
	background: rgba(5, 7, 12, .72);
	-webkit-backdrop-filter: blur(16px) saturate(.72);
	backdrop-filter: blur(16px) saturate(.72);
	border: 1px solid var(--rule);
	box-shadow: 0 1.5em 4em rgba(0, 0, 0, .35);
	transition: border-color .12s;
}
/* Faint scanlines. */
.panel::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: repeating-linear-gradient(to bottom, var(--scan) 0 1px, transparent 1px 3px);
}
/* Corner ticks. */
.ticks {
	position: absolute;
	inset: -1px;
	pointer-events: none;
	--t: rgba(150, 170, 255, .7);
	background:
		linear-gradient(var(--t), var(--t)) 0 0       / 11px 1px no-repeat,
		linear-gradient(var(--t), var(--t)) 0 0       / 1px 11px no-repeat,
		linear-gradient(var(--t), var(--t)) 100% 0    / 11px 1px no-repeat,
		linear-gradient(var(--t), var(--t)) 100% 0    / 1px 11px no-repeat,
		linear-gradient(var(--t), var(--t)) 0 100%    / 11px 1px no-repeat,
		linear-gradient(var(--t), var(--t)) 0 100%    / 1px 11px no-repeat,
		linear-gradient(var(--t), var(--t)) 100% 100% / 11px 1px no-repeat,
		linear-gradient(var(--t), var(--t)) 100% 100% / 1px 11px no-repeat;
}
.burst .panel { border-color: rgba(120, 210, 255, .5); }

.real, .anim { font-size: 1em; line-height: 1.55; text-wrap: pretty; }   /* no one-word last lines */
.real p, .anim p { margin: 0 0 1.05em; }
.real p:last-child, .anim p:last-child { margin-bottom: 0; }

/* With scripting, the real copy is visually hidden but stays in the accessibility tree. */
.js .real {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}
html:not(.js) .anim { display: none; }

/* Animated copy: every word is laid out from the start, transparent, so nothing reflows. */
.anim { user-select: none; }
.w { position: relative; color: transparent; }
.w.on { color: var(--ink); }

.cur {
	display: inline-block;
	position: relative;
	width: 0;
	height: 0;
}
.cur::before {
	content: "";
	position: absolute;
	left: .14em;
	bottom: -.22em;
	width: .1em;
	height: 1.1em;
	background: rgba(170, 195, 255, .6);
}
.cur.blink { animation: blink 1.1s steps(1) infinite; }
.cur.fade  { animation: none; opacity: 0; transition: opacity 1.2s ease-out; }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

/* ---------- actions ---------- */

.actions {
	margin-top: 1.5em;
	padding-top: 1.25em;
	border-top: 1px solid rgba(104, 122, 240, .22);
	transition: opacity .9s ease-out, visibility 0s;
}
.js .actions:not(.in) {
	opacity: 0;
	visibility: hidden;
	transition: opacity .9s ease-out, visibility 0s .9s;
}
.btn {
	display: inline-flex;
	align-items: center;
	gap: .6em;
	padding: .55em 1.05em;
	font: inherit;
	font-size: .9em;
	font-weight: 400;
	letter-spacing: .03em;
	color: var(--ink);
	text-decoration: none;
	background: rgba(65, 82, 245, .10);
	border: 1px solid rgba(120, 138, 255, .42);
	border-radius: 0;
	cursor: pointer;
	transition: background .2s, border-color .2s, box-shadow .2s;
}
.btn:hover {
	background: rgba(65, 82, 245, .22);
	border-color: rgba(160, 175, 255, .7);
	box-shadow: 0 0 1em rgba(65, 82, 245, .35);
}
.btn:focus-visible, input:focus-visible {
	outline: 2px solid #9db0ff;
	outline-offset: 2px;
}
.sub { margin: 1.2em 0 0; }
.sub label {
	display: block;
	margin-bottom: .6em;
	font-size: .86em;
	line-height: 1.5;
	color: var(--muted);
}
.sub .row { display: flex; gap: .6em; }
.sub input {
	flex: 1 1 auto;
	min-width: 0;
	padding: .55em .8em;
	font: inherit;
	font-size: .9em;
	color: var(--ink);
	background: rgba(5, 7, 12, .55);
	border: 1px solid rgba(120, 138, 255, .32);
	border-radius: 0;
}
.sub input::placeholder { color: rgba(170, 181, 207, .55); }
.btn:disabled { opacity: .55; cursor: default; box-shadow: none; }
/* The two links above the form, always the same width. A row of equal columns, each at least as wide as
   the longer label with its icon and padding (17.2em; the label measures 16.8 to 16.95em at desktop
   sizes), so the labels never wrap; where two such columns do not fit, the row is one column and
   each link takes the full width. */
.btns {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(17.2em, 100%), 1fr));
	gap: .6em;
	font-size: .9em;
}
.btns .btn {
	justify-content: center;
	width: auto;
	font-size: 1em;
	text-align: center;
}
/* The server's answer, a quiet line under the field. On a desktop it sits in the panel's bottom
   padding, so the panel (centred on the page) neither grows nor moves when it appears. */
.sub { position: relative; }
.note {
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;
	margin: .3em 0 0;
	font-size: .86em;
	line-height: 1.5;
	color: var(--muted);
}

/* ---------- corner links ---------- */

/* Image credits at the bottom left, The Order at the bottom centre and the Made with AI mark at the
   bottom right, each a small plate on the montage. They are placed against the bottom of the page, not of the window: where the page fits
   they sit in the window's corners, and where it scrolls they follow the panel, in the room the body's
   padding reserves, so they never lie over the text or the form. No underline in any state. */
.corner {
	position: absolute;
	z-index: 2;
	bottom: var(--cl-b);
	display: inline-flex;
	align-items: center;
	gap: .6em;
	min-height: var(--cl-h);
	padding: 0 .7em;
	font-size: 13px;
	line-height: 1;
	letter-spacing: .04em;
	white-space: nowrap;
	color: rgba(214, 222, 242, .78);
	text-decoration: none;
	background: rgba(5, 7, 12, .62);
	border: 1px solid rgba(104, 122, 240, .22);
}
.corner:hover, .corner:focus-visible { color: #fff; text-decoration: none; }
.corner:hover { border-color: rgba(160, 175, 255, .6); }
.corner:focus-visible { outline: 2px solid #9db0ff; outline-offset: 2px; }
.credits-link { left: max(1.2vw, env(safe-area-inset-left, 0px)); }
.ai-link {
	right: max(1.2vw, env(safe-area-inset-right, 0px));
	padding-left: 3px;
}
.order-link {
	left: 50%;
	transform: translateX(-50%);        /* bottom centre */
	padding-left: 3px;
}
/* The Made with AI mark is black line work, which vanishes on the montage, so it sits on a pale chip;
   the Order's gold mark sits on its own blue. Each is shown as drawn, never recoloured. */
.ai-link img,
.order-link img {
	display: block;
	box-sizing: content-box;
	width: 18px;
	height: 18px;
	padding: 2px;
	background: rgba(230, 236, 255, .9);
}
.order-link img { background: #1a237e; }

/* ---------- phone layout ---------- */

/* The stage is 9:16 and fixed: the disc sits at the middle of the width and 27% of the way down,
   with the page scrolling over it. The stage is sized from the large viewport (lvh) so that it
   neither jumps nor shows a bare strip as the browser bars come and go, and it is anchored at
   the top. The text panel starts 1.55 radii below the disc centre, inside the first screen. */
@media (orientation: portrait), (max-width: 820px) and (min-height: 501px) {
	:root {
		--W:  max(100vw, 56.25vh);
		--H:  calc(var(--W) * 16 / 9);
		--hf: .50;
		--vf: .27;
		--hx: 50vw;
		--hy: calc(var(--H) * .27);
		--R:  calc(var(--W) * .2);
		--u:  calc(1cqw * 16 / 9);         /* the disc is 16/9 larger against the stage than on desktop */
		--cl-h:    36px;                   /* a comfortable touch target for the corner links */
		--cl-b:    max(10px, env(safe-area-inset-bottom, 0px));
		--cl-room: calc(var(--cl-h) + var(--cl-b) + 16px);
	}
	@supports (height: 1lvh) {
		:root { --W: max(100vw, 56.25lvh); }
	}

	body {
		display: block;
		min-height: 100vh;
		padding:
			calc(var(--hy) + var(--R) * 1.55 + 14px)
			max(16px, env(safe-area-inset-right))
			var(--cl-room)
			max(16px, env(safe-area-inset-left));
		touch-action: manipulation;
	}
	@supports (height: 1svh) {
		body { min-height: 100svh; }
	}

	.shade {
		background:
			radial-gradient(ellipse calc(var(--u) * 34) calc(var(--u) * 19) at 50% 27%, rgba(5, 7, 12, 0) 55%, rgba(5, 7, 12, .30) 100%),
			linear-gradient(rgba(5, 7, 12, .10), rgba(5, 7, 12, .10));
	}

	.panel {
		width: min(30em, 100%);
		font-size: clamp(16.5px, 4.4vw, 20px);
		padding: 1.35em 1.25em .55em;
		background: rgba(5, 7, 12, .78);
		-webkit-backdrop-filter: blur(12px) saturate(.72);
		backdrop-filter: blur(12px) saturate(.72);
	}
	.real, .anim { line-height: 1.52; }

	.actions { margin-top: 1.25em; padding-top: 1.1em; }
	.btns { font-size: 1em; }
	.btn {
		display: flex;
		justify-content: center;
		width: 100%;
		min-height: 46px;
		font-size: 1em;
		text-align: center;
	}
	.sub { margin-top: 1.1em; }
	.note { position: static; margin: .5em 0 0; min-height: 1.3em; }
	.sub .row { flex-direction: column; gap: .7em; }
	.sub input {
		width: 100%;
		min-height: 46px;
		font-size: max(16px, 1em);      /* below 16px iOS zooms the page on focus */
	}

	.credits-link { left: max(16px, env(safe-area-inset-left, 0px)); }
	.ai-link      { right: max(16px, env(safe-area-inset-right, 0px)); }
}

/* ---------- narrow phones ---------- */

/* Below 420px the three plates no longer fit in one row (at 360px they need all 328px between the
   margins), so The Order stands above Image credits, and the reserved room grows by one plate. */
@media (max-width: 419.98px) {
	:root { --cl-room: calc(var(--cl-h) * 2 + 8px + var(--cl-b) + 16px); }
	.order-link {
		left: max(16px, env(safe-area-inset-left, 0px));
		bottom: calc(var(--cl-b) + var(--cl-h) + 8px);
		transform: none;
	}
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
	.js .base { opacity: 1; }
	.js.booted .glow, .glow { animation: none; opacity: .6; }
	.rgb, .slice { display: none; }
	.cur { display: none; }
	.actions, .js .actions:not(.in) { transition: none; }
}

/* ---------- credits page ---------- */

body.credits {
	display: block;
	padding: 0;
	background:
		radial-gradient(ellipse 60vw 40vh at 18% 0%, rgba(65, 82, 245, .16), transparent 70%),
		var(--bg);
	overflow-x: auto;
}
.credits .wrap {
	max-width: 74rem;
	margin: 0 auto;
	padding: 4.5rem 2rem 5rem;
}
.credits .back {
	font-size: .85rem;
	letter-spacing: .06em;
	color: var(--muted);
	text-decoration: none;
}
.credits .back:hover { color: #fff; }
.credits h1 {
	margin: 1.4rem 0 .4rem;
	font-size: 1.5rem;
	font-weight: 400;
	letter-spacing: .42em;
	text-transform: uppercase;
	color: var(--logo);
}
.credits h2 {
	margin: 2.4rem 0 .7rem;
	font-size: 1.05rem;
	font-weight: 400;
	letter-spacing: .08em;
	color: var(--logo);
}
.credits p { margin: .6rem 0; max-width: 46rem; line-height: 1.6; color: var(--ink); }
.credits a { color: #b9c6ff; text-underline-offset: .18em; text-decoration-color: rgba(185, 198, 255, .4); }
.credits a:hover { color: #fff; text-decoration-color: currentColor; }
.credits table { width: 100%; margin-top: 1rem; border-collapse: collapse; font-size: .9rem; line-height: 1.45; }
.credits th {
	position: sticky;
	top: 0;
	padding: .6rem .8rem;
	text-align: left;
	font-weight: 400;
	font-size: .78rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--muted);
	background: #080b14;
	border-bottom: 1px solid var(--rule);
}
.credits td { padding: .5rem .8rem; vertical-align: top; border-bottom: 1px solid rgba(104, 122, 240, .12); }
.credits td:nth-child(4), .credits td:nth-child(5) { white-space: nowrap; }
.credits td.n { width: 3rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.credits tbody tr:hover td { background: rgba(65, 82, 245, .07); }
.credits .fonts { color: var(--muted); font-size: .9rem; }
@media (max-width: 720px) {
	.credits .wrap { padding: 2.2rem 1.1rem 3rem; }
	.credits h1 { letter-spacing: .3em; }
	.credits table, .credits tbody, .credits tr, .credits td { display: block; }
	.credits thead { display: none; }
	.credits tr { padding: .75rem 0; border-bottom: 1px solid rgba(104, 122, 240, .16); }
	.credits td { display: inline; padding: 0; border: 0; }
	.credits td.n { display: none; }
	.credits td:nth-child(2) { display: block; margin-bottom: .15rem; color: var(--logo); }
	.credits td:nth-child(3)::after, .credits td:nth-child(4)::after { content: " \00b7  "; color: var(--muted); }
	.credits tbody tr:hover td { background: none; }
}
