MediaWiki:Common.css: Difference between revisions

Current answers. Practical procedures. Reliable reference.
Jump to navigation Jump to search
Fix TOC 'Contents' text still showing: core .toc h2 font-size:100% tied specificity with .toctitle h2, needed #toc id to win
Redesign pass 2: centred workspace layout, two-tier header, real masthead, tile-grid TOC, larger deliberate type scale, depth via surface elevation instead of borders
Line 20: Line 20:
   design -- see the tab-bar note below).
   design -- see the tab-bar note below).


   File organised to mirror the 2026-08-07 redesign brief's own section
   2026-08-07 SECOND PASS: the first redesign pass was judged too close to
   numbers, so both stay easy to cross-reference.
  stock MediaWiki with a colour change -- this pass changes the actual
   visual composition (centred workspace instead of a huge dead gutter,
  a two-tier header, a real masthead, a tile-grid TOC, a restructured
  status module, larger deliberate type scale, depth via surface
  elevation instead of borders-around-everything) while reusing every
  working mechanism from the first pass rather than throwing it away --
  the tab/:visited fix, the external-link specificity fix, the mobile
  reorder fix, and focus-visible/reduced-motion are all still here,
  unchanged in mechanism.
   ========================================================================== */
   ========================================================================== */


Line 28: Line 36:
   ========================================================================== */
   ========================================================================== */
:root {
:root {
/* Surfaces -- darkest to lightest */
/* Depth system: site (outermost, visible in the sidebar/header/gutters)
--edfm-bg-deep: #090d0f;
  -> article surface -> component surfaces, each a deliberate step
--edfm-bg-page: #0d1215;
  brighter so the page reads as having actual depth rather than "one
--edfm-surface-1: #12181c;
  background colour with slightly lighter boxes everywhere". */
--edfm-surface-2: #171f24;
--edfm-bg-deep: #07090b;
--edfm-surface-3: #1c252b;
--edfm-bg-page: #0a0e11;
--edfm-surface-1: #10171b;
--edfm-surface-2: #161f24;
--edfm-surface-3: #1c272d;
--edfm-surface-4: #233037;


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


/* Text */
--edfm-text: #edf0f2;
--edfm-text: #e7eaec;
--edfm-text-muted: #98a5ad;
--edfm-text-muted: #8e9aa1;
--edfm-text-dim: #6c7a82;
--edfm-text-dim: #68757c;


/* Accents -- orange is reserved for navigation/selection/emphasis/
/* Accents -- orange is reserved for navigation/selection/emphasis/
Line 53: Line 63:
--edfm-blue: #4f9fe8;
--edfm-blue: #4f9fe8;


/* Derived link colours (not part of the operator's token list verbatim,
/* Derived link colours */
  but named separately so link handling reads as its own concern) */
--edfm-link: var( --edfm-blue );
--edfm-link: var( --edfm-blue );
--edfm-link-visited: #3f7bb3;
--edfm-link-visited: #3f7bb3;
Line 68: Line 77:
--edfm-status-attention: var( --edfm-orange );
--edfm-status-attention: var( --edfm-orange );
--edfm-status-neutral: var( --edfm-text-dim );
--edfm-status-neutral: var( --edfm-text-dim );
--edfm-status-positive-bg: rgba( 66, 199, 217, 0.12 );
--edfm-status-attention-bg: rgba( 255, 138, 0, 0.12 );
--edfm-status-neutral-bg: rgba( 108, 122, 130, 0.12 );
/* Typography -- explicit desktop scale (2026-08-07 pass 2). Sized in
  rem against the root's real 16px (Vector legacy's own
  @font-size-root is 100%, i.e. browser default -- confirmed by
  reading skins.vector.styles.legacy/variables.less, not assumed)
  rather than nested em, specifically so component sizes can't
  compound smaller than intended inside whatever ambient size an
  ancestor happens to set. */
--edfm-fs-title: clamp( 1.85rem, 1.35rem + 2vw, 2.2rem ); /* ~30-35px */
--edfm-fs-h2: 1.35rem; /* ~21.6px */
--edfm-fs-h3: 1.15rem; /* ~18.4px */
--edfm-fs-body: 1rem; /* 16px */
--edfm-fs-resource-name: 1.1rem; /* ~17.6px */
--edfm-fs-meta: 0.8rem; /* ~12.8px */
--edfm-fs-sidebar: 0.875rem; /* 14px */
--edfm-fs-utility: 0.72rem; /* ~11.5px */


/* Typography */
--edfm-mono: 'JetBrains Mono', 'Fira Code', Consolas, 'SF Mono', Menlo, 'Courier New', monospace;
--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;
--edfm-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
Line 90: Line 117:
--border-color-progressive--active: var( --edfm-orange-bright );
--border-color-progressive--active: var( --edfm-orange-bright );


/* Shared geometry: a small clipped corner reads as "technical panel"
/* Geometry / layout */
  without a giant border-radius anywhere on the site. */
--edfm-corner: 10px;
--edfm-corner: 10px;
--edfm-content-max: 1200px;
--edfm-content-max: 1280px;
/* Vector legacy clears its fixed sidebar with `margin-left: 11em` at
  >=982px (skins.vector.styles.legacy/layouts/screen.less) -- reused
  here, not reinvented, so the centring maths below lines up exactly
  with where the sidebar actually ends. */
--edfm-sidebar-clear: 11em;
/* The gutter is whatever's left of the workspace (viewport minus the
  sidebar) after the capped content width, split evenly, never
  negative. On a screen too narrow to fit sidebar+content-max, this
  collapses to 0 and content just fills the workspace edge-to-edge --
  see "GLOBAL LAYOUT" below for the full explanation. */
--edfm-gutter: max( 0px, calc( ( 100vw - var( --edfm-sidebar-clear ) - var( --edfm-content-max ) ) / 2 ) );
}
}


Line 106: Line 143:
color: var( --edfm-text );
color: var( --edfm-text );
font-family: var( --edfm-sans );
font-family: var( --edfm-sans );
font-size: var( --edfm-fs-body );
}
}
/* Very faint (~2.5%) technical grid across the page background. Only
/* Background treatment: a faint technical grid plus a very soft radial
   visible where an opaque panel (sidebar, article surface, tables) isn't
   glow centred behind the (now centred) content column, so the composition
   already covering it -- the header strip, the sidebar, and the margin
  still has quiet visual interest in the gutters on ultrawide screens
   outside the width-capped article column on wide screens. Not an image
   instead of just flat colour -- both stay under ~3% opacity, this is
  asset; pure CSS gradients. */
   texture, not a HUD. Not image assets; pure CSS gradients. */
body {
body {
background-image:
background-image:
radial-gradient( ellipse 1400px 900px at 50% 0%, rgba( 66, 199, 217, 0.05 ), transparent 60% ),
linear-gradient( rgba( 255, 255, 255, 0.025 ) 1px, transparent 1px ),
linear-gradient( rgba( 255, 255, 255, 0.025 ) 1px, transparent 1px ),
linear-gradient( 90deg, 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;
background-size: auto, 48px 48px, 48px 48px;
background-repeat: no-repeat, repeat, repeat;
background-attachment: fixed, scroll, scroll;
}
}
@media ( prefers-reduced-motion: reduce ) {
@media ( prefers-reduced-motion: reduce ) {
Line 126: Line 167:
}
}
}
}
/* Focus visibility: the pre-redesign stylesheet had no explicit focus
/* Focus visibility: applies to every interactive element, not just links. */
  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,
a:focus-visible,
button:focus-visible,
button:focus-visible,
Line 138: Line 176:
outline: 2px solid var( --edfm-cyan );
outline: 2px solid var( --edfm-cyan );
outline-offset: 2px;
outline-offset: 2px;
}
/* Small reusable angular motif: a corner-cut bracket, used sparingly (see
  the redesign notes in docs/content-style-guide.md for exactly where) --
  deliberately not applied everywhere. */
