MediaWiki:Common.css

Current answers. Practical procedures. Reliable reference.
Revision as of 16:41, 7 August 2026 by Sythan (talk | contribs) (Fix TOC 'Contents' text still showing: core .toc h2 font-size:100% tied specificity with .toctitle h2, needed #toc id to win)
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* ==========================================================================
   EDFM site-wide styling -- "Elite Dangerous technical field manual" theme.
   Original CSS written for this project -- no code or assets copied from
   runescape.wiki, Elite Dangerous, or any other site/game, and no Frontier
   logo/branding/proprietary fonts/copied HUD elements. Restrained visual
   influence only: dark industrial surfaces, subtle angular geometry,
   orange/cyan accents used sparingly, information hierarchy first. This is
   a reference site, not a HUD -- no glow, no neon, no glassmorphism, no
   constant animation.

   SKIN NOTE: the site uses Vector "legacy" (2011), not Vector 2022 -- see
   the "Why Vector legacy" note in docs/content-style-guide.md (Vector 2022
   hard-restricts its pinned sidebar to logged-in users; legacy has no such
   restriction). Several rules below exist specifically to beat core Vector
   legacy/mediawiki.skinning selectors that are *more specific* than a naive
   override would be (documented inline at each occurrence) -- this isn't
   guesswork, each one was found by reading the actual core .less source and
   confirmed with a real rendered screenshot, not just computed-style checks
   (:visited colours in particular are invisible to getComputedStyle by
   design -- see the tab-bar note below).

   File organised to mirror the 2026-08-07 redesign brief's own section
   numbers, so both stay easy to cross-reference.
   ========================================================================== */

/* ==========================================================================
   1. DESIGN TOKENS
   ========================================================================== */
:root {
	/* Surfaces -- darkest to lightest */
	--edfm-bg-deep: #090d0f;
	--edfm-bg-page: #0d1215;
	--edfm-surface-1: #12181c;
	--edfm-surface-2: #171f24;
	--edfm-surface-3: #1c252b;

	/* Borders */
	--edfm-border: #273239;
	--edfm-border-soft: rgba( 255, 255, 255, 0.07 );

	/* Text */
	--edfm-text: #e7eaec;
	--edfm-text-muted: #8e9aa1;
	--edfm-text-dim: #68757c;

	/* Accents -- orange is reserved for navigation/selection/emphasis/
	   section numbering; cyan/blue are for links, verification info, and
	   secondary interface elements. See "Links" and "Colour system" in
	   docs/content-style-guide.md for the reasoning. */
	--edfm-orange: #ff8a00;
	--edfm-orange-bright: #ffa21a;
	--edfm-cyan: #42c7d9;
	--edfm-blue: #4f9fe8;

	/* Derived link colours (not part of the operator's token list verbatim,
	   but named separately so link handling reads as its own concern) */
	--edfm-link: var( --edfm-blue );
	--edfm-link-visited: #3f7bb3;
	--edfm-link-hover: #8cc4f7;
	--edfm-link-external: var( --edfm-cyan );
	--edfm-link-external-visited: #2f8f9c;
	--edfm-link-external-hover: #7fe0ec;
	--edfm-link-new: #e07a7a;

	/* Status semantics (article metadata module) -- text label always
	   present too, never colour-only. */
	--edfm-status-positive: var( --edfm-cyan );
	--edfm-status-attention: var( --edfm-orange );
	--edfm-status-neutral: var( --edfm-text-dim );

	/* Typography */
	--edfm-mono: 'JetBrains Mono', 'Fira Code', Consolas, 'SF Mono', Menlo, 'Courier New', monospace;
	--edfm-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

	/* Legacy aliases: earlier revisions of this stylesheet used these names
	   directly and some inline template output/older docs may still refer
	   to them; keep pointing at the current tokens rather than duplicate
	   values that could drift out of sync. */
	--edfm-orange-hover: var( --edfm-orange-bright );
	--edfm-orange-active: var( --edfm-orange-bright );
	--color-progressive: var( --edfm-orange );
	--color-progressive--hover: var( --edfm-orange-bright );
	--color-progressive--active: var( --edfm-orange-bright );
	--color-progressive--focus: var( --edfm-orange );
	--background-color-progressive: var( --edfm-orange );
	--background-color-progressive--hover: var( --edfm-orange-bright );
	--background-color-progressive--active: var( --edfm-orange-bright );
	--border-color-progressive: var( --edfm-orange );
	--border-color-progressive--hover: var( --edfm-orange-bright );
	--border-color-progressive--active: var( --edfm-orange-bright );

	/* Shared geometry: a small clipped corner reads as "technical panel"
	   without a giant border-radius anywhere on the site. */
	--edfm-corner: 10px;
	--edfm-content-max: 1200px;
}

/* ==========================================================================
   2. BASE / RESET-ADJACENT
   ========================================================================== */
html, body {
	background-color: var( --edfm-bg-page );
	color: var( --edfm-text );
}
body.mediawiki {
	color: var( --edfm-text );
	font-family: var( --edfm-sans );
}
/* Very faint (~2.5%) technical grid across the page background. Only
   visible where an opaque panel (sidebar, article surface, tables) isn't
   already covering it -- the header strip, the sidebar, and the margin
   outside the width-capped article column on wide screens. Not an image
   asset; pure CSS gradients. */
body {
	background-image:
		linear-gradient( rgba( 255, 255, 255, 0.025 ) 1px, transparent 1px ),
		linear-gradient( 90deg, rgba( 255, 255, 255, 0.025 ) 1px, transparent 1px );
	background-size: 48px 48px;
}
@media ( prefers-reduced-motion: reduce ) {
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
}
/* Focus visibility: the pre-redesign stylesheet had no explicit focus
   styling at all (relying entirely on browser defaults, which vary and can
   be hard to see against a dark theme). Applies to every interactive
   element, not just links. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var( --edfm-cyan );
	outline-offset: 2px;
}

/* ==========================================================================
   3. TYPOGRAPHY
   ========================================================================== */
h1, h2, h3, h4, h5, h6 {
	color: var( --edfm-text );
	border-color: var( --edfm-border );
}
/* !important justified here: MediaWiki core's mediawiki.skinning module
   sets heading colour with equal-specificity plain-tag selectors and kept
   winning in testing despite this stylesheet loading later -- rather than
   keep chasing exact cascade/bundling order, force it. This is a
   correctness/contrast fix, not decoration. */
.mw-body h1, .mw-body h2, .mw-body h3, .mw-body h4, .mw-body h5, .mw-body h6,
.mw-heading1, .mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6,
h1, h2, h3, h4, h5, h6 {
	color: var( --edfm-text ) !important;
	border-color: var( --edfm-border ) !important;
	font-family: var( --edfm-mono );
	letter-spacing: 0.01em;
	line-height: 1.3;
}
#firstHeading {
	color: var( --edfm-text ) !important;
	font-family: var( --edfm-mono );
	font-size: 1.9em;
}
/* Restrained "instrument label" bracket treatment on major section
   headings (h2): a plain "// " prefix via ::before (no image, no glow, no
   animation) plus a short orange accent segment layered over the
   otherwise-dim divider line core already draws under h2. If a heading
   opts into explicit numbering via {{Section number}} (see
   .edfm-section-number below), the automatic "// " is suppressed so the
   two treatments don't double up. */
