/* site.css -- the whole look of the site, in one file.

A NOTE ON WHY THIS IS BUILT THE WAY IT IS. The game it describes is played
entirely by ear by people who in many cases cannot see this page at all. So the
markup underneath is real: headings in order, lists that are lists, buttons that
are buttons, one h1 per page, and every live region announced when it changes.
Nothing here is decorative markup with a role bolted on afterwards.

Which also means the visual design has to do its work without carrying meaning
on its own. Nothing is distinguished by colour alone -- a live server says
"live", an offline one says "offline", and the dot beside the word is the
decoration rather than the message. */

:root {
	--bg: #0a0d10;
	--bg-raised: #11161b;
	--bg-panel: #151b22;
	--bg-inset: #0d1216;
	--line: #232c35;
	--line-bright: #33404c;
	--text: #dee5ec;
	--text-dim: #93a1ae;
	--text-faint: #6b7783;
	--amber: #f2a71b;
	--amber-dim: #a8741a;
	--cyan: #57c4dd;
	--cyan-dim: #2c6b7a;
	--live: #55d98a;
	--dead: #f0736b;
	--warn: #f2a71b;
	--radius: 6px;
	--mono: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;
	--sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--wide: 1200px;
	--rail: 400px;
	--head-h: 58px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	* { animation: none !important; transition: none !important; }
}

body {
	margin: 0;
	background: var(--bg);
	color: var(--text);
	font-family: var(--sans);
	font-size: 17px;
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
}

/* The one thing a keyboard user needs before anything else. */
.skip {
	position: absolute;
	left: -9999px;
	top: 0;
	background: var(--amber);
	color: #000;
	padding: .7rem 1.2rem;
	z-index: 100;
	font-weight: 600;
}
.skip:focus { left: 0; }