.edfm-corner-cut {
clip-path: polygon( 0 0, calc( 100% - var( --edfm-corner ) ) 0, 100% var( --edfm-corner ), 100% 100%, 0 100% );
}
}


Line 164: Line 209:
color: var( --edfm-text ) !important;
color: var( --edfm-text ) !important;
font-family: var( --edfm-mono );
font-family: var( --edfm-mono );
font-size: 1.9em;
font-size: var( --edfm-fs-title );
font-weight: 700;
margin-top: 0.15em;
}
}
/* Restrained "instrument label" bracket treatment on major section
/* Section headings (h2): "// " prefix in orange, bright heading text, a
  headings (h2): a plain "// " prefix via ::before (no image, no glow, no
   short orange accent segment over the dim full-width divider core
   animation) plus a short orange accent segment layered over the
  already draws. Substantially more vertical space than a wiki section
  otherwise-dim divider line core already draws under h2. If a heading
  normally gets, per the "sections feel packed together" fix -- 3.25rem
   opts into explicit numbering via {{Section number}} (see
  (~52px) above, ~1.1rem gap to the first content component below. If a
   .edfm-section-number below), the automatic "// " is suppressed so the
   heading opts into explicit numbering via {{Section number}}, the
  two treatments don't double up. */
   automatic "// " is suppressed so the two treatments don't double up. */
.mw-body h2 {
.mw-body h2 {
position: relative;
position: relative;
padding-bottom: 0.3em;
padding-bottom: 0.4em;
margin-top: 1.6em;
margin-top: 3.25rem;
margin-bottom: 1.1rem;
font-size: var( --edfm-fs-h2 );
}
}
.mw-body h2::before {
.mw-body h2::before {
Line 206: Line 255:
h3, h4 {
h3, h4 {
color: var( --edfm-text );
color: var( --edfm-text );
font-size: var( --edfm-fs-h3 );
}
}
h3::before {
h3::before {
Line 219: Line 269:
.mw-body li,
.mw-body li,
.mw-body dd {
.mw-body dd {
line-height: 1.65;
line-height: 1.7;
font-size: var( --edfm-fs-body );
}
}
.mw-body p {
.mw-body p {
margin: 0 0 1em 0;
margin: 0 0 1.1em 0;
max-width: 74em; /* comfortable measure even inside the wider content column */
max-width: 46em; /* comfortable reading measure, not the full column */
}
}
.mw-body ul,
.mw-body ul,
.mw-body ol {
.mw-body ol {
line-height: 1.65;
line-height: 1.7;
margin-bottom: 1em;
margin-bottom: 1.1em;
}
}
.mw-body h2 + p,
/* MW 1.46 wraps headings in a `.mw-heading2`/`.mw-heading3` div, so the
.mw-body h3 + p {
  sibling that immediately follows is that wrapper, not the `h2`/`h3`
margin-top: 0.6em;
  itself -- matching both forms since a page could still have a bare
  heading in edge cases (e.g. content generated without the wrapper). */
.mw-heading2 + p, .mw-body h2 + p,
.mw-heading3 + p, .mw-body h3 + p,
.mw-heading2 + div, .mw-body h2 + div,
.mw-heading3 + div, .mw-body h3 + div {
margin-top: 0;
}
}
hr {
hr {
background-color: var( --edfm-border );
background-color: var( --edfm-border );
border-color: var( --edfm-border );
border-color: var( --edfm-border );
}
/* Quiet, discoverable section-edit controls (logged-in editors only --
  MediaWiki only renders these for users who can edit). Keeping the
  functionality/keyboard access intact while making sure they don't
  compete visually with the heading they're attached to: low opacity at
  rest, full opacity on hover/focus of the heading OR the control itself,
  brackets hidden (the opacity+letter-spacing treatment already reads as
  a distinct control without them). */
.mw-editsection {
margin-left: 1em;
font-family: var( --edfm-mono );
font-size: var( --edfm-fs-utility ) !important;
font-weight: 700;
letter-spacing: 0.05em;
text-transform: uppercase;
opacity: 0.45;
transition: opacity 0.15s ease;
}
.mw-heading:hover .mw-editsection,
.mw-heading:focus-within .mw-editsection,
.mw-editsection:hover,
.mw-editsection:focus-within {
opacity: 1;
}
.mw-editsection a {
color: var( --edfm-text-dim );
}
.mw-editsection a:hover,
.mw-editsection a:focus-visible {
color: var( --edfm-cyan );
}
.mw-editsection-bracket {
display: none;
}
.mw-editsection-divider {
color: var( --edfm-text-dim );
margin: 0 0.3em;
}
}


Line 275: Line 370:


/* ==========================================================================
/* ==========================================================================
   1 + 4. GLOBAL LAYOUT / ARTICLE HEADER
   1. GLOBAL LAYOUT -- centred workspace
   ========================================================================== */
   ========================================================================== */
/* Vector legacy's core layout (skins.vector.styles.legacy/layouts/screen.less)
/* THE fix for "enormous unused region on the right side of wide displays".
  gives `.mw-body` (#content) a left margin to clear the fixed-width
  Vector legacy's core layout (skins.vector.styles.legacy/layouts/
  sidebar and otherwise lets it run edge-to-edge to the browser's right
  screen.less) gives `.mw-body` (#content) a left margin to clear the
  side -- there is no max-width at all, which is why content stretched
  fixed-width sidebar and otherwise lets it run edge-to-edge to the
   excessively on large displays. Capping width here only affects the
  browser's right side with no max-width at all -- the first redesign
   article/footer column; the full-width header/tab bar above it is left
  pass added a max-width but left the column pinned to the sidebar's left
   alone deliberately (its own float/absolute-position math is exactly what
  edge, which is *why* it still read as "a column stuck on the left with
   an earlier round of this project had to carefully debug to get the
   dead space on the right" rather than a composed layout.
   persistent sidebar working at all -- touching it again for a purely
 
   cosmetic width cap isn't worth the regression risk). A full-bleed
  Fix: instead of a fixed `margin-left: 11em`, compute how much space is
   toolbar above a capped content column is also just a normal, accepted
  left over in the workspace (viewport minus the sidebar) once the
   pattern on technical documentation sites. */
  content has its max-width, and split that leftover evenly between the
  left and right margins (via the --edfm-gutter token above) -- so the
   article is centred *within the workspace to the right of the sidebar*,
  not centred in the full viewport (which would ignore the sidebar and
  look off-centre) and not pinned to its left edge either. On a screen
  too narrow for sidebar + max-width content, --edfm-gutter naturally
  evaluates to 0 and this degrades to the old "fill the workspace"
  behaviour -- no separate narrow-screen override needed.
 
  The header/tab bar's own float/absolute-position box (#mw-head) is left
   at its native full width deliberately -- rewriting *that* mechanism is
   a different, much higher-risk change (it took several rounds to get
   right originally) -- but its *contents* (search box, personal tools,
   namespace/view tabs) get their own right/left offsets pulled in by the
   same --edfm-gutter below, so they still visually line up with the
   centred column beneath them instead of hugging the browser edge. */
.mw-body,
.mw-body,
#mw-data-after-content,
#mw-data-after-content,
.mw-footer {
.mw-footer {
margin-left: calc( var( --edfm-sidebar-clear ) + var( --edfm-gutter ) );
margin-right: var( --edfm-gutter );
max-width: var( --edfm-content-max );
max-width: var( --edfm-content-max );
box-sizing: border-box;
box-sizing: border-box;
Line 321: Line 433:
}
}


/* Eyebrow / deck (see Template:Article header). The eyebrow line is
/* ==========================================================================
  authored as ordinary wikitext and, purely as a placement detail, a small
  4. ARTICLE MASTHEAD (eyebrow / title / deck)
   script (MediaWiki:Common.js) moves it directly above #firstHeading on
  ========================================================================== */
  page load -- see the comment there for why that needs JS rather than
/* Eyebrow line is authored as ordinary wikitext (see Template:Article
  CSS/a template (the title is rendered by the skin before the article
  header) and, purely as a placement detail, a small script
  body in the DOM, so nothing living inside the article body can appear
   (MediaWiki:Common.js) moves it directly above #firstHeading on load --
  earlier than it without either moving it in the DOM or abandoning the
  see the comment there for why that needs JS rather than CSS/a template
  real semantic H1, and the brief is explicit the H1 must stay the real
  (the title is rendered by the skin before the article body in the DOM,
   H1). If JS is unavailable the eyebrow still renders, just directly under
  so nothing living inside the article body can appear earlier than it
   the title instead of above it -- nothing breaks, it's a placement
  without either moving it in the DOM or abandoning the real semantic H1).
   nicety, not functionality. */
   If JS is unavailable the eyebrow still renders, just directly under the
   title instead of above it.
 
  The eyebrow/title/deck aren't wrapped in one literal bounding box (they
  live at two different DOM depths -- eyebrow is a sibling of #firstHeading,
  deck is inside the article body further down -- wrapping them in one
  real container would need heavier JS than is justified here), so the
  "designed masthead" read comes from a matching top rule above the
  eyebrow and bottom rule below the deck, a small angular marker, and the
   larger title/subtitle type scale, rather than one drawn box. */
.edfm-eyebrow {
.edfm-eyebrow {
margin: 0 0 0.3em 0;
display: flex;
align-items: center;
gap: 0.55em;
margin: 0 0 0.5em 0;
padding-top: 1.1em;
border-top: 1px solid var( --edfm-border );
font-family: var( --edfm-mono );
font-family: var( --edfm-mono );
font-size: 0.75em;
font-size: var( --edfm-fs-meta );
font-weight: 700;
font-weight: 700;
letter-spacing: 0.08em;
letter-spacing: 0.12em;
text-transform: uppercase;
text-transform: uppercase;
color: var( --edfm-text-dim );
color: var( --edfm-text-dim );
}
.edfm-eyebrow::before {
content: '';
width: 8px;
height: 8px;
flex-shrink: 0;
background: var( --edfm-orange );
clip-path: polygon( 0 0, 100% 0, 100% 65%, 65% 100%, 0 100% );
}
}
.edfm-eyebrow .edfm-orange-mark {
.edfm-eyebrow .edfm-orange-mark {
Line 346: Line 480:
.edfm-deck {
.edfm-deck {
color: var( --edfm-text-muted );
color: var( --edfm-text-muted );
font-size: 1.05em;
font-size: 1.1rem;
max-width: 60em;
line-height: 1.55;
margin: 0.3em 0 1.2em 0;
max-width: 42em;
margin: 0.5em 0 1.7em 0;
padding-bottom: 1.6em;
border-bottom: 1px solid var( --edfm-border );
}
}


Line 356: Line 493:
#mw-panel {
#mw-panel {
background-color: var( --edfm-bg-deep );
background-color: var( --edfm-bg-deep );
}
/* Logo anchors the sidebar visually -- a rule beneath it separates
  "identity" from "navigation" instead of the nav groups just starting
  immediately under the logo with no break. */
#p-logo {
padding-bottom: 1.1rem;
margin-bottom: 0.9rem;
border-bottom: 1px solid var( --edfm-border );
}
/* Each nav group gets real breathing room from the one before it instead
  of being packed together like a stock wiki sidebar. */
#mw-panel .portal {
margin-top: 1.7rem;
}
#mw-panel .portal:first-of-type {
margin-top: 0;
}
}
#mw-panel .portal .body,
#mw-panel .portal .body,
Line 364: Line 517:
color: var( --edfm-text-muted );
color: var( --edfm-text-muted );
display: block;
display: block;
padding: 0.15em 0.4em;
font-size: var( --edfm-fs-sidebar );
margin: 0 -0.4em;
padding: 0.3em 0.5em;
margin: 0.05em -0.5em;
border-left: 2px solid transparent;
border-left: 2px solid transparent;
border-radius: 0;
border-radius: 0;
Line 379: Line 533:
   state" per the colour system, which is why the rest of the sidebar is
   state" per the colour system, which is why the rest of the sidebar is
   deliberately muted rather than orange throughout (an all-orange sidebar
   deliberately muted rather than orange throughout (an all-orange sidebar
   would both fight this indicator and read as visually dominant, which the
   would both fight this indicator and read as visually dominant). */
  brief specifically calls out to avoid). */