.mw-body h2 {
	position: relative;
	padding-bottom: 0.3em;
	margin-top: 1.6em;
}
.mw-body h2::before {
	content: '// ';
	color: var( --edfm-orange );
	font-weight: 400;
}
.mw-body h2:has( .edfm-section-number )::before {
	content: none;
}
.mw-body h2::after {
	content: '';
	position: absolute;
	left: 0;
	bottom: -1px;
	width: 3em;
	max-width: 100%;
	height: 2px;
	background: var( --edfm-orange );
}
.edfm-section-number {
	color: var( --edfm-orange );
	font-weight: 700;
}
.edfm-section-sep {
	color: var( --edfm-orange );
	margin-right: 0.15em;
}
h3, h4 {
	color: var( --edfm-text );
}
h3::before {
	content: '/ ';
	color: var( --edfm-text-dim );
	font-weight: 400;
}

/* Body text: readable sans-serif, deliberately NOT monospace -- long-form
   reading in monospace hurts readability, which stays a hard requirement
   even with a more technical visual language elsewhere. */
.mw-body p,
.mw-body li,
.mw-body dd {
	line-height: 1.65;
}
.mw-body p {
	margin: 0 0 1em 0;
	max-width: 74em; /* comfortable measure even inside the wider content column */
}
.mw-body ul,
.mw-body ol {
	line-height: 1.65;
	margin-bottom: 1em;
}
.mw-body h2 + p,
.mw-body h3 + p {
	margin-top: 0.6em;
}
hr {
	background-color: var( --edfm-border );
	border-color: var( --edfm-border );
}