a { color: var(--cyan); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: #8fdcef; }

:focus-visible {
	outline: 2px solid var(--amber);
	outline-offset: 2px;
	border-radius: 3px;
}

h1, h2, h3, h4 {
	line-height: 1.2;
	letter-spacing: -0.015em;
	margin: 0 0 .6rem;
	font-weight: 650;
}
h1 { font-size: clamp(2rem, 4.4vw, 3rem); }
h2 { font-size: clamp(1.4rem, 2.6vw, 1.85rem); margin-top: 2.6rem; }
h3 { font-size: 1.18rem; margin-top: 1.8rem; }
h4 { font-size: 1rem; margin-top: 1.3rem; color: var(--text-dim); }
p { margin: 0 0 1.1rem; }

code, kbd, samp, pre { font-family: var(--mono); font-size: .92em; }
code {
	background: var(--bg-inset);
	border: 1px solid var(--line);
	border-radius: 3px;
	padding: .08em .38em;
}
pre {
	background: var(--bg-inset);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: 1rem 1.1rem;
	overflow-x: auto;
	line-height: 1.5;
}
pre code { background: none; border: 0; padding: 0; }

kbd {
	background: var(--bg-raised);
	border: 1px solid var(--line-bright);
	border-bottom-width: 2px;
	border-radius: 4px;
	padding: .12em .45em;
	font-size: .84em;
	color: var(--text);
	white-space: nowrap;
}

hr { border: 0; border-top: 1px solid var(--line); margin: 2.5rem 0; }

blockquote {
	margin: 1.4rem 0;
	padding: .1rem 0 .1rem 1.2rem;
	border-left: 3px solid var(--amber-dim);
	color: var(--text-dim);
}

/* ---- the shell ------------------------------------------------------- */

.wrap { max-width: var(--wide); margin: 0 auto; padding: 0 1.4rem; }
.wrap-narrow { max-width: 780px; margin: 0 auto; padding: 0 1.4rem; }

header.site {
	position: sticky;
	top: 0;
	z-index: 40;
	background: rgba(10, 13, 16, .93);
	backdrop-filter: blur(10px);
	border-bottom: 1px solid var(--line);
}
header.site .wrap {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: 1.4rem;
	min-height: var(--head-h);
}
.brand {
	font-weight: 700;
	letter-spacing: .02em;
	color: var(--text);
	text-decoration: none;
	font-size: 1.02rem;
	white-space: nowrap;
}
.brand span { color: var(--amber); }
nav.site ul {
	display: flex;
	gap: .3rem;
	list-style: none;
	margin: 0;
	padding: 0;
	flex-wrap: wrap;
}
nav.site a {
	display: block;
	padding: .38rem .7rem;
	border-radius: 4px;
	color: var(--text-dim);
	text-decoration: none;
	font-size: .92rem;
}
nav.site a:hover { background: var(--bg-raised); color: var(--text); }
nav.site a[aria-current="page"] {
	color: var(--amber);
	background: var(--bg-raised);
}

/* The narrow-screen menu.

   THE NAV IS SEVEN LINKS AND THE HEADER ALSO CARRIES A LIVE BADGE, which at
   anything under about a thousand pixels used to wrap into a second and
   sometimes a third row and push the page down the screen. Below that width the
   links go behind one button instead.

   It is a button and a list, not a "hamburger": it says Menu, it carries
   aria-expanded, and it is in the tab order in the same place the links were.
   The list is still in the markup either way, so a page with scripting off has
   its navigation. */
.navtoggle {
	display: none;
	font: inherit;
	font-size: .88rem;
	gap: .45rem;
	align-items: center;
	background: var(--bg-raised);
	border: 1px solid var(--line);
	border-radius: 5px;
	color: var(--text);
	padding: .34rem .7rem;
	cursor: pointer;
}
.navtoggle:hover { border-color: var(--line-bright); }
.navtoggle .bars {
	display: block;
	width: 14px;
	height: 2px;
	background: currentColor;
	box-shadow: 0 -5px 0 currentColor, 0 5px 0 currentColor;
}

@media (max-width: 1000px) {
	/* Every placement is explicit here. Auto-placement will not put a
	   full-width item back on row one once it has moved past it, so the badge
	   and the button would end up on a third row of their own. */
	header.site .wrap { grid-template-columns: auto 1fr auto auto; }
	.brand { grid-row: 1; grid-column: 1; }
	.pulse { grid-row: 1; grid-column: 3; }
	.navtoggle { grid-row: 1; grid-column: 4; display: inline-flex; }
	nav.site {
		grid-row: 2;
		grid-column: 1 / -1;
		display: none;
		padding-bottom: .7rem;
	}
	nav.site.open { display: block; }
	nav.site ul { flex-direction: column; gap: 0; }
	nav.site a { padding: .55rem .7rem; border-radius: 5px; }
}

/* The live badge in the header: on every page, because "is anybody playing"
   is the question the site is most often opened to answer. */
.pulse {
	margin-left: auto;
	display: flex;
	align-items: center;
	gap: .5rem;
	font-size: .86rem;
	font-family: var(--mono);
	color: var(--text-dim);
	text-decoration: none;
	border: 1px solid var(--line);
	border-radius: 999px;
	padding: .28rem .8rem .28rem .6rem;
	white-space: nowrap;
}
.pulse:hover { border-color: var(--line-bright); color: var(--text); }
.dot {
	width: 8px; height: 8px;
	border-radius: 50%;
	background: var(--text-faint);
	flex: none;
}
.dot.live { background: var(--live); box-shadow: 0 0 0 3px rgba(85, 217, 138, .16); }
.dot.dead { background: var(--dead); }
.dot.unknown { background: var(--text-faint); }

footer.site {
	border-top: 1px solid var(--line);
	margin-top: 5rem;
	padding: 2.5rem 0 3.5rem;
	color: var(--text-faint);
	font-size: .9rem;
}
footer.site a { color: var(--text-dim); }
footer.site .cols {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
	gap: 1.6rem 2rem;
	margin-bottom: 2rem;
}
footer.site h2 {
	font-size: .78rem;
	text-transform: uppercase;
	letter-spacing: .1em;
	color: var(--text-dim);
	margin: 0 0 .6rem;
}
footer.site ul { list-style: none; margin: 0; padding: 0; }
footer.site li { margin-bottom: .3rem; }

main { padding-top: 2.4rem; }

/* A quiet rule above each major section of a page.

   NOT A BOX AND NOT A COLOUR. These pages are long and every heading in them
   was the same weight as every other, so nothing said where one subject ended
   and the next began. A hairline does, costs nothing to a screen reader, and
   does not turn the page into a stack of cards. */
main > .wrap > section + section,
main > .wrap > section + p.faint {
	border-top: 1px solid var(--line);
	padding-top: 2.2rem;
	margin-top: 2.6rem;
}
main > .wrap > section + section > h2:first-child,
main > .wrap > section > h2:first-child { margin-top: 0; }

/* ---- page headers ---------------------------------------------------- */

.page-head { margin-bottom: 2.5rem; }
.eyebrow {
	font-family: var(--mono);
	font-size: .76rem;
	text-transform: uppercase;
	letter-spacing: .16em;
	color: var(--amber);
	margin: 0 0 .7rem;
}
.lede {
	font-size: 1.18rem;
	color: var(--text-dim);
	max-width: 60ch;
	margin-bottom: 0;
}

/* ---- panels and cards ------------------------------------------------ */

.panel {
	background: var(--bg-panel);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: 1.4rem 1.5rem;
}
.panel > :last-child { margin-bottom: 0; }
.panel > h2:first-child, .panel > h3:first-child { margin-top: 0; }

.grid {
	display: grid;
	gap: 1.1rem;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

.card {
	display: block;
	background: var(--bg-panel);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: 1.3rem 1.4rem;
	text-decoration: none;
	color: inherit;
}
a.card {
	transition: border-color .12s ease, background-color .12s ease, transform .12s ease;
}
a.card:hover {
	border-color: var(--amber-dim);
	background: var(--bg-raised);
	transform: translateY(-1px);
}
.card h3 { margin: 0 0 .4rem; font-size: 1.1rem; color: var(--text); }
.card p { margin: 0; color: var(--text-dim); font-size: .95rem; }
.card .tag {
	display: inline-block;
	font-family: var(--mono);
	font-size: .7rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--amber);
	margin-bottom: .5rem;
}

/* ---- numbers --------------------------------------------------------- */

.stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: 1px;
	background: var(--line);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	overflow: hidden;
}
.stat { background: var(--bg-panel); padding: 1rem 1.1rem; }
.stat .n {
	display: block;
	font-family: var(--mono);
	font-size: 1.9rem;
	font-weight: 600;
	line-height: 1.1;
	color: var(--text);
	font-variant-numeric: tabular-nums;
}
.stat .n.zero { color: var(--text-faint); }
.stat .k {
	display: block;
	font-size: .78rem;
	text-transform: uppercase;
	letter-spacing: .08em;
	color: var(--text-faint);
	margin-top: .3rem;
}