.edfm-nav-current > a {
.edfm-nav-current > a {
color: var( --edfm-orange ) !important;
color: var( --edfm-orange ) !important;
font-weight: 700;
font-weight: 700;
border-left-color: var( --edfm-orange );
border-left-color: var( --edfm-orange );
border-left-width: 3px;
background: var( --edfm-surface-1 );
background: var( --edfm-surface-1 );
}
}
Line 393: Line 547:
letter-spacing: 0.08em;
letter-spacing: 0.08em;
text-transform: uppercase;
text-transform: uppercase;
font-size: 0.75em;
font-size: var( --edfm-fs-utility );
border-left: 2px solid var( --edfm-orange );
border-left: 2px solid var( --edfm-orange );
padding-left: 0.5em;
padding-left: 0.5em;
margin-left: -0.5em;
margin-left: -0.5em;
margin-bottom: 0.4em;
}
}


/* ==========================================================================
/* ==========================================================================
   4/9. HEADER / MASTHEAD / MEDIAWIKI TABS
   3. TOP BAR -- two-tier chrome
   ========================================================================== */
   ========================================================================== */
/* Vector legacy's #mw-head naturally has ~2.5em of empty space above the
  tabs row (core: `#left-navigation/#right-navigation { margin-top:2.5em }`),
  originally reserved just for #p-personal to float in. Painting that same
  box with a background gradient that stays transparent for that top
  band and then switches to a surface colour for the tabs band creates a
  real two-tier read -- "primary chrome" (personal tools/search, over the
  page's own background) above "wiki authoring controls" (the tabs, on
  their own distinct strip) below -- without touching #mw-head's own
  position/width mechanics, which is the same fragile absolute-position
  system the very first pass of this project had to debug carefully to
  get the persistent sidebar working at all. Not worth re-risking that
  for a background change. */
#mw-head {
background-image: linear-gradient(
to bottom,
transparent 0,
transparent 2.35em,
var( --edfm-surface-2 ) 2.35em,
var( --edfm-surface-2 ) 100%
);
border-bottom: 1px solid var( --edfm-border );
}
#mw-page-base {
#mw-page-base {
background-color: var( --edfm-bg-deep );
background-color: var( --edfm-bg-deep );
Line 408: Line 585:
#mw-head-base {
#mw-head-base {
background-color: var( --edfm-bg-deep );
background-color: var( --edfm-bg-deep );
}
#p-personal,
.vector-header-container {
border-bottom: 2px solid var( --edfm-orange );
border-bottom: 2px solid var( --edfm-orange );
}
}
#mw-head-base {
/* Personal tools (login/logout) and the search box are the "primary
border-bottom: 2px solid var( --edfm-orange );
  chrome" tier -- pulled in by the same gutter used to centre the article,
  so on wide screens they visually line up with the centred column
  instead of hugging the browser edge, and given noticeably more visual
  weight than the tabs below them. */
#p-personal {
right: calc( 0.75em + var( --edfm-gutter ) );
}
}
/* Personal tools (login/logout) -- a real action, kept orange-adjacent but
  quiet until interacted with, matching "utility control" treatment. */