/* ==========================================================================
   8. LINKS
   ========================================================================== */
a { color: var( --edfm-link ); transition: color 0.1s ease; }
a:visited { color: var( --edfm-link-visited ); }
a:hover { color: var( --edfm-link-hover ); }
a.new, .new a { color: var( --edfm-link-new ); }
a.external { color: var( --edfm-link-external ); }
/* Core MediaWiki ships `.mw-parser-output a.external`/`a.extiw` (and their
   :visited/:hover states) at higher specificity (two classes + a tag) than
   a plain `a.external` rule (one class + a tag), so the line above never
   actually wins for real article links on its own -- the same underlying
   "core selector outranks a naive theme override" gotcha as the tab
   :visited fix further down. Matching the same selector shape here (this
   stylesheet loads after core skin styles) is what actually applies our
   colour to external links in article content. */
.mw-parser-output a.external,
.mw-parser-output a.extiw {
	color: var( --edfm-link-external );
}
.mw-parser-output a.external:visited,
.mw-parser-output a.extiw:visited {
	color: var( --edfm-link-external-visited );
}
.mw-parser-output a.external:hover,
.mw-parser-output a.extiw:hover {
	color: var( --edfm-link-external-hover );
}
.mw-footer a {
	color: var( --edfm-link );
}
.mw-footer a:hover {
	color: var( --edfm-link-hover );
}

/* ==========================================================================
   1 + 4. GLOBAL LAYOUT / ARTICLE HEADER
   ========================================================================== */
/* Vector legacy's core layout (skins.vector.styles.legacy/layouts/screen.less)
   gives `.mw-body` (#content) a left margin to clear the fixed-width
   sidebar and otherwise lets it run edge-to-edge to the browser's right
   side -- there is no max-width at all, which is why content stretched
   excessively on large displays. Capping width here only affects the
   article/footer column; the full-width header/tab bar above it is left
   alone deliberately (its own float/absolute-position math is exactly what
   an earlier round of this project had to carefully debug to get the
   persistent sidebar working at all -- touching it again for a purely
   cosmetic width cap isn't worth the regression risk). A full-bleed
   toolbar above a capped content column is also just a normal, accepted
   pattern on technical documentation sites. */
.mw-body,
#mw-data-after-content,
.mw-footer {
	max-width: var( --edfm-content-max );
	box-sizing: border-box;
}
/* Tables, code blocks, and preformatted content are still allowed to be
   wider than a comfortable reading measure (technical data often needs
   it) -- they scroll horizontally inside the capped column instead of
   being force-shrunk or breaking the layout. Ordinary images/galleries
   already respect the column via max-width:100% below. */
.mw-body table,
.mw-body pre,
.mw-body .mw-code {
	max-width: 100%;
	overflow-x: auto;
}
.mw-body table.wikitable,
.mw-body table.mw-datatable {
	display: block;
	overflow-x: auto;
}
.mw-body table.wikitable tbody,
.mw-body table.mw-datatable tbody {
	display: table;
	width: 100%;
}
.mw-body img {
	max-width: 100%;
	height: auto;
}