/* ---- tables ---------------------------------------------------------- */

.table-scroll { overflow-x: auto; margin: 1.4rem 0; }
table {
	border-collapse: collapse;
	width: 100%;
	font-size: .94rem;
	min-width: 460px;
}
th, td {
	text-align: left;
	padding: .62rem .85rem;
	border-bottom: 1px solid var(--line);
	vertical-align: top;
}
th {
	color: var(--text-dim);
	font-weight: 600;
	font-size: .8rem;
	text-transform: uppercase;
	letter-spacing: .07em;
	border-bottom-color: var(--line-bright);
}
tbody tr:hover td { background: var(--bg-raised); }

/* ---- status ---------------------------------------------------------- */

.status-strip {
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--bg-panel);
	overflow: hidden;
}
.status-strip .bar {
	display: flex;
	align-items: center;
	gap: .7rem;
	padding: .8rem 1.2rem;
	border-bottom: 1px solid var(--line);
	background: var(--bg-inset);
	font-family: var(--mono);
	font-size: .87rem;
	flex-wrap: wrap;
}
.status-strip .bar .age { color: var(--text-faint); margin-left: auto; }
.status-strip .body { padding: 1.2rem; }

.rows { list-style: none; margin: 0; padding: 0; }
.rows > li {
	padding: .8rem 0;
	border-bottom: 1px solid var(--line);
}
.rows > li:last-child { border-bottom: 0; padding-bottom: 0; }
.rows > li:first-child { padding-top: 0; }

.row-head {
	display: flex;
	align-items: baseline;
	gap: .6rem;
	flex-wrap: wrap;
}
.row-head strong { font-size: 1.02rem; }
.row-sub { color: var(--text-dim); font-size: .92rem; margin-top: .15rem; }

.pill {
	display: inline-block;
	font-family: var(--mono);
	font-size: .72rem;
	letter-spacing: .05em;
	text-transform: uppercase;
	padding: .12rem .5rem;
	border-radius: 999px;
	border: 1px solid var(--line-bright);
	color: var(--text-dim);
	white-space: nowrap;
}
.pill.open { border-color: var(--live); color: var(--live); }
.pill.shut { border-color: var(--line-bright); color: var(--text-faint); }
.pill.hot { border-color: var(--amber); color: var(--amber); }
.pill.away { border-color: var(--line-bright); color: var(--text-faint); }
.pill.staff { border-color: var(--cyan-dim); color: var(--cyan); }

.empty {
	color: var(--text-faint);
	font-style: italic;
	margin: 0;
}

.notice {
	border: 1px solid var(--line-bright);
	border-left: 3px solid var(--amber);
	background: var(--bg-inset);
	border-radius: var(--radius);
	padding: .9rem 1.1rem;
	color: var(--text-dim);
	font-size: .94rem;
	margin: 1.2rem 0;
}
.notice.bad { border-left-color: var(--dead); }
.notice > :last-child { margin-bottom: 0; }

/* The message of the day, presented as the server's own words rather than as
   site copy, because that is what it is. */
.motd {
	white-space: pre-wrap;
	font-size: .98rem;
	color: var(--text-dim);
	margin: 0;
	max-height: 21rem;
	overflow-y: auto;
}
.motd strong { color: var(--text); }

/* ---- buttons --------------------------------------------------------- */