#p-personal a {
#p-personal a {
color: var( --edfm-text-muted );
color: var( --edfm-text-muted );
font-family: var( --edfm-mono );
font-family: var( --edfm-mono );
font-size: var( --edfm-fs-sidebar );
padding: 0.3em 0.2em;
}
}
#p-personal a:hover {
#p-personal a:hover {
color: var( --edfm-orange );
color: var( --edfm-orange );
}
#right-navigation {
margin-right: var( --edfm-gutter );
}
#left-navigation {
margin-left: calc( var( --edfm-sidebar-clear ) + var( --edfm-gutter ) );
}
.vector-search-box-inner input,
#searchInput {
background-color: var( --edfm-surface-3 );
color: var( --edfm-text );
border: 1px solid var( --edfm-border );
font-family: var( --edfm-mono );
font-size: var( --edfm-fs-sidebar );
padding: 0.4em 0.6em;
}
#searchInput:focus {
border-color: var( --edfm-cyan );
}
#searchInput::placeholder {
color: var( --edfm-text-dim );
}
}
/* Namespace tabs (Main Page / Discussion, left) and view tabs
/* Namespace tabs (Main Page / Discussion, left) and view tabs
Line 442: Line 642:
   genuinely visiting the linked pages first.
   genuinely visiting the linked pages first.


   Per the redesign brief, tabs are "important navigation" (namespace
   These are the "wiki authoring controls" utility tier -- deliberately
   identity) rather than "utility controls" (the view/actions tabs, see
   smaller (--edfm-fs-utility) and quieter than personal-tools/search
   below) -- selected state stays orange; unselected rests at a slightly
  above them, sitting on their own background strip (see #mw-head above).
  dimmer neutral than article body text so the *selected* tab still reads
   Selected state stays orange (it's still real navigation, just
   as the clear focal point. */
  secondary); unselected rests dim so the *selected* tab is the one that
   reads clearly. */
.vector-menu-tabs-legacy li {
.vector-menu-tabs-legacy li {
background-image: none;
background-image: none;
background-color: var( --edfm-surface-2 );
background-color: transparent;
}
}
.vector-menu-tabs-legacy li.selected {
.vector-menu-tabs-legacy li.selected {
Line 460: Line 661:
color: var( --edfm-text-dim );
color: var( --edfm-text-dim );
font-family: var( --edfm-mono );
font-family: var( --edfm-mono );
letter-spacing: 0.01em;
font-size: var( --edfm-fs-utility );
letter-spacing: 0.03em;
text-transform: uppercase;
font-weight: 700;
}
}
.vector-menu-tabs-legacy li a:hover,
.vector-menu-tabs-legacy li a:hover,
Line 475: Line 679:
}
}
/* "More" actions dropdown (#p-cactions) sits in the same tab row; same
/* "More" actions dropdown (#p-cactions) sits in the same tab row; same
   :visited gotcha applies to its menu items. Kept deliberately quiet --
   :visited gotcha applies to its menu items. */
  this is the clearest case of "utility control, not primary nav". */
.vector-menu-dropdown .vector-menu-heading {
.vector-menu-dropdown .vector-menu-heading {
color: var( --edfm-text-dim );
color: var( --edfm-text-dim );
Line 483: Line 686:
padding-left: 8px;
padding-left: 8px;
margin-left: 0;
margin-left: 0;
text-transform: none;
margin-bottom: 0;
letter-spacing: normal;
text-transform: uppercase;
font-size: 1em;
letter-spacing: 0.03em;
font-weight: normal;
font-size: var( --edfm-fs-utility );
font-weight: 700;
}
}
.vector-menu-dropdown .vector-menu-heading:hover,
.vector-menu-dropdown .vector-menu-heading:hover,
Line 493: Line 697:
}
}
.vector-menu-dropdown .vector-menu-content {
.vector-menu-dropdown .vector-menu-content {
background-color: var( --edfm-surface-2 );
background-color: var( --edfm-surface-3 );
border-color: var( --edfm-border );
border-color: var( --edfm-border );
}
}
Line 499: Line 703:
.vector-menu-dropdown .vector-menu-content a:visited {
.vector-menu-dropdown .vector-menu-content a:visited {
color: var( --edfm-text-muted );
color: var( --edfm-text-muted );
font-size: var( --edfm-fs-sidebar );
}
}
.vector-menu-dropdown .vector-menu-content li.selected a,
.vector-menu-dropdown .vector-menu-content li.selected a,
Line 505: Line 710:
}
}
.vector-menu-dropdown .vector-menu-content li:hover {
.vector-menu-dropdown .vector-menu-content li:hover {
background-color: var( --edfm-surface-3 );
background-color: var( --edfm-surface-4 );
}
.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 );
}
}


Line 533: Line 728:


/* ==========================================================================
/* ==========================================================================
   10. TABLE OF CONTENTS
   10. JUMP NAVIGATION (table of contents)
   ========================================================================== */
   ========================================================================== */
/* Restyled as an "EDFM navigation module" rather than a default wiki TOC,
/* A compact navigation strip/tile-grid rather than a traditional TOC box
   while leaving MediaWiki's actual TOC markup/anchors completely alone --
   of small text links -- real MediaWiki anchors/markup untouched, this is
   this is presentation only. "Contents" is kept in the DOM for screen
   all presentation. "Contents" is kept in the DOM for screen readers/
   readers/no-JS/no-CSS fallback (more standard wording there anyway) and
   no-JS/no-CSS fallback (more standard wording there anyway) and visually
   visually replaced with "Jump to" via ::before on the wrapper, with the
   replaced with "Jump to" via ::before on the wrapper, with the real
   real heading text hidden via font-size rather than display:none so it
   heading text hidden via font-size rather than display:none so it
   remains in the accessibility tree. */
   remains in the accessibility tree. */