/* Eyebrow / deck (see Template:Article header). The eyebrow line is
   authored as ordinary wikitext and, purely as a placement detail, a small
   script (MediaWiki:Common.js) moves it directly above #firstHeading on
   page load -- see the comment there for why that needs JS rather than
   CSS/a template (the title is rendered by the skin before the article
   body in the DOM, so nothing living inside the article body can appear
   earlier than it without either moving it in the DOM or abandoning the
   real semantic H1, and the brief is explicit the H1 must stay the real
   H1). If JS is unavailable the eyebrow still renders, just directly under
   the title instead of above it -- nothing breaks, it's a placement
   nicety, not functionality. */
.edfm-eyebrow {
	margin: 0 0 0.3em 0;
	font-family: var( --edfm-mono );
	font-size: 0.75em;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var( --edfm-text-dim );
}
.edfm-eyebrow .edfm-orange-mark {
	color: var( --edfm-orange );
}
.edfm-deck {
	color: var( --edfm-text-muted );
	font-size: 1.05em;
	max-width: 60em;
	margin: 0.3em 0 1.2em 0;
}

/* ==========================================================================
   1. SIDEBAR
   ========================================================================== */
#mw-panel {
	background-color: var( --edfm-bg-deep );
}
#mw-panel .portal .body,
#mw-panel .portal ul {
	border-color: var( --edfm-border-soft );
}
#mw-panel .portal a {
	color: var( --edfm-text-muted );
	display: block;
	padding: 0.15em 0.4em;
	margin: 0 -0.4em;
	border-left: 2px solid transparent;
	border-radius: 0;
}
#mw-panel .portal a:hover {
	color: var( --edfm-cyan );
	background: var( --edfm-surface-1 );
}
/* "You are here" -- MediaWiki's sidebar has no built-in current-page
   indication; MediaWiki:Common.js adds the .edfm-nav-current class to the
   matching list item by comparing hrefs to the current URL. Orange is
   reserved for exactly this kind of "important navigation / selected
   state" per the colour system, which is why the rest of the sidebar is
   deliberately muted rather than orange throughout (an all-orange sidebar
   would both fight this indicator and read as visually dominant, which the
   brief specifically calls out to avoid). */
.edfm-nav-current > a {
	color: var( --edfm-orange ) !important;
	font-weight: 700;
	border-left-color: var( --edfm-orange );
	background: var( --edfm-surface-1 );
}
.vector-menu-heading {
	color: var( --edfm-text-dim );
	font-weight: 700;
	font-family: var( --edfm-mono );
	letter-spacing: 0.08em;
	text-transform: uppercase;
	font-size: 0.75em;
	border-left: 2px solid var( --edfm-orange );
	padding-left: 0.5em;
	margin-left: -0.5em;
}

/* ==========================================================================
   4/9. HEADER / MASTHEAD / MEDIAWIKI TABS
   ========================================================================== */
#mw-page-base {
	background-color: var( --edfm-bg-deep );
	background-image: none;
}
#mw-head-base {
	background-color: var( --edfm-bg-deep );
}
#p-personal,
.vector-header-container {
	border-bottom: 2px solid var( --edfm-orange );
}
#mw-head-base {
	border-bottom: 2px solid var( --edfm-orange );
}
/* Personal tools (login/logout) -- a real action, kept orange-adjacent but
   quiet until interacted with, matching "utility control" treatment. */