.btn {
	display: inline-block;
	font: inherit;
	font-size: .95rem;
	font-weight: 550;
	padding: .58rem 1.15rem;
	border-radius: var(--radius);
	border: 1px solid var(--line-bright);
	background: var(--bg-raised);
	color: var(--text);
	cursor: pointer;
	text-decoration: none;
}
.btn:hover { border-color: var(--amber-dim); background: var(--bg-panel); }
.btn.primary {
	background: var(--amber);
	border-color: var(--amber);
	color: #16110a;
}
.btn.primary:hover { background: #ffb92e; border-color: #ffb92e; }
.btn.small { font-size: .85rem; padding: .35rem .8rem; }

.actions { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: 1.6rem; }

/* ---- the map list ---------------------------------------------------- */

/* A wall of buttons, one per map, and the description opens directly beneath
   them rather than on a page of its own. The whole point is that choosing
   another map is one press away from reading this one. */
.map-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
	gap: .55rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.map-btn {
	display: block;
	width: 100%;
	text-align: left;
	font: inherit;
	background: var(--bg-panel);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: .7rem .85rem;
	color: var(--text);
	cursor: pointer;
	line-height: 1.35;
}
.map-btn:hover { border-color: var(--line-bright); background: var(--bg-raised); }
.map-btn .mt { display: block; font-weight: 570; font-size: .97rem; }
.map-btn .ms {
	display: block;
	font-family: var(--mono);
	font-size: .72rem;
	letter-spacing: .04em;
	color: var(--text-faint);
	text-transform: uppercase;
	margin-top: .2rem;
}
.map-btn[aria-expanded="true"] {
	border-color: var(--amber);
	background: var(--bg-raised);
	box-shadow: inset 3px 0 0 var(--amber);
}
.map-btn[aria-expanded="true"] .ms { color: var(--amber); }
.map-btn.gap .mt { color: var(--text-dim); }

/* The panel that opens under the list. */
.map-panel {
	margin-top: 1.4rem;
	border: 1px solid var(--line-bright);
	border-top: 2px solid var(--amber);
	border-radius: var(--radius);
	background: var(--bg-panel);
	scroll-margin-top: calc(var(--head-h) + 1.4rem);
}
.map-panel[hidden] { display: none; }
.map-panel .ph {
	display: flex;
	align-items: flex-start;
	gap: 1rem;
	padding: 1.2rem 1.4rem;
	border-bottom: 1px solid var(--line);
	background: var(--bg-inset);
	border-radius: var(--radius) var(--radius) 0 0;
}
.map-panel .ph h2 { margin: 0; font-size: 1.5rem; }
.map-panel .ph .meta {
	font-family: var(--mono);
	font-size: .78rem;
	color: var(--text-faint);
	margin-top: .35rem;
	display: flex;
	gap: .5rem;
	flex-wrap: wrap;
}
.map-panel .close { margin-left: auto; flex: none; }
.map-panel .pb { padding: 1.4rem 1.6rem 1.7rem; }
.map-panel .pb > :last-child { margin-bottom: 0; }
.map-panel .pb h3 {
	font-family: var(--mono);
	font-size: .8rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--amber);
	margin: 2rem 0 .8rem;
	padding-bottom: .4rem;
	border-bottom: 1px solid var(--line);
}
.map-panel .pb h3:first-child { margin-top: 0; }
.map-panel .pb p { max-width: 74ch; }

/* ---- the documentation viewer ---------------------------------------- */

.doc-layout {
	display: grid;
	grid-template-columns: 250px minmax(0, 1fr);
	gap: 2rem;
	align-items: start;
}
@media (max-width: 860px) {
	.doc-layout { grid-template-columns: 1fr; }
}
.doc-nav {
	position: sticky;
	top: calc(var(--head-h) + 18px);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--bg-panel);
	padding: .5rem;
	max-height: calc(100vh - var(--head-h) - 42px);
	overflow-y: auto;
}
@media (max-width: 860px) { .doc-nav { position: static; max-height: none; } }
.doc-nav ul { list-style: none; margin: 0; padding: 0; }
.doc-nav button {
	display: block;
	width: 100%;
	text-align: left;
	font: inherit;
	font-size: .94rem;
	background: none;
	border: 0;
	border-radius: 4px;
	padding: .5rem .7rem;
	color: var(--text-dim);
	cursor: pointer;
}
.doc-nav button:hover { background: var(--bg-raised); color: var(--text); }
.doc-nav button[aria-current="true"] {
	background: var(--bg-raised);
	color: var(--amber);
	box-shadow: inset 2px 0 0 var(--amber);
}
.doc-nav button small {
	display: block;
	font-size: .76rem;
	color: var(--text-faint);
	line-height: 1.35;
	margin-top: .12rem;
}
.doc-nav button[aria-current="true"] small { color: var(--text-dim); }

.doc-body { min-width: 0; }
.doc-meta {
	font-family: var(--mono);
	font-size: .8rem;
	color: var(--text-faint);
	border-bottom: 1px solid var(--line);
	padding-bottom: .8rem;
	margin-bottom: 1.6rem;
	display: flex;
	gap: .8rem;
	flex-wrap: wrap;
	align-items: center;
}