#toc, .toc {
#toc, .toc {
background-color: var( --edfm-surface-2 ) !important;
background: none;
border: 1px solid var( --edfm-border ) !important;
border: none;
color: var( --edfm-text );
color: var( --edfm-text );
padding: 0.8em 1em;
padding: 0;
clip-path: polygon( 0 0, calc( 100% - var( --edfm-corner ) ) 0, 100% var( --edfm-corner ), 100% 100%, 0 100% );
margin: 1.8rem 0;
}
}
.toctitle {
.toctitle {
position: relative;
position: relative;
margin-bottom: 0.4em;
margin-bottom: 0.7em;
}
}
.toctitle::before {
.toctitle::before {
content: 'Jump to';
content: 'Jump to';
font-family: var( --edfm-mono );
font-family: var( --edfm-mono );
font-size: 0.75em;
font-size: var( --edfm-fs-meta );
font-weight: 700;
font-weight: 700;
letter-spacing: 0.1em;
letter-spacing: 0.12em;
text-transform: uppercase;
text-transform: uppercase;
color: var( --edfm-orange );
color: var( --edfm-orange );
Line 584: Line 779:
color: var( --edfm-text-dim );
color: var( --edfm-text-dim );
}
}
/* Top-level entries as wrapped horizontal "chips" -- reads well for the
/* Desktop: a real grid of clickable tiles (3 columns suits this site's
   short/medium pages this site mostly has, and simply wraps onto more
  typical 5-8 top-level sections well: commonly 2-3 rows) instead of one
   rows for longer ones rather than needing a separate vertical mode. */
   long line of small text. Each tile has its own surface, a visible
   boundary via the accent rail (not a full border -- see "stop using a
  border around everything"), and an obvious hover state. */
.toc > ul {
.toc > ul {
display: flex;
display: grid;
flex-wrap: wrap;
grid-template-columns: repeat( 3, 1fr );
gap: 0.4em 1.2em;
gap: 0.6rem;
list-style: none;
list-style: none;
margin: 0;
margin: 0;
padding: 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 {
.toc li {
Line 607: Line 796:
}
}
.toc a {
.toc a {
display: inline-flex;
display: flex;
align-items: baseline;
align-items: center;
gap: 0.35em;
gap: 0.6em;
height: 100%;
box-sizing: border-box;
padding: 0.7em 0.9em;
background: var( --edfm-surface-2 );
border-left: 2px solid var( --edfm-border );
color: var( --edfm-text-muted );
color: var( --edfm-text-muted );
text-decoration: none;
text-decoration: none;
font-size: 0.92em;
font-size: 0.88rem;
transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
}
.toc a:hover {
.toc a:hover {
color: var( --edfm-cyan );
background: var( --edfm-surface-4 );
border-left-color: var( --edfm-cyan );
color: var( --edfm-text );
transform: translateY( -1px );
}
/* Nested sub-levels (rare on this site so far) drop back to a plain
  indented block list inside their parent tile's grid cell rather than
  trying to stay gridded themselves. */
.toc ul ul {
grid-column: unset;
list-style: none;
margin: 0.3em 0 0 1.2em;
padding: 0;
display: block;
}
.toc ul ul a {
background: none;
border-left-width: 1px;
padding: 0.3em 0.6em;
font-size: 0.85em;
}
}
.tocnumber {
.tocnumber {
Line 621: Line 835:
font-family: var( --edfm-mono );
font-family: var( --edfm-mono );
font-weight: 700;
font-weight: 700;
min-width: 1.2em;
font-size: 1.05rem;
min-width: 1.4em;
}
}
.toctext {
.toctext {
color: inherit;
color: inherit;
line-height: 1.3;
}
@media ( max-width: 1000px ) and ( min-width: 801px ) {
.toc > ul {
grid-template-columns: repeat( 2, 1fr );
}
}
}


Line 631: Line 852:
   ========================================================================== */
   ========================================================================== */
/* Deliberately NOT defined here. .edfm-box / .edfm-panel* / .edfm-status* /
/* Deliberately NOT defined here. .edfm-box / .edfm-panel* / .edfm-status* /
   .edfm-inline-flag are used exclusively by the editorial templates (see
   .edfm-inline-flag / .edfm-related* are used exclusively by the
  Template:Article status, Template:Draft warning, etc.), which already
  editorial templates (see Template:Article status, Template:Draft
   load Template:EDFM style/styles.css themselves via <templatestyles>.
  warning, Template:Related articles, 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
   Defining the same class names in both this file and that one would
   leave their relative precedence dependent on unclear/unstable ordering
   leave their relative precedence dependent on unclear/unstable ordering
Line 651: Line 873:
color: var( --edfm-text );
color: var( --edfm-text );
border-color: var( --edfm-border );
border-color: var( --edfm-border );
font-size: var( --edfm-fs-body );
}
}
table.wikitable > tr > th,
table.wikitable > tr > th,
Line 660: Line 883:
letter-spacing: 0.03em;
letter-spacing: 0.03em;
text-transform: uppercase;
text-transform: uppercase;
font-size: 0.85em;
font-size: var( --edfm-fs-meta );
text-align: left;
text-align: left;
padding: 0.6em 0.8em;
}
}
table.wikitable > tr > td,
table.wikitable > tr > td,
table.wikitable > * > tr > td {
table.wikitable > * > tr > td {
border-color: var( --edfm-border-soft );
border-color: var( --edfm-border-soft );
padding: 0.5em 0.7em;
padding: 0.6em 0.8em;
}
}
/* Subtle alternating row treatment -- helps scanning wide/dense reference
/* Subtle alternating row treatment -- helps scanning wide/dense reference
Line 676: Line 900:


/* ==========================================================================
/* ==========================================================================
   13. FOOTER
   15. FOOTER
   ========================================================================== */
   ========================================================================== */
/* A real branded footer: a small wordmark line (pure CSS generated
  content -- decorative branding only, redundant with the sidebar logo
  already visible, so nothing load-bearing depends on it being
  selectable), a top rule with more separation from the article above it,
  and MediaWiki's real info/places/icon links laid out on a clean grid
  with the badges aligned as a group rather than floating alone. */
.mw-footer {
.mw-footer {
margin-left: auto;
margin-left: calc( var( --edfm-sidebar-clear ) + var( --edfm-gutter ) );
margin-right: auto;
margin-right: var( --edfm-gutter );
margin-top: 2.5rem;
padding-top: 1.6rem;
border-top: 1px solid var( --edfm-border );
border-top: 1px solid var( --edfm-border );
display: grid;
display: grid;
grid-template-columns: 1fr auto;
grid-template-columns: 1fr auto;
grid-template-areas: "info icons" "places icons";
grid-template-areas: "brand brand" "info icons" "places icons";
align-items: center;
align-items: center;
column-gap: 2em;
column-gap: 2em;
row-gap: 0.3em;
row-gap: 0.4rem;
}
.mw-footer::before {
grid-area: brand;
content: 'Elite Dangerous Field Manual';
font-family: var( --edfm-mono );
font-size: var( --edfm-fs-meta );
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var( --edfm-text-dim );
margin-bottom: 0.4rem;
}
}
.mw-footer,
.mw-footer,
Line 695: Line 938:
color: var( --edfm-text-dim );
color: var( --edfm-text-dim );
border-color: var( --edfm-border-soft );
border-color: var( --edfm-border-soft );
font-size: var( --edfm-fs-meta );
}
}
#footer-info {
#footer-info {
Line 703: Line 947:
grid-area: places;
grid-area: places;
margin: 0;
margin: 0;
}
#footer-places li {
display: inline-block;
margin-right: 1em;
}
}
#footer-icons {
#footer-icons {
Line 718: Line 966:
.mw-footer {
.mw-footer {
grid-template-columns: 1fr;
grid-template-columns: 1fr;
grid-template-areas: "info" "places" "icons";
grid-template-areas: "brand" "info" "places" "icons";
}
}
#footer-icons {
#footer-icons {
Line 729: Line 977:
   ========================================================================== */
   ========================================================================== */
.catlinks {
.catlinks {
background-color: var( --edfm-surface-2 ) !important;
background: none !important;
border-color: var( --edfm-border ) !important;
border: none !important;
color: var( --edfm-text-muted );
border-top: 1px solid var( --edfm-border-soft ) !important;
color: var( --edfm-text-dim );
font-size: var( --edfm-fs-meta );
padding: 0.9em 0 0 0 !important;
margin-top: 1.8rem !important;
}
}
div.thumbinner {
div.thumbinner {
Line 758: Line 1,010:
float: right;
float: right;
clear: right;
clear: right;
width: 300px;
width: 310px;
margin: 0 0 1.2em 1.2em;
margin: 0 0 1.2em 1.2em;
border: 1px solid var( --edfm-orange );
border: 1px solid var( --edfm-border );
border-top: 2px solid var( --edfm-orange );
background: var( --edfm-surface-2 );
background: var( --edfm-surface-2 );
color: var( --edfm-text );
color: var( --edfm-text );
font-size: 0.9em;
font-size: 0.92rem;
}
}
.edfm-infobox-title {
.edfm-infobox-title {
Line 773: Line 1,026:
text-transform: uppercase;
text-transform: uppercase;
text-align: center;
text-align: center;
padding: 0.4em 0.6em;
padding: 0.5em 0.6em;
clip-path: polygon( 0 0, calc( 100% - 14px ) 0, 100% 14px, 100% 100%, 0 100% );
clip-path: polygon( 0 0, calc( 100% - 14px ) 0, 100% 14px, 100% 100%, 0 100% );
}
}
Line 784: Line 1,037:
display: flex;
display: flex;
border-bottom: 1px solid var( --edfm-border-soft );
border-bottom: 1px solid var( --edfm-border-soft );
padding: 0.35em 0.6em;
padding: 0.45em 0.7em;
}
}
.edfm-infobox-row:last-child {
.edfm-infobox-row:last-child {
Line 792: Line 1,045:
font-weight: 700;
font-weight: 700;
font-family: var( --edfm-mono );
font-family: var( --edfm-mono );
font-size: 0.85em;
font-size: var( --edfm-fs-meta );
width: 40%;
width: 40%;
flex-shrink: 0;
flex-shrink: 0;
Line 859: Line 1,112:
position: static;
position: static;
width: auto;
width: auto;
background-image: none;
background-color: var( --edfm-surface-2 );
}
}
#left-navigation,
#left-navigation,
#right-navigation {
#right-navigation {
float: none;
float: none;
margin: 0;
margin: 0 !important;
width: auto;
width: auto;
clear: both;
clear: both;
}
}
#left-navigation {
#left-navigation {
margin-top: 0;
margin-top: 0 !important;
}
}
/* Core Vector legacy floats each tab/dropdown portlet
/* Core Vector legacy floats each tab/dropdown portlet
Line 899: Line 1,154:
padding: 0.5em 1em;
padding: 0.5em 1em;
margin: 0;
margin: 0;
right: auto;
right: auto !important;
top: auto;
top: auto;
}
}
Line 925: Line 1,180:
#mw-data-after-content,
#mw-data-after-content,
.mw-footer {
.mw-footer {
margin-left: 0;
margin-left: 0 !important;
margin-right: 0 !important;
max-width: none;
max-width: none;
}
}
Line 937: Line 1,193:
}
}
.toc > ul {
.toc > ul {
gap: 0.3em 0.9em;
grid-template-columns: 1fr;
gap: 0.5rem;
}
}
#firstHeading {
#firstHeading {
font-size: 1.5em;
font-size: 1.6rem;
}
.mw-body h2 {
margin-top: 2.25rem;
}
.edfm-eyebrow {
padding-top: 0.9em;
}
}
}
}

Revision as of 17:28, 7 August 2026

/* ==========================================================================
   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).

   2026-08-07 SECOND PASS: the first redesign pass was judged too close to
   stock MediaWiki with a colour change -- this pass changes the actual
   visual composition (centred workspace instead of a huge dead gutter,
   a two-tier header, a real masthead, a tile-grid TOC, a restructured
   status module, larger deliberate type scale, depth via surface
   elevation instead of borders-around-everything) while reusing every
   working mechanism from the first pass rather than throwing it away --
   the tab/:visited fix, the external-link specificity fix, the mobile
   reorder fix, and focus-visible/reduced-motion are all still here,
   unchanged in mechanism.
   ========================================================================== */