#p-personal a {
	color: var( --edfm-text-muted );
	font-family: var( --edfm-mono );
}
#p-personal a:hover {
	color: var( --edfm-orange );
}
/* Namespace tabs (Main Page / Discussion, left) and view tabs
   (Read / Edit / View history, right) both use Vector legacy's
   .vector-menu-tabs-legacy markup. Core skin CSS paints every tab `li`
   with a gradient fading to white and forces the selected tab to pure
   white -- neither is touched by recolouring the link text alone, which is
   why these stayed light before this stylesheet covered the `li`
   background too. Core also has an `a:visited` rule (higher specificity
   than a plain `a` rule, since a pseudo-class counts the same as a class)
   that reasserts a near-black "visited" colour meant for a white
   background; since these tabs point at pages you've almost always
   already visited, without an explicit `:visited` override here the text
   goes dark-on-dark. This can't be caught by reading getComputedStyle() in
   an automated check -- browsers deliberately report the *unvisited*
   colour to JS for privacy reasons, so it only shows up on an actual
   screen; verified with real rendered screenshots, including after
   genuinely visiting the linked pages first.

   Per the redesign brief, tabs are "important navigation" (namespace
   identity) rather than "utility controls" (the view/actions tabs, see
   below) -- selected state stays orange; unselected rests at a slightly
   dimmer neutral than article body text so the *selected* tab still reads
   as the clear focal point. */
.vector-menu-tabs-legacy li {
	background-image: none;
	background-color: var( --edfm-surface-2 );
}
.vector-menu-tabs-legacy li.selected {
	background-image: none;
	background-color: var( --edfm-surface-1 );
}
.vector-menu-tabs-legacy li a,
.vector-menu-tabs-legacy li a:visited {
	background-color: transparent;
	color: var( --edfm-text-dim );
	font-family: var( --edfm-mono );
	letter-spacing: 0.01em;
}
.vector-menu-tabs-legacy li a:hover,
.vector-menu-tabs-legacy li a:visited:hover {
	color: var( --edfm-text );
}
.vector-menu-tabs-legacy li.selected a,
.vector-menu-tabs-legacy li.selected a:visited {
	color: var( --edfm-orange );
}
.vector-menu-tabs-legacy li.new a,
.vector-menu-tabs-legacy li.new a:visited {
	color: var( --edfm-link-new );
}
/* "More" actions dropdown (#p-cactions) sits in the same tab row; same
   :visited gotcha applies to its menu items. Kept deliberately quiet --
   this is the clearest case of "utility control, not primary nav". */
.vector-menu-dropdown .vector-menu-heading {
	color: var( --edfm-text-dim );
	font-family: var( --edfm-mono );
	border-left: none;
	padding-left: 8px;
	margin-left: 0;
	text-transform: none;
	letter-spacing: normal;
	font-size: 1em;
	font-weight: normal;
}
.vector-menu-dropdown .vector-menu-heading:hover,
.vector-menu-dropdown .vector-menu-heading:focus {
	color: var( --edfm-orange );
}
.vector-menu-dropdown .vector-menu-content {
	background-color: var( --edfm-surface-2 );
	border-color: var( --edfm-border );
}
.vector-menu-dropdown .vector-menu-content a,
.vector-menu-dropdown .vector-menu-content a:visited {
	color: var( --edfm-text-muted );
}
.vector-menu-dropdown .vector-menu-content li.selected a,
.vector-menu-dropdown .vector-menu-content li.selected a:visited {
	color: var( --edfm-orange );
}
.vector-menu-dropdown .vector-menu-content li:hover {
	background-color: var( --edfm-surface-3 );
}
.vector-search-box-inner input,
#searchInput {
	background-color: var( --edfm-surface-2 );
	color: var( --edfm-text );
	border: 1px solid var( --edfm-border );
	font-family: var( --edfm-mono );
}
#searchInput::placeholder {
	color: var( --edfm-text-dim );
}

/* ==========================================================================
   CONTENT / ARTICLE SURFACE
   ========================================================================== */
.mw-body,
.parsoid-body {
	background-color: var( --edfm-surface-1 );
	color: var( --edfm-text );
	border-color: var( --edfm-border );
	font-family: var( --edfm-sans );
}
#content {
	background-color: var( --edfm-surface-1 );
}

/* ==========================================================================
   10. TABLE OF CONTENTS
   ========================================================================== */
/* Restyled as an "EDFM navigation module" rather than a default wiki TOC,
   while leaving MediaWiki's actual TOC markup/anchors completely alone --
   this is presentation only. "Contents" is kept in the DOM for screen
   readers/no-JS/no-CSS fallback (more standard wording there anyway) and
   visually replaced with "Jump to" via ::before on the wrapper, with the
   real heading text hidden via font-size rather than display:none so it
   remains in the accessibility tree. */