/* Rendered markdown. Kept to the same rhythm as the rest of the site so a
   document does not look like a different website. */
.prose { max-width: 74ch; }
.prose > h1:first-child { margin-top: 0; }
.prose h2 { padding-bottom: .4rem; border-bottom: 1px solid var(--line); }
.prose ul, .prose ol { padding-left: 1.4rem; margin: 0 0 1.1rem; }
.prose li { margin-bottom: .4rem; }
.prose li > ul, .prose li > ol { margin-top: .4rem; }
.prose table { min-width: 0; }
.prose .plain {
	white-space: pre-wrap;
	font-family: var(--mono);
	font-size: .9rem;
	line-height: 1.6;
	color: var(--text-dim);
}

/* ---- the changelog --------------------------------------------------- */

.release {
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--bg-panel);
	margin-bottom: .8rem;
	overflow: hidden;
}
.release > summary {
	list-style: none;
	cursor: pointer;
	padding: 1rem 1.3rem;
	display: flex;
	gap: 1rem;
	align-items: baseline;
	flex-wrap: wrap;
}
.release > summary::-webkit-details-marker { display: none; }
.release > summary:hover { background: var(--bg-raised); }
.release[open] > summary {
	border-bottom: 1px solid var(--line);
	background: var(--bg-inset);
}
.release .ver {
	font-family: var(--mono);
	font-weight: 650;
	font-size: 1.05rem;
	color: var(--amber);
	min-width: 4.2rem;
}
.release .vt { font-size: 1rem; color: var(--text); flex: 1 1 20ch; }
.release .vc {
	font-family: var(--mono);
	font-size: .76rem;
	color: var(--text-faint);
}
.release .rb { padding: 1.3rem 1.5rem 1.6rem; }
.release .rb > :last-child { margin-bottom: 0; }
.release.newest { border-color: var(--amber-dim); }

.timeline-key {
	display: flex;
	gap: 1.4rem;
	flex-wrap: wrap;
	font-family: var(--mono);
	font-size: .82rem;
	color: var(--text-faint);
	margin-bottom: 1.6rem;
}

/* ---- utility --------------------------------------------------------- */

.visually-hidden {
	position: absolute;
	width: 1px; height: 1px;
	margin: -1px; padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}
.dim { color: var(--text-dim); }
.faint { color: var(--text-faint); }
.mono { font-family: var(--mono); }
.nowrap { white-space: nowrap; }
.mt0 { margin-top: 0; }
.mb0 { margin-bottom: 0; }
.center { text-align: center; }

/* A quiet loading state. Text rather than a spinner, because a spinner says
   nothing to a screen reader and this page has readers who use one. */
.loading { color: var(--text-faint); font-family: var(--mono); font-size: .9rem; }

.two-col {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 1.4rem 2.4rem;
}

.hero {
	padding: 4rem 0 2.6rem;
	border-bottom: 1px solid var(--line);
	margin-bottom: 2.8rem;
	/* A very slight lift behind the top of the page, so the hero is a place
	   rather than the first paragraph of a long document. */
	background:
		radial-gradient(110ch 26rem at 12% -6rem, rgba(242, 167, 27, .07), transparent 70%),
		radial-gradient(90ch 22rem at 88% -4rem, rgba(87, 196, 221, .05), transparent 70%);
}
.hero h1 { max-width: 20ch; }
.hero .lede { font-size: 1.24rem; max-width: 64ch; margin-top: 1.2rem; }
.hero .version {
	font-family: var(--mono);
	font-size: .82rem;
	color: var(--text-faint);
	letter-spacing: .06em;
}

/* ---- the reference tables: weapons and vehicles ----------------------- */

/* A row of controls above a long table. Everything in it narrows the table
   below; nothing in it navigates. */
.controls {
	display: flex;
	gap: .5rem .9rem;
	flex-wrap: wrap;
	align-items: center;
	margin-bottom: 1.3rem;
	padding: .75rem .95rem;
	background: var(--bg-inset);
	border: 1px solid var(--line);
	border-radius: var(--radius);
}
.controls label {
	font-size: .82rem;
	color: var(--text-dim);
	display: flex;
	align-items: center;
	gap: .4rem;
}
.controls select, .controls input[type="search"] {
	font: inherit;
	font-size: .9rem;
	background: var(--bg-panel);
	color: var(--text);
	border: 1px solid var(--line-bright);
	border-radius: 5px;
	padding: .36rem .55rem;
}
.controls select:hover, .controls input[type="search"]:hover {
	border-color: var(--text-faint);
}
.controls input[type="search"] { min-width: 14rem; flex: 1 1 14rem; max-width: 24rem; }
.controls .count {
	margin-left: auto;
	font-family: var(--mono);
	font-size: .82rem;
	color: var(--text-faint);
}

