:root { --accent: #e5383b;
	--dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' shape-rendering='crispEdges' fill-opacity='.36'%3E%3Cpath d='M0 0h1v1H0zM2 0h1v3H2zM0 2h1v2H0z'/%3E%3C/svg%3E"); }
body { margin: 0; background: #0a0a0b; color: #ece8df; font-family: Verdana, sans-serif; font-size: 13px; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* The menu's style (menu.cpp) at UI scale 1. Verdana 13 px ImGui line height = 10.7 px CSS, 17 px rows; the Void & Bone
   neutrals and the default red accent (nihilo Core/core_theme.hpp, Config menu.ascent), skrt dot texture, square cards with a slim title strip, square controls (the knob is the menu's only round shape). The window fills the
   viewport. */
#win { --winBg: #121213; --head: #0f0f10; --panel: #121213; --line: #222224; --field: #1a1a1c; --fieldLine: #2d2d30;
	--text: #ece8df; --dimText: #8f8c86; --mute: #5c5a56; --bad: #e8776d; --warn: #e3b261; --accentLine: color-mix(in srgb, var(--accent) 55%, var(--fieldLine));
	--boxTop: #2a2a2d; --boxBottom: #161618; /* the checkbox's off gradient (menu.cpp kStyle.checkOff), also on buttons and dropdowns */ }
#win { position: relative; min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; background: var(--winBg); font-size: 10.7px; line-height: 17px; overflow: hidden; }
/* Header (the menu rework's): title left; the logged-in user and logout right. Shown only when logged in: it drops in
   from the top when the login opens the main page. */
.header { display: flex; align-items: center; flex: none; height: 32px; box-sizing: border-box; padding: 0 10px; background: var(--head); border-bottom: 1px solid var(--line); user-select: none; }
.title { flex: 1; display: flex; align-items: center; font-size: 12.34px; font-weight: bold; letter-spacing: 0.06em; }
/* The Nihilo wordmark (nihilo Menu/menu_mark.hpp, tools/menu_preview/template.html): NIHIL and the ring in the text
   color, the slash in the accent. 299 x 64 units, 60 per cap height at 1.25 x Verdana Bold's cap height. */
.wordmark { display: block; flex: none; color: var(--text); }
.wordmark .slash { stroke: var(--accent); }
/* Easter egg (app.js, 1 page load in 100): the slash cycles slowly through the rainbow. All stops have the same
   lightness, so only the hue moves: no bright and dark pulses. */
.rainbow .wordmark .slash { animation: rainbow 12s linear infinite; }
@keyframes rainbow { 0%, 100% { stroke: oklch(0.7 0.16 25); } 12.5% { stroke: oklch(0.7 0.16 65); } 25% { stroke: oklch(0.7 0.16 100); } 37.5% { stroke: oklch(0.7 0.16 145); } 50% { stroke: oklch(0.7 0.16 195); } 62.5% { stroke: oklch(0.7 0.16 250); } 75% { stroke: oklch(0.7 0.16 295); } 87.5% { stroke: oklch(0.7 0.16 340); } }
.title .wordmark { height: 0.9693em; width: 4.5284em; }
/* The big wordmark above the log in and sign up panel. At login it flies into the header's wordmark. */
.jumbo { justify-self: center; width: min(520px, calc(100vw - 32px)); height: auto; aspect-ratio: 299 / 64; margin-bottom: 30px; }
.who { display: flex; gap: 10px; color: var(--mute); white-space: nowrap; }
a.link { text-decoration: none; }
/* Header and inline links are buttons (keyboard reachable) drawn as text. The name keeps its color; only hover and
   keyboard focus show the accent. */
button.link, button.name { background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }
button.name { color: var(--text); }
button.name:hover, button.name:focus-visible { color: var(--accent); outline: none; }
/* Content background: the skrt 4x4 dot mask, black at 0.36 alpha, pinned to the viewport. */
.content { flex: 1; padding: 20px 10px; display: grid; gap: 10px; background: var(--dots) 0 0 / 4px 4px fixed, #121213; image-rendering: pixelated; }
.content.auth { grid-template-columns: 300px; justify-content: center; align-content: center; }
/* Log in and sign up: the panel sits in the middle row, so the panel (not the logo and panel together) is centered;
   the logo sits at the bottom of the row above it. A short window grows the top row instead of overlapping. */
#pageAuth { grid-template-rows: 1fr auto 1fr; }
#pageAuth .jumbo { align-self: end; }
.content.column { grid-template-columns: minmax(0, 760px); justify-content: center; align-content: start; }
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
/* Invite banner (main page): a card strip with an accent tint and a 2 px accent bar. */
.banner { display: flex; gap: 10px; align-items: center; padding: 6px 10px; background: color-mix(in srgb, var(--accent) 10%, var(--panel)); border: 1px solid var(--line); box-shadow: inset 2px 0 0 var(--accent); }
/* Page morph (morph): frames that fly from one page's panels to the next page's panels. No page has its own
   rise-in; a second entrance after a morph would bounce. */
.ghost { position: absolute; margin: 0; box-sizing: border-box; pointer-events: none; z-index: 1; }
.ghost.top { z-index: 2; }
/* Panel: a square card, 88% opaque (the dots show through), with a title strip inside it. */
.panel { min-width: 0; background: color-mix(in srgb, var(--panel) 88%, transparent); border: 1px solid var(--line); }
/* Title strip: 16 px plus the hairline. The capitals start 4 px down (text-box trims the line to cap top and
   baseline), which leaves 5 px under them: all-caps text looks centered with about 1 px more space below. */
.ptitle { position: relative; box-sizing: border-box; height: 17px; padding: 4px 10px 0; border-bottom: 1px solid var(--line); white-space: nowrap; font-size: 9.9px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--dimText); text-box: trim-both cap alphabetic; }
.ptitle::before { content: ""; position: absolute; left: 0; top: 4px; height: 7px; width: 2px; background: var(--accent); }
.body { padding: 6px 10px 8px; }
.row { display: flex; align-items: center; height: 17px; margin-bottom: 4px; }
.row .k { width: 140px; color: var(--dimText); }
.row .v { flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.dim { color: var(--mute); margin-bottom: 6px; }
.link { color: var(--accent); cursor: pointer; }
.link:hover, .link:focus-visible { text-decoration: underline; outline: none; }
/* Log in <-> Sign up: the repeat-password field opens (0fr to 1fr) while the texts fade out, swap, and fade in. */
.more { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows 0.3s ease, opacity 0.3s ease; }
.more > div { min-height: 0; overflow: hidden; }
.signup .more { grid-template-rows: 1fr; opacity: 1; }
.swap { transition: opacity 0.15s; }
.fading .swap { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .more, .swap { transition: none; } }
/* Button (menu.cpp ButtonFace): the checkbox's off gradient, hairline border, normal weight; hover = accent border
   and white text; pressed = the flat accent press fill. Loader size: full width, 30 px. */
.btn { display: flex; align-items: center; justify-content: center; width: 100%; height: 30px; margin-bottom: 6px; padding: 0; background: linear-gradient(var(--boxTop), var(--boxBottom)); border: 1px solid var(--fieldLine); color: var(--text); font: inherit; cursor: pointer; }
.btn:hover:not(:disabled) { border-color: var(--accent); color: #fff; }
.btn:active:not(:disabled) { background: color-mix(in srgb, var(--accent) 18%, var(--field)); }
/* Answers shown on the button, the loader's Status colors. */
.btn.ready, .btn.ready:hover:not(:disabled) { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, var(--fieldLine)); }
.btn.ok, .btn.ok:disabled { color: var(--accent); }
.btn.bad { color: var(--bad); }
.btn.warn { color: var(--warn); }
.btn:disabled { color: var(--mute); cursor: default; }
.btn.run::after, .log .run::after { content: "."; animation: dots 1.2s steps(1, end) infinite; }
@keyframes dots { 0% { content: "."; } 33.33% { content: ".."; } 66.67% { content: "..."; } }
/* Text field (the menu rework's): flat square field, hairline border, accent border on focus. */
input.txt, select.txt, textarea.txt { display: block; width: 100%; height: 24px; margin-bottom: 6px; box-sizing: border-box; background: var(--field); border: 1px solid var(--fieldLine); color: var(--text); font: inherit; padding: 0 7px; outline: none; }
textarea.txt { height: 110px; padding: 3px 7px; resize: vertical; }
/* Dropdown (menu.cpp BeginDropdown): the button's gradient, accentLine border while hovered, a dimText chevron 10 px
   from the right end. The field color under the gradient colors the native option list. */
select.txt { appearance: none; padding-right: 20px; cursor: pointer; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='4'%3E%3Cpath d='M.5.5l3 3 3-3' fill='none' stroke='%238f8c86'/%3E%3C/svg%3E") no-repeat right 6px center, linear-gradient(var(--boxTop), var(--boxBottom)) var(--field); }
select.txt:hover { border-color: var(--accentLine); }
input.txt::placeholder, textarea.txt::placeholder { color: var(--mute); }
input.txt:focus, select.txt:focus, textarea.txt:focus { border-color: var(--accent); }
input.txt:disabled { color: var(--mute); }
/* Changelog: release list (the menu rework's list: sunken field; the selected row has an accent tint and a 2 px
   accent bar) beside the selected release's notes. */
.cl { display: grid; grid-template-columns: 220px 1fr; gap: 10px; }
.list { background: #0e0e0f; border: 1px solid var(--line); padding: 2px 0; user-select: none; align-self: start; }
.list div { display: flex; padding: 0 8px; line-height: 17px; cursor: pointer; color: var(--dimText); }
.list div:hover { background: #1a1a1c; color: var(--text); }
.list div.sel { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--text); box-shadow: inset 2px 0 0 var(--accent); }
.list .ch { width: 70px; color: var(--mute); }
.list .d { margin-left: auto; color: var(--mute); font-variant-numeric: tabular-nums; }
/* Invite list: available codes copy on click; used codes are dim and inert. Codes stay selectable. */
.list.inv { user-select: text; margin-bottom: 6px; }
.list div.used { color: var(--mute); cursor: default; }
.list div.used:hover { background: none; }
.notes b { display: block; font-weight: normal; color: var(--text); }
.notes ul { margin: 0; padding-left: 16px; color: var(--dimText); }
.notes li { margin-bottom: 3px; }
/* Legal page: the changelog's list beside the document. Headings at the text color, the rest dim. Bracketed
   placeholders (the operator's details) are in the warn color until filled in. */
.doc { color: var(--dimText); }
.doc h4 { margin: 12px 0 2px; font-size: inherit; font-weight: normal; color: var(--text); }
.doc .name, .doc code { font: inherit; color: var(--text); }
.doc p { margin: 0 0 6px; }
.doc ul { margin-bottom: 6px; }
.ph { color: var(--warn); }
/* Sign-up terms box: the menu's checkbox (template.html .box): 8 px square, gray gradient, accent when on; hover and
   focus: the accentLine border (the accent 55% into the hairline). */
.agree { display: flex; align-items: flex-start; gap: 5px; margin-bottom: 6px; color: var(--dimText); cursor: pointer; }
.agree input { appearance: none; flex: none; width: 8px; height: 8px; margin: 4px 0 0; background: linear-gradient(var(--boxTop), var(--boxBottom)); border: 1px solid var(--fieldLine); box-sizing: border-box; cursor: pointer; }
.agree:hover input, .agree input:focus-visible { border-color: var(--accentLine); outline: none; }
.agree input:checked { background: linear-gradient(var(--accent), color-mix(in srgb, var(--accent) 65%, #000)); border-color: var(--accent); }
/* Footer: the header's strip under every page, with the Lua API and legal links. */
.foot { display: flex; flex-wrap: wrap; gap: 0 14px; flex: none; padding: 4px 10px; background: var(--head); border-top: 1px solid var(--line); color: var(--mute); }
.foot > span { margin-right: auto; }
.foot .link { color: var(--dimText); }
.foot .link:hover, .foot .link:focus-visible { color: var(--accent); }
/* Status log: the loader rework's Status box. Warnings and errors get a tinted row with a 2 px bar in their color. */
.log { height: 110px; overflow-y: auto; background: #0e0e0f; border: 1px solid var(--line); padding: 3px 0; }
.log div { padding: 0 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--dimText); }
.log .t { float: right; color: var(--mute); font-variant-numeric: tabular-nums; }
.log .ok { color: var(--accent); }
.log .idle { color: var(--mute); }
.log .warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 8%, transparent); box-shadow: inset 2px 0 0 var(--warn); }
.log .bad { color: var(--bad); background: color-mix(in srgb, var(--bad) 8%, transparent); box-shadow: inset 2px 0 0 var(--bad); }
/* Scrollbar (the menu rework's): 4 px, square, accent on hover. */
.log::-webkit-scrollbar, .list.scroll::-webkit-scrollbar { width: 4px; }
.log::-webkit-scrollbar-track, .list.scroll::-webkit-scrollbar-track { background: transparent; }
.log::-webkit-scrollbar-thumb, .list.scroll::-webkit-scrollbar-thumb { background: #343437; min-height: 18px; }
.log::-webkit-scrollbar-thumb:hover, .list.scroll::-webkit-scrollbar-thumb:hover { background: var(--accent); }
/* Admin page: the tab strip (selected = accent tint and a 2 px accent bar, like the list's selected row), a result line
   under it, button grids, and small tags on list rows. */
.content.column.wide { grid-template-columns: minmax(0, 980px); }
.tabpage { display: grid; gap: 10px; align-content: start; }
.tabs { display: flex; flex-wrap: wrap; background: color-mix(in srgb, var(--panel) 88%, transparent); border: 1px solid var(--line); }
.tabs button { height: 24px; padding: 0 14px; background: none; border: 0; color: var(--dimText); font: inherit; cursor: pointer; }
.tabs button:hover, .tabs button:focus-visible { background: #1a1a1c; color: var(--text); outline: none; }
.tabs button.sel { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--text); box-shadow: inset 0 -2px 0 var(--accent); }
.amsg { padding: 0 10px; background: var(--panel); border: 1px solid var(--line); color: var(--dimText); }
.amsg.ok { color: var(--accent); box-shadow: inset 2px 0 0 var(--accent); }
.amsg.warn { color: var(--warn); box-shadow: inset 2px 0 0 var(--warn); }
.amsg.bad { color: var(--bad); box-shadow: inset 2px 0 0 var(--bad); }
.btns { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6px; }
.btns.four { grid-template-columns: repeat(4, 1fr); }
.btns .full { grid-column: 1 / -1; }
.list.scroll { max-height: 230px; overflow-y: auto; margin-bottom: 6px; }
.list .tag { margin-left: 8px; color: var(--mute); }
.list .tag.warn { color: var(--warn); }
.list .tag.bad { color: var(--bad); }
.agree input:disabled { opacity: 0.45; cursor: default; }
.list.scroll div > * { white-space: nowrap; }
.list.scroll .ch { flex: none; }
.list.narrow .d, .list.narrow .tag { display: none; }
/* Values in the state colors. */
.v.ok { color: var(--accent); }
.v.warn { color: var(--warn); }
.v.bad { color: var(--bad); }
.warnText { color: var(--warn); }
/* Ban screen: the reason in a sunken box with a 2 px bar in the bad color; the panel's title bar is bad too. */
#banPanel .ptitle::before { background: var(--bad); }
.banReason { margin-bottom: 6px; padding: 3px 8px; background: #0e0e0f; border: 1px solid var(--line); box-shadow: inset 2px 0 0 var(--bad); color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.perm { color: var(--text); }
[hidden] { display: none !important; }
/* Touch screens: the menu's 17 px rows are too small to read and tap, so scale text and targets up. Text fields
   use 16 px so iOS does not zoom in on focus. Same colors, frames and dots. */
@media (max-width: 640px), (pointer: coarse) {
	#win { font-size: 14px; line-height: 22px; }
	/* Header wraps: a long name (16 chars) plus logout moves under the title instead of past the edge. */
	.header { height: auto; min-height: 48px; flex-wrap: wrap; column-gap: 12px; padding: 0 12px; }
	.title { font-size: 17px; }
	.who { gap: 0 14px; flex-wrap: wrap; white-space: normal; min-width: 0; }
	.who button, .who a { display: inline-flex; align-items: center; min-height: 44px; overflow-wrap: anywhere; }
	/* Title strip at 12 px capitals (about 9 px tall): 7 px above, 8 px below. */
	.ptitle { height: 25px; padding: 7px 12px 0; font-size: 12px; }
	.ptitle::before { top: 7px; height: 9px; }
	.body { padding: 8px 12px 10px; }
	/* Widths in em so larger system text sizes still fit; long values wrap. */
	.row { height: auto; min-height: 24px; }
	.row .k { flex: 0 1 10em; width: auto; min-width: 0; padding-right: 8px; box-sizing: border-box; overflow-wrap: anywhere; }
	.row .v { min-width: 0; white-space: normal; overflow-wrap: anywhere; }
	.dim { margin-bottom: 10px; }
	button.link { min-height: 36px; }
	.btn { height: auto; min-height: 46px; margin-bottom: 10px; font-size: 15px; }
	input.txt, select.txt { height: 44px; margin-bottom: 10px; font-size: 16px; padding: 0 10px; }
	select.txt { padding-right: 22px; }
	textarea.txt { height: 150px; margin-bottom: 10px; font-size: 16px; padding: 8px 10px; }
	.tabs button { min-height: 40px; }
	.amsg { padding: 4px 12px; }
	.agree input { width: 16px; height: 16px; margin-top: 3px; }
	.foot { padding: 4px 12px; }
	.list div { flex-wrap: wrap; align-items: center; column-gap: 8px; min-height: 40px; line-height: 22px; padding: 0 10px; overflow-wrap: anywhere; }
	.list .ch { width: 6.5em; flex: none; }
	.log { height: auto; min-height: 170px; max-height: 60vh; }
	.log div { padding: 2px 10px; white-space: normal; overflow-wrap: anywhere; }
	.banner { flex-wrap: wrap; padding: 8px 12px; }
}
/* Phones: one column. */
@media (max-width: 640px) {
	.content { padding: 14px 8px; }
	.content.auth { grid-template-columns: minmax(0, 380px); }
	/* Phones keep the logo and panel centered together. */
	#pageAuth { grid-template-rows: none; }
	.jumbo { margin-bottom: 20px; }
	.pair, .cl { grid-template-columns: minmax(0, 1fr); }
	.btns.four { grid-template-columns: 1fr 1fr; }
}