#toc, .toc {
	background-color: var( --edfm-surface-2 ) !important;
	border: 1px solid var( --edfm-border ) !important;
	color: var( --edfm-text );
	padding: 0.8em 1em;
	clip-path: polygon( 0 0, calc( 100% - var( --edfm-corner ) ) 0, 100% var( --edfm-corner ), 100% 100%, 0 100% );
}
.toctitle {
	position: relative;
	margin-bottom: 0.4em;
}
.toctitle::before {
	content: 'Jump to';
	font-family: var( --edfm-mono );
	font-size: 0.75em;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var( --edfm-orange );
}
/* Core ships `.toc h2 { font-size: 100%; ... }` (mediawiki.skinning/toc/
   screen.less) at the exact same specificity (one class + one tag) as a
   plain `.toctitle h2` rule -- same "tie that doesn't resolve the way
   naive source order would suggest" gotcha documented elsewhere in this
   file. #toc's own ID makes this one unambiguous instead of relying on
   cascade order. */
#toc .toctitle h2,
.toc .toctitle h2 {
	font-size: 0 !important;
	line-height: 0;
	margin: 0;
	border: none;
	padding: 0;
	display: inline;
}
.toctitle h2::before,
.toctitle h2::after {
	content: none;
}
.toctogglelabel::before {
	color: var( --edfm-text-dim );
}
/* Top-level entries as wrapped horizontal "chips" -- reads well for the
   short/medium pages this site mostly has, and simply wraps onto more
   rows for longer ones rather than needing a separate vertical mode. */
.toc > ul {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4em 1.2em;
	list-style: none;
	margin: 0;
	padding: 0;
}
.toc ul ul {
	flex-basis: 100%;
	width: 100%;
	list-style: none;
	margin: 0.2em 0 0.2em 1.4em;
	padding: 0;
	display: block;
}
.toc li {
	margin: 0;
}
.toc a {
	display: inline-flex;
	align-items: baseline;
	gap: 0.35em;
	color: var( --edfm-text-muted );
	text-decoration: none;
	font-size: 0.92em;
}
.toc a:hover {
	color: var( --edfm-cyan );
}
.tocnumber {
	color: var( --edfm-orange );
	font-family: var( --edfm-mono );
	font-weight: 700;
	min-width: 1.2em;
}
.toctext {
	color: inherit;
}

/* ==========================================================================
   6. PANELS / CALLOUTS, and 11. ARTICLE METADATA / STATUS MODULE
   ========================================================================== */
/* Deliberately NOT defined here. .edfm-box / .edfm-panel* / .edfm-status* /
   .edfm-inline-flag are used exclusively by the editorial templates (see
   Template:Article status, Template:Draft warning, etc.), which already
   load Template:EDFM style/styles.css themselves via <templatestyles>.
   Defining the same class names in both this file and that one would
   leave their relative precedence dependent on unclear/unstable ordering
   between a ResourceLoader "site" stylesheet and a TemplateStyles-injected
   <style> tag -- rather than rely on that, there is exactly one definition
   of each, living in Template:EDFM style/styles.css. That file freely uses
   the --edfm-* custom properties defined above; custom properties resolve
   through the DOM regardless of which stylesheet declared vs references
   them, so this split costs nothing. */

/* ==========================================================================
   7. TABLES (wikitables, and Special: pages' tables)
   ========================================================================== */
table.wikitable,
table.mw-datatable {
	background-color: var( --edfm-surface-2 );
	color: var( --edfm-text );
	border-color: var( --edfm-border );
}
table.wikitable > tr > th,
table.wikitable > * > tr > th {
	background-color: var( --edfm-surface-3 );
	color: var( --edfm-text );
	border-color: var( --edfm-border );
	font-family: var( --edfm-mono );
	letter-spacing: 0.03em;
	text-transform: uppercase;
	font-size: 0.85em;
	text-align: left;
}
table.wikitable > tr > td,
table.wikitable > * > tr > td {
	border-color: var( --edfm-border-soft );
	padding: 0.5em 0.7em;
}
/* Subtle alternating row treatment -- helps scanning wide/dense reference
   tables without turning them into cards. */