/* The table itself. Sorting is on the header buttons, so the header is a row
   of real buttons rather than clickable cells. */
table.data { min-width: 600px; font-variant-numeric: tabular-nums; }
table.data th { padding: 0; }
table.data th button {
	display: flex;
	align-items: center;
	gap: .3rem;
	width: 100%;
	font: inherit;
	font-size: .8rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .07em;
	color: var(--text-dim);
	background: none;
	border: 0;
	padding: .58rem .8rem;
	cursor: pointer;
	text-align: left;
}
table.data th button:hover { color: var(--text); background: var(--bg-raised); }
table.data th[aria-sort] button { color: var(--amber); }
table.data th button .arrow { font-size: .7em; opacity: .8; }
table.data th.num button, table.data td.num { text-align: right; justify-content: flex-end; }
table.data td.num { white-space: nowrap; }
table.data tbody tr { cursor: pointer; }
table.data tbody tr[aria-selected="true"] td {
	background: var(--bg-raised);
	box-shadow: inset 3px 0 0 var(--amber);
}
table.data .nm { font-weight: 560; }
table.data .sub {
	display: block;
	font-size: .78rem;
	color: var(--text-faint);
}

/* ---- the two-pane reference layout ------------------------------------ */

/* WHAT WAS WRONG WITH IT BEFORE. The weapon table is eight columns wide and
   the detail panel opened underneath it, so picking a weapon pushed the table
   you were comparing against off the top of the screen -- and then picking the
   next one scrolled you back up to find it. Comparing two weapons meant
   scrolling between them.

   So on a wide screen the table keeps the left and the detail sits in a
   sticky rail on the right, where it stays put while you pick down the list.
   Below that width there is not room for both and it stacks, which is the old
   behaviour, and the old behaviour is fine when it is the only option.

   The rail is a grid column rather than a floating overlay on purpose: an
   overlay would cover the table, which is the one thing this layout exists to
   stop happening. */
.ref-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 1.6rem;
	align-items: start;
}
@media (min-width: 1080px) {
	.ref-layout { grid-template-columns: minmax(0, 1fr) var(--rail); }
	.ref-rail {
		position: sticky;
		top: calc(var(--head-h) + 18px);
		max-height: calc(100vh - var(--head-h) - 42px);
		overflow-y: auto;
		overscroll-behavior: contain;
	}
	.ref-layout .detail { margin-top: 0; }
	.ref-layout .table-scroll { margin-top: 0; }
}

/* What the rail says before anything has been picked. Without this the column
   is simply empty, which reads as something that failed to load rather than as
   something waiting for you. */
.rail-hint {
	border: 1px dashed var(--line-bright);
	border-radius: var(--radius);
	padding: 1.3rem 1.4rem;
	color: var(--text-faint);
	font-size: .94rem;
}
.rail-hint p { margin: 0; }
.rail-hint[hidden] { display: none; }
@media (max-width: 1079px) { .rail-hint { display: none; } }

/* The detail panel. Same idea as the map panel: it opens beside, or below, the
   thing you picked from, rather than on a page of its own. */
.detail {
	margin-top: 1.4rem;
	border: 1px solid var(--line-bright);
	border-top: 2px solid var(--amber);
	border-radius: var(--radius);
	background: var(--bg-panel);
	scroll-margin-top: calc(var(--head-h) + 1.4rem);
}
.detail[hidden] { display: none; }
.detail .dh {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: start;
	gap: .6rem 1rem;
	padding: 1.1rem 1.4rem;
	border-bottom: 1px solid var(--line);
	background: var(--bg-inset);
	border-radius: var(--radius) var(--radius) 0 0;
}
.detail .dh h2 { margin: 0; font-size: 1.4rem; }
.detail .dh .desig {
	margin: .2rem 0 0;
	font-family: var(--mono);
	font-size: .78rem;
	letter-spacing: .04em;
	color: var(--text-faint);
}
.detail .dh .desig:empty { display: none; }
.detail .dh .tags { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .5rem; }
.detail .dh .close { grid-column: 2; grid-row: 1; align-self: start; }
.detail .db { padding: 1.3rem 1.4rem 1.5rem; }
.ref-rail .detail .dh { padding: 1rem 1.2rem; }
.ref-rail .detail .db { padding: 1.2rem 1.2rem 1.4rem; }
.ref-rail .detail .dh h2 { font-size: 1.25rem; }
/* In a column this narrow the seat rows have to stack: role over label over
   gun. Side by side they wrapped mid-sentence and read as four fragments. */
.ref-rail .seats li { display: block; }
.ref-rail .seats .role { display: block; min-width: 0; margin-bottom: .1rem; }
.ref-rail .seats .gun { display: block; margin: .15rem 0; }
.detail .db > :last-child { margin-bottom: 0; }
.detail .note {
	color: var(--text-dim);
	max-width: 70ch;
	margin: 0 0 1.4rem;
}