/* ==========================================================================
   1. DESIGN TOKENS
   ========================================================================== */
:root {
	/* Depth system: site (outermost, visible in the sidebar/header/gutters)
	   -> article surface -> component surfaces, each a deliberate step
	   brighter so the page reads as having actual depth rather than "one
	   background colour with slightly lighter boxes everywhere". */
	--edfm-bg-deep: #07090b;
	--edfm-bg-page: #0a0e11;
	--edfm-surface-1: #10171b;
	--edfm-surface-2: #161f24;
	--edfm-surface-3: #1c272d;
	--edfm-surface-4: #233037;

	--edfm-border: #26333b;
	--edfm-border-soft: rgba( 255, 255, 255, 0.06 );

	--edfm-text: #edf0f2;
	--edfm-text-muted: #98a5ad;
	--edfm-text-dim: #6c7a82;

	/* 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 */
	--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 );
	--edfm-status-positive-bg: rgba( 66, 199, 217, 0.12 );
	--edfm-status-attention-bg: rgba( 255, 138, 0, 0.12 );
	--edfm-status-neutral-bg: rgba( 108, 122, 130, 0.12 );

	/* Typography -- explicit desktop scale (2026-08-07 pass 2). Sized in
	   rem against the root's real 16px (Vector legacy's own
	   @font-size-root is 100%, i.e. browser default -- confirmed by
	   reading skins.vector.styles.legacy/variables.less, not assumed)
	   rather than nested em, specifically so component sizes can't
	   compound smaller than intended inside whatever ambient size an
	   ancestor happens to set. */
	--edfm-fs-title: clamp( 1.85rem, 1.35rem + 2vw, 2.2rem ); /* ~30-35px */
	--edfm-fs-h2: 1.35rem; /* ~21.6px */
	--edfm-fs-h3: 1.15rem; /* ~18.4px */
	--edfm-fs-body: 1rem; /* 16px */
	--edfm-fs-resource-name: 1.1rem; /* ~17.6px */
	--edfm-fs-meta: 0.8rem; /* ~12.8px */
	--edfm-fs-sidebar: 0.875rem; /* 14px */
	--edfm-fs-utility: 0.72rem; /* ~11.5px */

	--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 );

	/* Geometry / layout */
	--edfm-corner: 10px;
	--edfm-content-max: 1280px;
	/* Vector legacy clears its fixed sidebar with `margin-left: 11em` at
	   >=982px (skins.vector.styles.legacy/layouts/screen.less) -- reused
	   here, not reinvented, so the centring maths below lines up exactly
	   with where the sidebar actually ends. */
	--edfm-sidebar-clear: 11em;
	/* The gutter is whatever's left of the workspace (viewport minus the
	   sidebar) after the capped content width, split evenly, never
	   negative. On a screen too narrow to fit sidebar+content-max, this
	   collapses to 0 and content just fills the workspace edge-to-edge --
	   see "GLOBAL LAYOUT" below for the full explanation. */
	--edfm-gutter: max( 0px, calc( ( 100vw - var( --edfm-sidebar-clear ) - var( --edfm-content-max ) ) / 2 ) );
}

/* ==========================================================================
   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 );
	font-size: var( --edfm-fs-body );
}
/* Background treatment: a faint technical grid plus a very soft radial
   glow centred behind the (now centred) content column, so the composition
   still has quiet visual interest in the gutters on ultrawide screens
   instead of just flat colour -- both stay under ~3% opacity, this is
   texture, not a HUD. Not image assets; pure CSS gradients. */
body {
	background-image:
		radial-gradient( ellipse 1400px 900px at 50% 0%, rgba( 66, 199, 217, 0.05 ), transparent 60% ),
		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: auto, 48px 48px, 48px 48px;
	background-repeat: no-repeat, repeat, repeat;
	background-attachment: fixed, scroll, scroll;
}
@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: 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;
}

/* Small reusable angular motif: a corner-cut bracket, used sparingly (see
   the redesign notes in docs/content-style-guide.md for exactly where) --
   deliberately not applied everywhere. */
.edfm-corner-cut {
	clip-path: polygon( 0 0, calc( 100% - var( --edfm-corner ) ) 0, 100% var( --edfm-corner ), 100% 100%, 0 100% );
}

/* ==========================================================================
   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: var( --edfm-fs-title );
	font-weight: 700;
	margin-top: 0.15em;
}
/* Section headings (h2): "// " prefix in orange, bright heading text, a
   short orange accent segment over the dim full-width divider core
   already draws. Substantially more vertical space than a wiki section
   normally gets, per the "sections feel packed together" fix -- 3.25rem
   (~52px) above, ~1.1rem gap to the first content component below. If a
   heading opts into explicit numbering via {{Section number}}, the
   automatic "// " is suppressed so the two treatments don't double up. */
.mw-body h2 {
	position: relative;
	padding-bottom: 0.4em;
	margin-top: 3.25rem;
	margin-bottom: 1.1rem;
	font-size: var( --edfm-fs-h2 );
}
.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 );
	font-size: var( --edfm-fs-h3 );
}
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.7;
	font-size: var( --edfm-fs-body );
}
.mw-body p {
	margin: 0 0 1.1em 0;
	max-width: 46em; /* comfortable reading measure, not the full column */
}
.mw-body ul,
.mw-body ol {
	line-height: 1.7;
	margin-bottom: 1.1em;
}
/* MW 1.46 wraps headings in a `.mw-heading2`/`.mw-heading3` div, so the
   sibling that immediately follows is that wrapper, not the `h2`/`h3`
   itself -- matching both forms since a page could still have a bare
   heading in edge cases (e.g. content generated without the wrapper). */
.mw-heading2 + p, .mw-body h2 + p,
.mw-heading3 + p, .mw-body h3 + p,
.mw-heading2 + div, .mw-body h2 + div,
.mw-heading3 + div, .mw-body h3 + div {
	margin-top: 0;
}
hr {
	background-color: var( --edfm-border );
	border-color: var( --edfm-border );
}