table.wikitable > tbody > tr:nth-child( even ),
table.wikitable > * > tr:nth-child( even ) {
	background-color: var( --edfm-surface-1 );
}

/* ==========================================================================
   13. FOOTER
   ========================================================================== */
.mw-footer {
	margin-left: auto;
	margin-right: auto;
	border-top: 1px solid var( --edfm-border );
	display: grid;
	grid-template-columns: 1fr auto;
	grid-template-areas: "info icons" "places icons";
	align-items: center;
	column-gap: 2em;
	row-gap: 0.3em;
}
.mw-footer,
.mw-footer li,
#footer-info,
#footer-info li {
	color: var( --edfm-text-dim );
	border-color: var( --edfm-border-soft );
}
#footer-info {
	grid-area: info;
	margin: 0;
}
#footer-places {
	grid-area: places;
	margin: 0;
}
#footer-icons {
	grid-area: icons;
	align-self: center;
	display: flex;
	gap: 0.75em;
	margin: 0;
}
#footer-icons img {
	background: var( --edfm-text );
	border-radius: 2px;
}
@media ( max-width: 640px ) {
	.mw-footer {
		grid-template-columns: 1fr;
		grid-template-areas: "info" "places" "icons";
	}
	#footer-icons {
		margin-top: 0.5em;
	}
}

/* ==========================================================================
   MISC MediaWiki UI chrome that ships with light backgrounds by default
   ========================================================================== */
.catlinks {
	background-color: var( --edfm-surface-2 ) !important;
	border-color: var( --edfm-border ) !important;
	color: var( --edfm-text-muted );
}
div.thumbinner {
	background-color: var( --edfm-surface-2 );
	border-color: var( --edfm-border );
}
.thumbimage {
	background-color: var( --edfm-surface-1 );
	border-color: var( --edfm-border );
}

/* Code / preformatted text (syntaxhighlight uses its own Pygments theme,
   set via $wgPygmentsStyle in LocalSettings.php; this covers plain
   <pre>/<code> that isn't Pygments-highlighted). */
pre, code, .mw-code {
	background-color: var( --edfm-surface-2 );
	color: var( --edfm-text );
	border-color: var( --edfm-border );
	font-family: var( --edfm-mono );
}

/* ==========================================================================
   GENERIC INFOBOX -- see Template:Infobox
   ========================================================================== */
.edfm-infobox {
	float: right;
	clear: right;
	width: 300px;
	margin: 0 0 1.2em 1.2em;
	border: 1px solid var( --edfm-orange );
	background: var( --edfm-surface-2 );
	color: var( --edfm-text );
	font-size: 0.9em;
}
.edfm-infobox-title {
	background: var( --edfm-orange );
	color: var( --edfm-bg-deep );
	font-weight: 700;
	font-family: var( --edfm-mono );
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-align: center;
	padding: 0.4em 0.6em;
	clip-path: polygon( 0 0, calc( 100% - 14px ) 0, 100% 14px, 100% 100%, 0 100% );
}
.edfm-infobox-image {
	text-align: center;
	padding: 0.6em;
	border-bottom: 1px solid var( --edfm-border );
}
.edfm-infobox-row {
	display: flex;
	border-bottom: 1px solid var( --edfm-border-soft );
	padding: 0.35em 0.6em;
}
.edfm-infobox-row:last-child {
	border-bottom: none;
}
.edfm-infobox-label {
	font-weight: 700;
	font-family: var( --edfm-mono );
	font-size: 0.85em;
	width: 40%;
	flex-shrink: 0;
	color: var( --edfm-cyan );
}
.edfm-infobox-value {
	width: 60%;
}
@media ( max-width: 640px ) {
	.edfm-infobox {
		float: none;
		width: auto;
		margin: 1em 0;
	}
}

/* ==========================================================================
   14. MOBILE
   ========================================================================== */