/* The description: what the thing is, as opposed to what it does.

   IT COMES FIRST, above the figures, and it is set larger than they are. The
   numbers answer "which of these two should I carry"; the prose answers "what
   am I holding", and somebody who has just clicked a name they did not
   recognise is asking the second question. The first paragraph is the
   appearance, so it is the one lifted out. */
.lore {
	margin: 0 0 1.5rem;
	max-width: 66ch;
	border-left: 2px solid var(--amber-dim);
	padding-left: 1.1rem;
}
.lore p {
	margin: 0 0 .85rem;
	color: var(--text-dim);
	font-size: .97rem;
	line-height: 1.72;
}
.lore p:first-child {
	color: var(--text);
	font-size: 1.04rem;
}
.lore p:last-child { margin-bottom: 0; }

/* The same prose on a card rather than in a panel: the grenades and the armour
   abilities, which are few enough to show whole rather than to be clicked. */
.lore-cards {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	gap: 1.1rem;
	margin: 1.4rem 0;
}
.lore-card {
	background: var(--bg-panel);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: 1.2rem 1.35rem 1.3rem;
}
.lore-card h3 {
	margin: 0 0 .5rem;
	font-size: 1.06rem;
}
.lore-card .figures {
	display: flex;
	flex-wrap: wrap;
	gap: .35rem .5rem;
	margin: 0 0 .9rem;
}
.lore-card .lore {
	border-left: 0;
	padding-left: 0;
	margin-bottom: 0;
	max-width: none;
}
.lore-card .lore p { font-size: .93rem; }
.lore-card .lore p:first-child { font-size: .97rem; }

/* Groups of figures. One group per question somebody is asking. */
.groups {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 1.4rem 2rem;
}
.group h3 {
	margin: 0 0 .6rem;
	font-family: var(--mono);
	font-size: .74rem;
	letter-spacing: .13em;
	text-transform: uppercase;
	color: var(--amber);
	padding-bottom: .35rem;
	border-bottom: 1px solid var(--line);
}
.group dl { margin: 0; display: grid; grid-template-columns: 1fr auto; gap: .3rem .8rem; }
.group dt { color: var(--text-dim); font-size: .9rem; }
.group dd {
	margin: 0;
	font-family: var(--mono);
	font-size: .9rem;
	text-align: right;
	font-variant-numeric: tabular-nums;
}
.group dd.wide { text-align: left; grid-column: 1 / -1; color: var(--text-dim); font-family: var(--sans); }

/* The seats of a vehicle, which are the interesting part of one. */
.seats { list-style: none; margin: 1rem 0 0; padding: 0; }
.seats li {
	display: flex;
	gap: .7rem;
	align-items: baseline;
	flex-wrap: wrap;
	padding: .6rem 0;
	border-bottom: 1px solid var(--line);
}
.seats li:last-child { border-bottom: 0; }
.seats .role {
	font-family: var(--mono);
	font-size: .72rem;
	text-transform: uppercase;
	letter-spacing: .06em;
	color: var(--amber);
	min-width: 5.5rem;
}
.seats .gun { color: var(--text-dim); font-size: .9rem; }

/* ---- opened as a file rather than served ------------------------------ */

/* What somebody sees when they have double-clicked one of these pages in
   Explorer instead of going through the bridge.

   IT TAKES THE PAGE OVER RATHER THAN WARNING AT THE TOP OF IT. Every page on
   this site gets its content from /api/, and a file:// page cannot reach that:
   the maps, the documents, the changelog, the weapons and the vehicles would
   all sit at "Asking the server..." for ever, and every link in the header
   would point at a folder on the C: drive. A banner over a site where nothing
   works is a banner somebody scrolls past to find out that nothing works. */
.fileguard {
	max-width: 660px;
	margin: 3.5rem auto;
	padding: 0 1.4rem;
}
.fileguard h1 { font-size: 1.9rem; margin-bottom: 1rem; }
.fileguard .lede { font-size: 1.1rem; margin-bottom: 2rem; }
.fileguard ol { padding-left: 1.3rem; }
.fileguard li { margin-bottom: .8rem; }
.fileguard .where {
	font-family: var(--mono);
	font-size: .86rem;
	color: var(--text-faint);
	word-break: break-all;
	margin-top: 2.5rem;
	padding-top: 1.2rem;
	border-top: 1px solid var(--line);
}
.fileguard .big {
	display: inline-block;
	font-size: 1.05rem;
	padding: .8rem 1.5rem;
	margin: .4rem 0 1.4rem;
}

/* ---- the admin panel -------------------------------------------------- */

.signin {
	max-width: 380px;
	margin: 4rem auto;
	padding: 0 1.4rem;
}
.signin form { display: grid; gap: .9rem; }
.signin label { display: grid; gap: .3rem; font-size: .9rem; color: var(--text-dim); }
.signin input {
	font: inherit;
	background: var(--bg-inset);
	color: var(--text);
	border: 1px solid var(--line-bright);
	border-radius: 4px;
	padding: .55rem .7rem;
}