/* Quiet, discoverable section-edit controls (logged-in editors only --
   MediaWiki only renders these for users who can edit). Keeping the
   functionality/keyboard access intact while making sure they don't
   compete visually with the heading they're attached to: low opacity at
   rest, full opacity on hover/focus of the heading OR the control itself,
   brackets hidden (the opacity+letter-spacing treatment already reads as
   a distinct control without them). */
.mw-editsection {
	margin-left: 1em;
	font-family: var( --edfm-mono );
	font-size: var( --edfm-fs-utility ) !important;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	opacity: 0.45;
	transition: opacity 0.15s ease;
}
.mw-heading:hover .mw-editsection,
.mw-heading:focus-within .mw-editsection,
.mw-editsection:hover,
.mw-editsection:focus-within {
	opacity: 1;
}
.mw-editsection a {
	color: var( --edfm-text-dim );
}
.mw-editsection a:hover,
.mw-editsection a:focus-visible {
	color: var( --edfm-cyan );
}
.mw-editsection-bracket {
	display: none;
}
.mw-editsection-divider {
	color: var( --edfm-text-dim );
	margin: 0 0.3em;
}

/* ==========================================================================
   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. GLOBAL LAYOUT -- centred workspace
   ========================================================================== */
/* THE fix for "enormous unused region on the right side of wide displays".
   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 with no max-width at all -- the first redesign
   pass added a max-width but left the column pinned to the sidebar's left
   edge, which is *why* it still read as "a column stuck on the left with
   dead space on the right" rather than a composed layout.

   Fix: instead of a fixed `margin-left: 11em`, compute how much space is
   left over in the workspace (viewport minus the sidebar) once the
   content has its max-width, and split that leftover evenly between the
   left and right margins (via the --edfm-gutter token above) -- so the
   article is centred *within the workspace to the right of the sidebar*,
   not centred in the full viewport (which would ignore the sidebar and
   look off-centre) and not pinned to its left edge either. On a screen
   too narrow for sidebar + max-width content, --edfm-gutter naturally
   evaluates to 0 and this degrades to the old "fill the workspace"
   behaviour -- no separate narrow-screen override needed.

   The header/tab bar's own float/absolute-position box (#mw-head) is left
   at its native full width deliberately -- rewriting *that* mechanism is
   a different, much higher-risk change (it took several rounds to get
   right originally) -- but its *contents* (search box, personal tools,
   namespace/view tabs) get their own right/left offsets pulled in by the
   same --edfm-gutter below, so they still visually line up with the
   centred column beneath them instead of hugging the browser edge. */
.mw-body,
#mw-data-after-content,
.mw-footer {
	margin-left: calc( var( --edfm-sidebar-clear ) + var( --edfm-gutter ) );
	margin-right: var( --edfm-gutter );
	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;
}

/* ==========================================================================
   4. ARTICLE MASTHEAD (eyebrow / title / deck)
   ========================================================================== */
/* Eyebrow line is authored as ordinary wikitext (see Template:Article
   header) and, purely as a placement detail, a small script
   (MediaWiki:Common.js) moves it directly above #firstHeading on 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).
   If JS is unavailable the eyebrow still renders, just directly under the
   title instead of above it.

   The eyebrow/title/deck aren't wrapped in one literal bounding box (they
   live at two different DOM depths -- eyebrow is a sibling of #firstHeading,
   deck is inside the article body further down -- wrapping them in one
   real container would need heavier JS than is justified here), so the
   "designed masthead" read comes from a matching top rule above the
   eyebrow and bottom rule below the deck, a small angular marker, and the
   larger title/subtitle type scale, rather than one drawn box. */
.edfm-eyebrow {
	display: flex;
	align-items: center;
	gap: 0.55em;
	margin: 0 0 0.5em 0;
	padding-top: 1.1em;
	border-top: 1px solid var( --edfm-border );
	font-family: var( --edfm-mono );
	font-size: var( --edfm-fs-meta );
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var( --edfm-text-dim );
}
.edfm-eyebrow::before {
	content: '';
	width: 8px;
	height: 8px;
	flex-shrink: 0;
	background: var( --edfm-orange );
	clip-path: polygon( 0 0, 100% 0, 100% 65%, 65% 100%, 0 100% );
}
.edfm-eyebrow .edfm-orange-mark {
	color: var( --edfm-orange );
}
.edfm-deck {
	color: var( --edfm-text-muted );
	font-size: 1.1rem;
	line-height: 1.55;
	max-width: 42em;
	margin: 0.5em 0 1.7em 0;
	padding-bottom: 1.6em;
	border-bottom: 1px solid var( --edfm-border );
}

/* ==========================================================================
   1. SIDEBAR
   ========================================================================== */
#mw-panel {
	background-color: var( --edfm-bg-deep );
}
/* Logo anchors the sidebar visually -- a rule beneath it separates
   "identity" from "navigation" instead of the nav groups just starting
   immediately under the logo with no break. */
#p-logo {
	padding-bottom: 1.1rem;
	margin-bottom: 0.9rem;
	border-bottom: 1px solid var( --edfm-border );
}
/* Each nav group gets real breathing room from the one before it instead
   of being packed together like a stock wiki sidebar. */
#mw-panel .portal {
	margin-top: 1.7rem;
}
#mw-panel .portal:first-of-type {
	margin-top: 0;
}
#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;
	font-size: var( --edfm-fs-sidebar );
	padding: 0.3em 0.5em;
	margin: 0.05em -0.5em;
	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). */
.edfm-nav-current > a {
	color: var( --edfm-orange ) !important;
	font-weight: 700;
	border-left-color: var( --edfm-orange );
	border-left-width: 3px;
	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: var( --edfm-fs-utility );
	border-left: 2px solid var( --edfm-orange );
	padding-left: 0.5em;
	margin-left: -0.5em;
	margin-bottom: 0.4em;
}

/* ==========================================================================
   3. TOP BAR -- two-tier chrome
   ========================================================================== */
/* Vector legacy's #mw-head naturally has ~2.5em of empty space above the
   tabs row (core: `#left-navigation/#right-navigation { margin-top:2.5em }`),
   originally reserved just for #p-personal to float in. Painting that same
   box with a background gradient that stays transparent for that top
   band and then switches to a surface colour for the tabs band creates a
   real two-tier read -- "primary chrome" (personal tools/search, over the
   page's own background) above "wiki authoring controls" (the tabs, on
   their own distinct strip) below -- without touching #mw-head's own
   position/width mechanics, which is the same fragile absolute-position
   system the very first pass of this project had to debug carefully to
   get the persistent sidebar working at all. Not worth re-risking that
   for a background change. */
#mw-head {
	background-image: linear-gradient(
		to bottom,
		transparent 0,
		transparent 2.35em,
		var( --edfm-surface-2 ) 2.35em,
		var( --edfm-surface-2 ) 100%
	);
	border-bottom: 1px solid var( --edfm-border );
}
#mw-page-base {
	background-color: var( --edfm-bg-deep );
	background-image: none;
}
#mw-head-base {
	background-color: var( --edfm-bg-deep );
	border-bottom: 2px solid var( --edfm-orange );
}
/* Personal tools (login/logout) and the search box are the "primary
   chrome" tier -- pulled in by the same gutter used to centre the article,
   so on wide screens they visually line up with the centred column
   instead of hugging the browser edge, and given noticeably more visual
   weight than the tabs below them. */
#p-personal {
	right: calc( 0.75em + var( --edfm-gutter ) );
}
#p-personal a {
	color: var( --edfm-text-muted );
	font-family: var( --edfm-mono );
	font-size: var( --edfm-fs-sidebar );
	padding: 0.3em 0.2em;
}
#p-personal a:hover {
	color: var( --edfm-orange );
}
#right-navigation {
	margin-right: var( --edfm-gutter );
}
#left-navigation {
	margin-left: calc( var( --edfm-sidebar-clear ) + var( --edfm-gutter ) );
}
.vector-search-box-inner input,
#searchInput {
	background-color: var( --edfm-surface-3 );
	color: var( --edfm-text );
	border: 1px solid var( --edfm-border );
	font-family: var( --edfm-mono );
	font-size: var( --edfm-fs-sidebar );
	padding: 0.4em 0.6em;
}
#searchInput:focus {
	border-color: var( --edfm-cyan );
}
#searchInput::placeholder {
	color: var( --edfm-text-dim );
}
/* 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.

   These are the "wiki authoring controls" utility tier -- deliberately
   smaller (--edfm-fs-utility) and quieter than personal-tools/search
   above them, sitting on their own background strip (see #mw-head above).
   Selected state stays orange (it's still real navigation, just
   secondary); unselected rests dim so the *selected* tab is the one that
   reads clearly. */