/* Vector legacy has NO built-in responsive breakpoint at all (unlike
   Vector 2022) -- its entire header region (#mw-head, tabs, search,
   personal tools/login) is built with absolute positioning and floats
   that all assume a fixed-width sidebar reserving 10-11em on the left,
   AND the page's actual DOM order is content-then-navigation-then-footer
   (the absolute positioning was doing double duty: both moving the header
   visually to the top AND compensating for that DOM order). Simply
   removing the positioning stacks things in DOM order, which reads oddly
   on a phone (article text, then the nav/sidebar, then the footer).
   Confirmed the actual DOM structure directly (not guessed): <body>'s
   real children are #mw-page-base, #mw-head-base, #content,
   #mw-navigation (which itself contains #mw-head then #mw-panel, already
   in the right relative order), #footer. Since all four major regions are
   direct children of <body>, flexbox `order` on <body> can reorder them
   properly without needing to touch the DOM itself.
   Result: header/search/tabs, then sidebar nav, then content, then
   footer -- a plain stacked mobile layout, not a collapsible hamburger
   menu, but a correct and readable order. */
@media ( max-width: 800px ) {
	body {
		display: flex;
		flex-direction: column;
	}
	/* #mw-head-base ships with `margin-top: -5em` in Vector legacy's own
	   CSS -- a trick to sit it behind the absolutely-positioned header.
	   Now that the header is a normal flex sibling, that negative margin
	   drags everything after it upward. Neutralize both decorative
	   strips. */
	#mw-page-base,
	#mw-head-base {
		order: 0;
		height: 0;
		margin: 0;
		min-height: 0;
	}
	#mw-navigation {
		order: 1;
	}
	#content {
		order: 2;
	}
	.mw-footer {
		order: 3;
	}

	#mw-head {
		position: static;
		width: auto;
	}
	#left-navigation,
	#right-navigation {
		float: none;
		margin: 0;
		width: auto;
		clear: both;
	}
	#left-navigation {
		margin-top: 0;
	}
	/* Core Vector legacy floats each tab/dropdown portlet
	   (.vector-menu-tabs-legacy for Page/Discussion and Read/View
	   source/View history, .vector-menu-dropdown for the More menu) AND
	   floats every <li> inside their <ul>, with no wrapping at all -- at
	   narrow widths the labels just overflow and overlap each other
	   (confirmed with a real screenshot: "View source" and "More"
	   overlapped instead of wrapping to a new line). Switching the
	   portlets to inline-block and their tab lists to flex-wrap lets them
	   reflow onto as many rows as needed instead. */
	#left-navigation .vector-menu-tabs-legacy,
	#right-navigation .vector-menu-tabs-legacy,
	#right-navigation .vector-menu-dropdown {
		float: none;
		display: inline-block;
		vertical-align: top;
	}
	.vector-menu-tabs-legacy ul {
		float: none;
		display: flex;
		flex-wrap: wrap;
	}
	.vector-menu-tabs-legacy li {
		float: none;
	}
	#p-personal {
		position: static;
		text-align: right;
		padding: 0.5em 1em;
		margin: 0;
		right: auto;
		top: auto;
	}
	#p-personal ul {
		padding-left: 0;
	}
	.vector-search-box {
		float: none;
		margin: 0.5em 1em;
		display: block;
	}
	.vector-search-box-inner {
		width: auto;
		max-width: none;
	}
	#mw-panel {
		position: static;
		width: auto;
		padding: 0.5em 1em;
		float: none;
		border-top: 1px solid var( --edfm-border );
		border-bottom: 1px solid var( --edfm-border );
	}
	.mw-body,
	#mw-data-after-content,
	.mw-footer {
		margin-left: 0;
		max-width: none;
	}
	.mw-body {
		margin-top: 0;
		border-width: 0;
		padding: 1em;
	}
	.edfm-status-details {
		grid-template-columns: 1fr;
	}
	.toc > ul {
		gap: 0.3em 0.9em;
	}
	#firstHeading {
		font-size: 1.5em;
	}
}