/* An action's answer, shown where the action was rather than in a corner. */
.said {
	margin: 1rem 0 0;
	padding: .8rem 1rem;
	border-radius: var(--radius);
	border: 1px solid var(--line-bright);
	border-left: 3px solid var(--line-bright);
	background: var(--bg-inset);
	font-size: .93rem;
	white-space: pre-wrap;
}
.said.good { border-left-color: var(--live); }
.said.bad { border-left-color: var(--dead); }
.said.busy { border-left-color: var(--amber); color: var(--text-dim); }
.said[hidden] { display: none; }

.who {
	display: flex;
	gap: .5rem;
	align-items: center;
	flex-wrap: wrap;
	padding: .7rem 0;
	border-bottom: 1px solid var(--line);
}
.who:last-child { border-bottom: 0; }
.who .nm { font-weight: 570; min-width: 9rem; }
.who .at { color: var(--text-dim); font-size: .9rem; flex: 1 1 14rem; }
.who .btns { display: flex; gap: .35rem; flex-wrap: wrap; }

textarea.editor {
	width: 100%;
	min-height: 22rem;
	font-family: var(--mono);
	font-size: .88rem;
	line-height: 1.55;
	background: var(--bg-inset);
	color: var(--text);
	border: 1px solid var(--line-bright);
	border-radius: var(--radius);
	padding: .9rem 1rem;
	resize: vertical;
}

pre.logview {
	max-height: 34rem;
	overflow: auto;
	font-size: .82rem;
	line-height: 1.5;
}

.danger {
	border-color: var(--dead);
	border-left: 3px solid var(--dead);
}
.btn.bad { border-color: var(--dead); color: var(--dead); }
.btn.bad:hover { background: rgba(240, 115, 107, .12); border-color: var(--dead); }

.rank-note {
	font-family: var(--mono);
	font-size: .78rem;
	color: var(--text-faint);
	margin-left: auto;
}


/* ---- names, records and the boards ------------------------------------

A name anywhere on this site is the control that opens that person's record.
It is a button and it looks like a link, which is the one case where those two
should be told apart by what they do rather than by how they look: it does not
navigate, it opens a panel over the page you are already reading, and losing
the page you were reading is the whole thing it exists to avoid.

It carries an underline rather than only a colour, because nothing on this site
is distinguished by colour alone. */
.namebtn {
	font: inherit;
	font-weight: 570;
	color: var(--cyan);
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}
.namebtn:hover { color: var(--text); }

/* The record itself. A real <dialog>, so Escape, the focus trap and the inert
background behind it are the browser's job rather than ours. */
.profile-dialog {
	width: min(720px, calc(100vw - 2.4rem));
	max-height: min(80vh, 900px);
	padding: 0;
	border: 1px solid var(--line-bright);
	border-radius: var(--radius);
	background: var(--bg-raised);
	color: var(--text);
	overflow: auto;
}
.profile-dialog::backdrop { background: rgba(4, 6, 8, .72); }
.profile-dialog .phead {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding: 1rem 1.3rem;
	border-bottom: 1px solid var(--line);
	background: var(--bg-panel);
	position: sticky;
	top: 0;
}
.profile-dialog .phead h2 { margin: 0; font-size: 1.35rem; }
.profile-dialog .phead .close { margin-left: auto; flex: none; }
.profile-dialog .pbody { padding: 1.3rem; }
.profile-dialog .pbody > :first-child { margin-top: 0; }
.profile-dialog .pbody > :last-child { margin-bottom: 0; }
.profile-dialog .stats { margin: 1rem 0 1.4rem; }
.profile-dialog h3 { margin: 1.5rem 0 .6rem; font-size: 1.05rem; }

/* Which board is being looked at. A row of toggles rather than a select,
because there are nine of them, they each carry a count, and the count is worth
seeing before you choose rather than after. */
.boardpick {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
	margin: 1.4rem 0;
}
.boardbtn {
	font: inherit;
	font-size: .92rem;
	display: inline-flex;
	align-items: baseline;
	gap: .5rem;
	padding: .45rem .9rem;
	border: 1px solid var(--line-bright);
	border-radius: var(--radius);
	background: var(--bg-panel);
	color: var(--text-dim);
	cursor: pointer;
}
.boardbtn:hover { border-color: var(--amber-dim); color: var(--text); }
.boardbtn .n {
	font-family: var(--mono);
	font-size: .78rem;
	color: var(--text-faint);
}
.boardbtn[aria-pressed="true"] {
	border-color: var(--amber);
	color: var(--text);
	background: var(--bg-inset);
}
.boardbtn[aria-pressed="true"] .n { color: var(--amber); }