.vector-menu-tabs-legacy li {
	background-image: none;
	background-color: transparent;
}
.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 );
	font-size: var( --edfm-fs-utility );
	letter-spacing: 0.03em;
	text-transform: uppercase;
	font-weight: 700;
}
.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. */
.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;
	margin-bottom: 0;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	font-size: var( --edfm-fs-utility );
	font-weight: 700;
}
.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-3 );
	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 );
	font-size: var( --edfm-fs-sidebar );
}
.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-4 );
}

/* ==========================================================================
   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. JUMP NAVIGATION (table of contents)
   ========================================================================== */
/* A compact navigation strip/tile-grid rather than a traditional TOC box
   of small text links -- real MediaWiki anchors/markup untouched, this is
   all presentation. "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: none;
	border: none;
	color: var( --edfm-text );
	padding: 0;
	margin: 1.8rem 0;
}
.toctitle {
	position: relative;
	margin-bottom: 0.7em;
}
.toctitle::before {
	content: 'Jump to';
	font-family: var( --edfm-mono );
	font-size: var( --edfm-fs-meta );
	font-weight: 700;
	letter-spacing: 0.12em;
	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 );
}
/* Desktop: a real grid of clickable tiles (3 columns suits this site's
   typical 5-8 top-level sections well: commonly 2-3 rows) instead of one
   long line of small text. Each tile has its own surface, a visible
   boundary via the accent rail (not a full border -- see "stop using a
   border around everything"), and an obvious hover state. */
.toc > ul {
	display: grid;
	grid-template-columns: repeat( 3, 1fr );
	gap: 0.6rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.toc li {
	margin: 0;
}
.toc a {
	display: flex;
	align-items: center;
	gap: 0.6em;
	height: 100%;
	box-sizing: border-box;
	padding: 0.7em 0.9em;
	background: var( --edfm-surface-2 );
	border-left: 2px solid var( --edfm-border );
	color: var( --edfm-text-muted );
	text-decoration: none;
	font-size: 0.88rem;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.toc a:hover {
	background: var( --edfm-surface-4 );
	border-left-color: var( --edfm-cyan );
	color: var( --edfm-text );
	transform: translateY( -1px );
}
/* Nested sub-levels (rare on this site so far) drop back to a plain
   indented block list inside their parent tile's grid cell rather than
   trying to stay gridded themselves. */
.toc ul ul {
	grid-column: unset;
	list-style: none;
	margin: 0.3em 0 0 1.2em;
	padding: 0;
	display: block;
}
.toc ul ul a {
	background: none;
	border-left-width: 1px;
	padding: 0.3em 0.6em;
	font-size: 0.85em;
}
.tocnumber {
	color: var( --edfm-orange );
	font-family: var( --edfm-mono );
	font-weight: 700;
	font-size: 1.05rem;
	min-width: 1.4em;
}
.toctext {
	color: inherit;
	line-height: 1.3;
}
@media ( max-width: 1000px ) and ( min-width: 801px ) {
	.toc > ul {
		grid-template-columns: repeat( 2, 1fr );
	}
}

/* ==========================================================================
   6. PANELS / CALLOUTS, and 11. ARTICLE METADATA / STATUS MODULE
   ========================================================================== */
/* Deliberately NOT defined here. .edfm-box / .edfm-panel* / .edfm-status* /
   .edfm-inline-flag / .edfm-related* are used exclusively by the
   editorial templates (see Template:Article status, Template:Draft
   warning, Template:Related articles, 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 );
	font-size: var( --edfm-fs-body );
}
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: var( --edfm-fs-meta );
	text-align: left;
	padding: 0.6em 0.8em;
}
table.wikitable > tr > td,
table.wikitable > * > tr > td {
	border-color: var( --edfm-border-soft );
	padding: 0.6em 0.8em;
}
/* 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 );
}

/* ==========================================================================
   15. FOOTER
   ========================================================================== */
/* A real branded footer: a small wordmark line (pure CSS generated
   content -- decorative branding only, redundant with the sidebar logo
   already visible, so nothing load-bearing depends on it being
   selectable), a top rule with more separation from the article above it,
   and MediaWiki's real info/places/icon links laid out on a clean grid
   with the badges aligned as a group rather than floating alone. */
.mw-footer {
	margin-left: calc( var( --edfm-sidebar-clear ) + var( --edfm-gutter ) );
	margin-right: var( --edfm-gutter );
	margin-top: 2.5rem;
	padding-top: 1.6rem;
	border-top: 1px solid var( --edfm-border );
	display: grid;
	grid-template-columns: 1fr auto;
	grid-template-areas: "brand brand" "info icons" "places icons";
	align-items: center;
	column-gap: 2em;
	row-gap: 0.4rem;
}
.mw-footer::before {
	grid-area: brand;
	content: 'Elite Dangerous Field Manual';
	font-family: var( --edfm-mono );
	font-size: var( --edfm-fs-meta );
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var( --edfm-text-dim );
	margin-bottom: 0.4rem;
}
.mw-footer,
.mw-footer li,
#footer-info,
#footer-info li {
	color: var( --edfm-text-dim );
	border-color: var( --edfm-border-soft );
	font-size: var( --edfm-fs-meta );
}
#footer-info {
	grid-area: info;
	margin: 0;
}
#footer-places {
	grid-area: places;
	margin: 0;
}
#footer-places li {
	display: inline-block;
	margin-right: 1em;
}
#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: "brand" "info" "places" "icons";
	}
	#footer-icons {
		margin-top: 0.5em;
	}
}

/* ==========================================================================
   MISC MediaWiki UI chrome that ships with light backgrounds by default
   ========================================================================== */
.catlinks {
	background: none !important;
	border: none !important;
	border-top: 1px solid var( --edfm-border-soft ) !important;
	color: var( --edfm-text-dim );
	font-size: var( --edfm-fs-meta );
	padding: 0.9em 0 0 0 !important;
	margin-top: 1.8rem !important;
}
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: 310px;
	margin: 0 0 1.2em 1.2em;
	border: 1px solid var( --edfm-border );
	border-top: 2px solid var( --edfm-orange );
	background: var( --edfm-surface-2 );
	color: var( --edfm-text );
	font-size: 0.92rem;
}
.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.5em 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.45em 0.7em;
}
.edfm-infobox-row:last-child {
	border-bottom: none;
}
.edfm-infobox-label {
	font-weight: 700;
	font-family: var( --edfm-mono );
	font-size: var( --edfm-fs-meta );
	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;
		background-image: none;
		background-color: var( --edfm-surface-2 );
	}
	#left-navigation,
	#right-navigation {
		float: none;
		margin: 0 !important;
		width: auto;
		clear: both;
	}
	#left-navigation {
		margin-top: 0 !important;
	}
	/* 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 !important;
		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 !important;
		margin-right: 0 !important;
		max-width: none;
	}
	.mw-body {
		margin-top: 0;
		border-width: 0;
		padding: 1em;
	}
	.edfm-status-details {
		grid-template-columns: 1fr;
	}
	.toc > ul {
		grid-template-columns: 1fr;
		gap: 0.5rem;
	}
	#firstHeading {
		font-size: 1.6rem;
	}
	.mw-body h2 {
		margin-top: 2.25rem;
	}
	.edfm-eyebrow {
		padding-top: 0.9em;
	}
}