|
|
| Line 1: |
Line 1: |
| /* ==========================================================================
| |
| 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.9rem, 1.4rem + 2vw, 2.25rem ); /* ~30-36px */
| |
| --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.9375rem; /* 15px -- polish pass: +1px for readability */
| |
| --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;
| |
| /* Polish-pass bump from 1280px -- article read as slightly too narrow
| |
| on large desktop displays, and future reference tables (engineering,
| |
| ship stats, colonisation data) will want the room. Still centred
| |
| within the workspace via --edfm-gutter below, not stretched
| |
| edge-to-edge. */
| |
| --edfm-content-max: 1320px;
| |
| /* RuneScape.wiki-style integrated rail: wide enough for readable labels,
| |
| but joined directly to the page plane. Width and clear match so the
| |
| article starts beside the sidebar shadow instead of after a dead gutter. */
| |
| --edfm-sidebar-width: 12.75rem;
| |
| --edfm-sidebar-clear: 12.75rem;
| |
| /* 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;
| |
| }
| |
| /* Full-height sidebar rail: mirrors the RuneScape.wiki behavior where the
| |
| left rail has no visible bottom edge. The real #mw-panel only carries the
| |
| navigation content; this fixed layer paints the uninterrupted surface,
| |
| border, and shadow down the whole viewport. */
| |
| body::before {
| |
| content: '';
| |
| position: fixed;
| |
| top: 0;
| |
| left: 0;
| |
| bottom: 0;
| |
| width: var( --edfm-sidebar-width );
| |
| background: linear-gradient( 180deg, var( --edfm-surface-1 ) 0%, var( --edfm-bg-deep ) 100% );
| |
| border-right: 1px solid var( --edfm-border );
| |
| box-shadow: 10px 0 22px rgba( 0, 0, 0, 0.32 );
| |
| pointer-events: none;
| |
| z-index: 1;
| |
| }
| |
| @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 {
| |
| position: relative;
| |
| z-index: 2;
| |
| margin-left: var( --edfm-sidebar-clear );
| |
| 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 {
| |
| /* Keep real table layout so header cells and body cells share one column grid.
| |
| The earlier display:block + tbody display:table overflow hack made sortable
| |
| headers size independently from body columns, which visibly misaligned the
| |
| Engineer directory after portrait chips were added. */
| |
| display: table;
| |
| width: 100%;
| |
| table-layout: auto;
| |
| }
| |
| .mw-body table.wikitable th,
| |
| .mw-body table.wikitable td,
| |
| .mw-body table.mw-datatable th,
| |
| .mw-body table.mw-datatable td {
| |
| vertical-align: middle;
| |
| }
| |
| .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: transparent;
| |
| box-sizing: border-box;
| |
| width: var( --edfm-sidebar-width );
| |
| padding: 0 0.65rem 1.35rem 0.65rem;
| |
| border-right: 0;
| |
| box-shadow: none;
| |
| z-index: 3;
| |
| }
| |
| /* Logo anchors the sidebar visually. Do not draw a divider on or near
| |
| #p-logo: Vector legacy fixes the logo box at 155px high and the EDFM hex
| |
| mark reaches that edge, so any horizontal rule in this box cuts through
| |
| the lower point of the logo. Navigation spacing below provides the break. */
| |
| #p-logo {
| |
| box-sizing: border-box;
| |
| width: auto;
| |
| margin: 0 -0.65rem 1.25rem -0.65rem;
| |
| padding: 0.95rem 0.55rem 1.05rem 0.55rem;
| |
| border-bottom: 0 !important;
| |
| background: radial-gradient( circle at 50% 25%, rgba( 255, 138, 0, 0.08 ), transparent 58% );
| |
| }
| |
| /* Each nav group gets real breathing room from the one before it instead
| |
| of being packed together like a stock wiki sidebar. */
| |
|
| |
| /* Sidebar Discord invite CTA: injected by MediaWiki:Common.js directly below
| |
| the logo and above the first generated Vector portlet, matching the compact
| |
| community-button placement shown in the reference screenshot. */
| |
| .edfm-discord-cta {
| |
| display: inline-flex;
| |
| align-items: center;
| |
| justify-content: center;
| |
| gap: 0.42rem;
| |
| box-sizing: border-box;
| |
| width: calc( 100% - 1.35rem );
| |
| min-height: 1.78rem;
| |
| margin: 0.35rem 0.675rem 1.05rem 0.675rem;
| |
| padding: 0.36rem 0.56rem;
| |
| border-radius: 4px;
| |
| background: #5865f2;
| |
| color: #fff !important;
| |
| font-size: 0.76rem;
| |
| font-weight: 700;
| |
| line-height: 1.1;
| |
| text-align: center;
| |
| text-decoration: none !important;
| |
| box-shadow: 0 2px 5px rgba( 0, 0, 0, 0.35 );
| |
| transition: background-color 120ms ease, box-shadow 120ms ease, transform 120ms ease;
| |
| }
| |
| .edfm-discord-cta:hover,
| |
| .edfm-discord-cta:focus {
| |
| background: #4752c4;
| |
| color: #fff !important;
| |
| text-decoration: none !important;
| |
| box-shadow: 0 3px 8px rgba( 0, 0, 0, 0.42 );
| |
| transform: translateY( -1px );
| |
| }
| |
| .edfm-discord-cta-icon {
| |
| display: inline-flex;
| |
| width: 1rem;
| |
| height: 1rem;
| |
| flex: 0 0 auto;
| |
| }
| |
| .edfm-discord-cta-icon svg {
| |
| display: block;
| |
| width: 100%;
| |
| height: 100%;
| |
| fill: currentColor;
| |
| }
| |
|
| |
| #mw-panel .portal,
| |
| #mw-panel .vector-menu-portal {
| |
| box-sizing: border-box;
| |
| width: auto;
| |
| max-width: none;
| |
| margin-top: 1.45rem;
| |
| }
| |
| #mw-panel .portal:first-of-type,
| |
| #mw-panel .vector-menu-portal:first-of-type {
| |
| margin-top: 0;
| |
| }
| |
| #mw-panel .portal .body,
| |
| #mw-panel .portal ul,
| |
| #mw-panel .vector-menu-content,
| |
| #mw-panel .vector-menu-content-list {
| |
| box-sizing: border-box;
| |
| width: auto;
| |
| max-width: none;
| |
| margin-left: 0;
| |
| margin-right: 0;
| |
| padding-left: 0;
| |
| border-color: var( --edfm-border-soft );
| |
| }
| |
| #mw-panel .portal a {
| |
| color: var( --edfm-text-muted );
| |
| display: block;
| |
| font-size: var( --edfm-fs-sidebar );
| |
| line-height: 1.35;
| |
| padding: 0.42em 0.55em;
| |
| margin: 0.08em -0.35em;
| |
| border-left: 2px solid transparent;
| |
| border-radius: 2px;
| |
| }
| |
| #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-2 );
| |
| box-shadow: inset 0 0 0 1px rgba( 255, 138, 0, 0.08 );
| |
| }
| |
| .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 );
| |
| /* Polish pass: thinned from 2px -- at 2px this competed visually with
| |
| the masthead's own orange marker/rule directly below it; a single
| |
| thinner accent line still reads as "site identity colour" without
| |
| the repetition. */
| |
| border-bottom: 1px 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 ) );
| |
| display: flex;
| |
| align-items: center;
| |
| gap: 0.75rem;
| |
| }
| |
| #p-personal ul {
| |
| display: flex;
| |
| align-items: center;
| |
| gap: 0.55rem;
| |
| }
| |
| #p-personal li {
| |
| margin-left: 0;
| |
| }
| |
| #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 );
| |
| }
| |
| .edfm-topbar-clocks {
| |
| display: inline-flex;
| |
| align-items: center;
| |
| gap: 0.5rem;
| |
| font-family: var( --edfm-mono );
| |
| font-size: var( --edfm-fs-sidebar );
| |
| line-height: 1;
| |
| white-space: nowrap;
| |
| }
| |
| .edfm-topbar-clock {
| |
| display: inline-flex;
| |
| align-items: center;
| |
| gap: 0.3em;
| |
| padding: 0.3em 0.55em;
| |
| background: rgba( 66, 199, 217, 0.08 );
| |
| border: 1px solid var( --edfm-border-soft );
| |
| border-left: 2px solid var( --edfm-cyan );
| |
| color: var( --edfm-text );
| |
| }
| |
| .edfm-topbar-clock-label {
| |
| color: var( --edfm-text-dim );
| |
| font-size: var( --edfm-fs-utility );
| |
| letter-spacing: 0.08em;
| |
| text-transform: uppercase;
| |
| }
| |
| .edfm-topbar-clock time {
| |
| color: var( --edfm-cyan );
| |
| font-weight: 700;
| |
| }
| |
| .edfm-topbar-clock-local {
| |
| background: rgba( 255, 138, 0, 0.06 );
| |
| border-left-color: var( --edfm-orange );
| |
| }
| |
| .edfm-topbar-clock-local time {
| |
| color: var( --edfm-orange-bright );
| |
| }
| |
| #right-navigation {
| |
| margin-right: var( --edfm-gutter );
| |
| }
| |
| #left-navigation {
| |
| margin-left: var( --edfm-sidebar-clear );
| |
| }
| |
| /* Polish pass: core caps this at `width:20vw; max-width:20em`, which read
| |
| as cramped next to the rest of the (now larger-scale) interface --
| |
| given more room on desktop, still capped so it can't dominate the bar. */
| |
| .vector-search-box-inner {
| |
| width: 22vw;
| |
| max-width: 24em;
| |
| }
| |
| .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.5em 0.7em;
| |
| transition: border-color 0.15s ease, box-shadow 0.15s ease;
| |
| }
| |
| #searchInput:focus {
| |
| border-color: var( --edfm-cyan );
| |
| box-shadow: 0 0 0 2px rgba( 66, 199, 217, 0.22 );
| |
| outline: none;
| |
| }
| |
| #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 );
| |
| /* Polish pass: a small underline makes the selected tab unambiguous at
| |
| a glance instead of relying on the text colour change alone. */
| |
| box-shadow: inset 0 -2px 0 var( --edfm-orange );
| |
| }
| |
| .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 );
| |
| }
| |
| .mw-body {
| |
| border-right: 1px solid var( --edfm-border );
| |
| }
| |
| #content {
| |
| background-color: var( --edfm-surface-1 );
| |
| }
| |
|
| |
| /* Site notice chrome. The global disclaimer was moved to its dedicated
| |
| legal/disclaimer page, so an empty #siteNotice must not leave behind a
| |
| phantom divider at the top of the article surface. */
| |
| #siteNotice:empty {
| |
| display: none;
| |
| }
| |
| #siteNotice:not( :empty ) {
| |
| font-size: var( --edfm-fs-meta );
| |
| line-height: 1.5;
| |
| color: var( --edfm-text-dim );
| |
| font-style: normal;
| |
| padding-bottom: 0.7em;
| |
| margin-bottom: 1.4rem;
| |
| border-bottom: 1px solid var( --edfm-border-soft );
| |
| }
| |
| #siteNotice:not( :empty ) em, #siteNotice:not( :empty ) i {
| |
| color: var( --edfm-text-muted );
| |
| font-style: italic;
| |
| }
| |
| #siteNotice:not( :empty ) a {
| |
| color: var( --edfm-link-external );
| |
| }
| |
| #siteNotice a:hover {
| |
| color: var( --edfm-link-external-hover );
| |
| }
| |
|
| |
| /* ==========================================================================
| |
| HOME PAGE DASHBOARD
| |
| ========================================================================== */
| |
| .edfm-home-hero {
| |
| margin: 0.9rem 0 1.6rem;
| |
| padding: 1.35rem 1.55rem;
| |
| background:
| |
| linear-gradient( 135deg, rgba( 255, 138, 0, 0.16 ), transparent 34% ),
| |
| linear-gradient( 315deg, rgba( 66, 199, 217, 0.14 ), transparent 42% ),
| |
| var( --edfm-surface-2 );
| |
| border: 1px solid var( --edfm-border );
| |
| border-left: 4px solid var( --edfm-cyan );
| |
| clip-path: polygon( 0 0, calc( 100% - 12px ) 0, 100% 12px, 100% 100%, 0 100% );
| |
| }
| |
| .edfm-home-hero-kicker,
| |
| .edfm-home-card-kicker {
| |
| color: var( --edfm-text-dim );
| |
| font-family: var( --edfm-mono );
| |
| font-size: var( --edfm-fs-meta );
| |
| font-weight: 800;
| |
| letter-spacing: 0.1em;
| |
| text-transform: uppercase;
| |
| }
| |
| .edfm-home-hero-title {
| |
| margin-top: 0.25rem;
| |
| color: var( --edfm-text );
| |
| font-family: var( --edfm-mono );
| |
| font-size: clamp( 1.55rem, 1.1rem + 1.5vw, 2.2rem );
| |
| font-weight: 800;
| |
| line-height: 1.15;
| |
| }
| |
| .edfm-home-hero-text {
| |
| max-width: 52rem;
| |
| margin-top: 0.55rem;
| |
| color: var( --edfm-text-muted );
| |
| font-size: 1.05rem;
| |
| line-height: 1.55;
| |
| }
| |
| .edfm-home-grid {
| |
| display: grid;
| |
| gap: 1rem;
| |
| margin: 1.2rem 0 2rem;
| |
| }
| |
| .edfm-home-grid-four {
| |
| grid-template-columns: repeat( 4, minmax( 0, 1fr ) );
| |
| }
| |
| .edfm-home-grid-topics {
| |
| grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
| |
| }
| |
| .edfm-home-grid-two {
| |
| grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
| |
| }
| |
| .edfm-home-card {
| |
| background: var( --edfm-surface-2 );
| |
| border: 1px solid var( --edfm-border );
| |
| border-left: 3px solid var( --edfm-cyan );
| |
| padding: 1rem 1.1rem;
| |
| box-shadow: 0 12px 24px rgba( 0, 0, 0, 0.2 );
| |
| transition: transform 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
| |
| }
| |
| .edfm-home-card:hover {
| |
| transform: translateY( -2px );
| |
| background: var( --edfm-surface-3 );
| |
| border-left-color: var( --edfm-orange );
| |
| }
| |
| .edfm-home-card-primary {
| |
| border-left-color: var( --edfm-orange );
| |
| }
| |
| .edfm-home-card-warning {
| |
| border-left-color: var( --edfm-text-dim );
| |
| }
| |
| .edfm-home-card-title,
| |
| .edfm-home-card-title a {
| |
| margin-top: 0.35rem;
| |
| color: var( --edfm-text ) !important;
| |
| font-family: var( --edfm-mono );
| |
| font-size: 1.05rem;
| |
| font-weight: 800;
| |
| line-height: 1.3;
| |
| text-decoration: none;
| |
| }
| |
| .edfm-home-card-title a:hover {
| |
| color: var( --edfm-orange-bright ) !important;
| |
| }
| |
| .edfm-home-card-text,
| |
| .edfm-home-link-list {
| |
| margin-top: 0.65rem;
| |
| color: var( --edfm-text-muted );
| |
| line-height: 1.6;
| |
| }
| |
| .edfm-home-link-list a {
| |
| font-weight: 600;
| |
| }
| |
| @media ( max-width: 1100px ) {
| |
| .edfm-home-grid-four {
| |
| grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
| |
| }
| |
| }
| |
| @media ( max-width: 760px ) {
| |
| .edfm-home-grid-four,
| |
| .edfm-home-grid-topics,
| |
| .edfm-home-grid-two {
| |
| grid-template-columns: 1fr;
| |
| }
| |
| }
| |
|
| |
| /* ==========================================================================
| |
| HOME PAGE NEWS MODULE
| |
| ========================================================================== */
| |
| .edfm-home-news {
| |
| margin: 1.8rem 0 2.2rem;
| |
| }
| |
| .edfm-news-feature-grid {
| |
| display: grid;
| |
| grid-template-columns: repeat( 3, minmax( 0, 1fr ) );
| |
| gap: 1rem;
| |
| margin-bottom: 1rem;
| |
| }
| |
| .edfm-news-card,
| |
| .edfm-news-list {
| |
| background: var( --edfm-surface-2 );
| |
| border: 1px solid var( --edfm-border );
| |
| box-shadow: 0 14px 26px rgba( 0, 0, 0, 0.22 );
| |
| overflow: hidden;
| |
| }
| |
| .edfm-news-card {
| |
| display: flex;
| |
| flex-direction: column;
| |
| min-height: 100%;
| |
| transition: transform 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
| |
| }
| |
| .edfm-news-card:hover {
| |
| transform: translateY( -2px );
| |
| border-color: rgba( 255, 138, 0, 0.48 );
| |
| background: var( --edfm-surface-3 );
| |
| }
| |
| .edfm-news-card-art {
| |
| display: flex;
| |
| align-items: flex-end;
| |
| min-height: 7rem;
| |
| padding: 0.8rem 1rem;
| |
| box-sizing: border-box;
| |
| background:
| |
| linear-gradient( 135deg, rgba( 255, 138, 0, 0.28 ), transparent 42% ),
| |
| linear-gradient( 315deg, rgba( 66, 199, 217, 0.2 ), transparent 48% ),
| |
| linear-gradient( 180deg, var( --edfm-surface-4 ), var( --edfm-surface-1 ) );
| |
| border-bottom: 1px solid var( --edfm-border );
| |
| color: rgba( 237, 240, 242, 0.72 );
| |
| font-family: var( --edfm-mono );
| |
| font-size: 0.8rem;
| |
| font-weight: 800;
| |
| letter-spacing: 0.16em;
| |
| text-transform: uppercase;
| |
| }
| |
| .edfm-news-card-primary .edfm-news-card-art {
| |
| background:
| |
| linear-gradient( 135deg, rgba( 255, 138, 0, 0.38 ), transparent 46% ),
| |
| linear-gradient( 315deg, rgba( 79, 159, 232, 0.26 ), transparent 52% ),
| |
| var( --edfm-surface-4 );
| |
| }
| |
| .edfm-news-card-body {
| |
| padding: 1rem 1.15rem 1.15rem;
| |
| }
| |
| .edfm-news-meta {
| |
| color: var( --edfm-text-dim );
| |
| font-family: var( --edfm-mono );
| |
| font-size: var( --edfm-fs-meta );
| |
| letter-spacing: 0.04em;
| |
| text-transform: uppercase;
| |
| margin-bottom: 0.35rem;
| |
| }
| |
| .edfm-news-title,
| |
| .edfm-news-title a {
| |
| color: var( --edfm-text ) !important;
| |
| font-family: var( --edfm-mono );
| |
| font-size: 1.1rem;
| |
| font-weight: 800;
| |
| line-height: 1.25;
| |
| text-decoration: none;
| |
| }
| |
| .edfm-news-title a:hover {
| |
| color: var( --edfm-orange-bright ) !important;
| |
| }
| |
| .edfm-news-summary {
| |
| color: var( --edfm-text-muted );
| |
| line-height: 1.55;
| |
| margin-top: 0.65rem;
| |
| }
| |
| .edfm-news-list {
| |
| padding: 1.1rem 1.25rem 1.2rem;
| |
| border-left: 4px solid var( --edfm-orange );
| |
| }
| |
| .edfm-news-list-heading {
| |
| color: var( --edfm-text );
| |
| font-family: var( --edfm-mono );
| |
| font-size: 1.05rem;
| |
| font-weight: 800;
| |
| letter-spacing: 0.04em;
| |
| text-transform: uppercase;
| |
| margin-bottom: 0.75rem;
| |
| }
| |
| .edfm-news-list ul {
| |
| margin: 0;
| |
| }
| |
| .edfm-news-list li {
| |
| margin-bottom: 0.55rem;
| |
| color: var( --edfm-text-muted );
| |
| }
| |
| .edfm-news-more {
| |
| margin-top: 0.9rem;
| |
| padding-top: 0.85rem;
| |
| border-top: 1px solid var( --edfm-border-soft );
| |
| text-align: right;
| |
| font-family: var( --edfm-mono );
| |
| font-weight: 800;
| |
| letter-spacing: 0.03em;
| |
| text-transform: uppercase;
| |
| }
| |
| @media ( max-width: 900px ) {
| |
| .edfm-news-feature-grid {
| |
| grid-template-columns: 1fr;
| |
| }
| |
| }
| |
|
| |
| /* ==========================================================================
| |
| 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 {
| |
| display: block;
| |
| width: 100%;
| |
| box-sizing: border-box;
| |
| 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( 4, 1fr );
| |
| gap: 0.45rem;
| |
| list-style: none;
| |
| margin: 0;
| |
| padding: 0;
| |
| }
| |
| .toc li {
| |
| margin: 0;
| |
| }
| |
| /* 2026-08-08 density pass: reverted to side-by-side number/label (from the
| |
| earlier "stacked number-above-label" polish pass) specifically to cut
| |
| per-tile height -- with 12 sections on articles like The Dweller, the
| |
| stacked layout meant the jump nav alone filled most of the first
| |
| viewport. Row layout plus tighter padding/font-size gets noticeably
| |
| more sections above the fold without dropping the numbering or shrinking
| |
| tap targets below a comfortable size -- see the dedicated mobile padding
| |
| bump further down for keeping touch targets safe on small screens
| |
| specifically. Whole tile stays one real <a>, so it's still a single
| |
| click/focus target and keyboard tab stop either way. */
| |
| .toc a {
| |
| display: flex;
| |
| flex-direction: row;
| |
| align-items: center;
| |
| gap: 0.5em;
| |
| height: 100%;
| |
| box-sizing: border-box;
| |
| padding: 0.5em 0.75em 0.5em 0.7em;
| |
| background: var( --edfm-surface-3 );
| |
| /* Left accent rail: matches the orange section numbers and gives each
| |
| jump tile a stronger EDFM navigation affordance without boxing the
| |
| entire card. */
| |
| border-left: 4px solid var( --edfm-orange );
| |
| box-shadow: inset 1px 0 0 rgba( 255, 162, 26, 0.35 );
| |
| color: var( --edfm-text-muted );
| |
| text-decoration: none;
| |
| transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 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 );
| |
| box-shadow: inset 1px 0 0 rgba( 66, 199, 217, 0.45 );
| |
| 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 {
| |
| flex-direction: row;
| |
| align-items: center;
| |
| background: none;
| |
| border-left-width: 1px;
| |
| padding: 0.3em 0.6em;
| |
| }
| |
| .toc ul ul .tocnumber {
| |
| font-size: 0.85em;
| |
| }
| |
| .toc ul ul .toctext {
| |
| font-size: 0.85em;
| |
| }
| |
| .tocnumber {
| |
| color: var( --edfm-orange );
| |
| font-family: var( --edfm-mono );
| |
| font-weight: 700;
| |
| font-size: 1.05rem;
| |
| line-height: 1;
| |
| }
| |
| .toctext {
| |
| color: inherit;
| |
| font-size: 0.85rem;
| |
| line-height: 1.3;
| |
| }
| |
| /* 2026-08-08: rebalanced for the 4-column desktop default above -- was
| |
| >1150px = 3 cols -> <=1150px = 2 cols -> <=560px = 1 col. A page with
| |
| 12 sections (e.g. The Dweller) now gets 3 rows at desktop width instead
| |
| of 4, so a new <=860px step was added rather than dropping straight
| |
| from 3 to 2 columns at 1150px, which left the same "Star systems,
| |
| navigation and exploration"-style long labels cramped in the 1024px
| |
| range this breakpoint set was originally tuned for. Order stays widest
| |
| condition first, narrowest last, so cascade order matches the max-width
| |
| overlap correctly at every width. */
| |
| @media ( max-width: 1150px ) {
| |
| .toc > ul {
| |
| grid-template-columns: repeat( 3, 1fr );
| |
| }
| |
| }
| |
| @media ( max-width: 860px ) {
| |
| .toc > ul {
| |
| grid-template-columns: repeat( 2, 1fr );
| |
| }
| |
| }
| |
| @media ( max-width: 560px ) {
| |
| .toc > ul {
| |
| grid-template-columns: 1fr;
| |
| }
| |
| /* Single-column tiles are already full-width here, so there's no
| |
| density pressure left -- restore closer to the pre-2026-08-08
| |
| padding instead of the tighter desktop value, keeping tap targets
| |
| comfortable rather than compacting mobile just because desktop
| |
| compacted. */
| |
| .toc a {
| |
| padding: 0.7em 0.95em;
| |
| }
| |
| }
| |
|
| |
| /* ==========================================================================
| |
| 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: var( --edfm-sidebar-clear );
| |
| 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: 'EDFM // Elite Dangerous Field Manual';
| |
| font-family: var( --edfm-mono );
| |
| font-size: 0.85rem;
| |
| font-weight: 700;
| |
| letter-spacing: 0.06em;
| |
| text-transform: uppercase;
| |
| color: var( --edfm-text-muted );
| |
| margin-bottom: 0.5rem;
| |
| }
| |
| .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;
| |
| line-height: 1.6;
| |
| }
| |
| #footer-places {
| |
| grid-area: places;
| |
| margin: 0;
| |
| }
| |
| /* Same "small uppercase label" treatment used for tags/meta text
| |
| elsewhere, so these read as deliberate EDFM navigation rather than
| |
| default MediaWiki footer links. */
| |
| #footer-places li {
| |
| display: inline-block;
| |
| margin-right: 1.4em;
| |
| }
| |
| #footer-places a {
| |
| font-family: var( --edfm-mono );
| |
| font-weight: 700;
| |
| letter-spacing: 0.03em;
| |
| text-transform: uppercase;
| |
| font-size: 0.78rem;
| |
| }
| |
| /* A left rule ties the badges to the rest of the footer instead of
| |
| letting them read as detached/floating in their own space. */
| |
| #footer-icons {
| |
| grid-area: icons;
| |
| align-self: center;
| |
| display: flex;
| |
| gap: 0.75em;
| |
| margin: 0;
| |
| padding-left: 1.6em;
| |
| border-left: 1px solid var( --edfm-border-soft );
| |
| }
| |
| #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.7em;
| |
| padding-left: 0;
| |
| border-left: none;
| |
| border-top: 1px solid var( --edfm-border-soft );
| |
| padding-top: 0.7em;
| |
| }
| |
| }
| |
|
| |
| /* ==========================================================================
| |
| 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-image-placeholder {
| |
| display: flex;
| |
| align-items: center;
| |
| justify-content: center;
| |
| height: 160px;
| |
| border: 1px dashed var( --edfm-border );
| |
| background: var( --edfm-surface-1 );
| |
| color: var( --edfm-text-dim );
| |
| font-family: var( --edfm-mono );
| |
| font-size: var( --edfm-fs-utility );
| |
| text-transform: uppercase;
| |
| letter-spacing: 0.06em;
| |
| text-align: center;
| |
| padding: 0.5em;
| |
| }
| |
| /* Optional section label (Template:Infobox's |groupN=) splitting a long
| |
| infobox into scannable groups, e.g. Engineer infoboxes into "ENGINEER"
| |
| and "ACCESS" (2026-08-08, part of the Engineer article layout pass). A
| |
| shaded band with a bottom rule rather than a full boxed sub-header --
| |
| consistent with .edfm-infobox-row's own bottom-rule-only separator, not
| |
| a new visual language. */
| |
| .edfm-infobox-group {
| |
| background: var( --edfm-surface-3 );
| |
| color: var( --edfm-text-dim );
| |
| font-family: var( --edfm-mono );
| |
| font-weight: 700;
| |
| font-size: var( --edfm-fs-utility );
| |
| letter-spacing: 0.08em;
| |
| text-transform: uppercase;
| |
| padding: 0.35em 0.7em;
| |
| 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::before {
| |
| display: none;
| |
| }
| |
| 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;
| |
| background: var( --edfm-bg-deep );
| |
| 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 column count is NOT overridden here -- the dedicated
| |
| 1150px/560px breakpoints above already cover every width down to
| |
| the smallest phones; duplicating a rule here previously fought
| |
| those (same specificity, this position in the cascade would have
| |
| won and wrongly forced 1 column as low as 561px). */
| |
| #firstHeading {
| |
| font-size: 1.6rem;
| |
| }
| |
| .mw-body h2 {
| |
| margin-top: 2.25rem;
| |
| }
| |
| .edfm-eyebrow {
| |
| padding-top: 0.9em;
| |
| }
| |
| }
| |
| /* ==========================================================================
| |
| 16. OOUI DIALOGS -- VisualEditor's save dialog, and any other OOUI
| |
| dialog (delete/move/protect confirmations, special-page dialogs).
| |
| These render via OOUI's own bundled WikimediaUI theme stylesheet,
| |
| entirely outside the .edfm-* component system this file otherwise
| |
| covers, so without this they show up starkly white against the rest of
| |
| the dark-themed site regardless of any variable/token used elsewhere in
| |
| this file. !important is justified the same way as the h1-h6 fix above:
| |
| OOUI's own stylesheet loads with equal-or-higher effective specificity,
| |
| and this is a correctness/contrast fix, not decoration.
| |
| ========================================================================== */
| |
| .oo-ui-window-frame {
| |
| background: var( --edfm-surface-2 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| }
| |
| .oo-ui-processDialog {
| |
| background: rgba( 7, 9, 11, 0.75 ) !important;
| |
| }
| |
| .oo-ui-processDialog-navigation,
| |
| .oo-ui-window-head,
| |
| .oo-ui-window-foot {
| |
| background: var( --edfm-surface-3 ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| .oo-ui-processDialog-title,
| |
| .oo-ui-labelElement-label,
| |
| .oo-ui-fieldLayout-header,
| |
| .oo-ui-fieldLayout .oo-ui-labelElement-label {
| |
| color: var( --edfm-text ) !important;
| |
| }
| |
| .oo-ui-inputWidget-input {
| |
| background: var( --edfm-surface-1 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| .ve-ui-mwSaveDialog-options,
| |
| .oo-ui-panelLayout,
| |
| .oo-ui-window-body {
| |
| background: var( --edfm-surface-2 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| }
| |
| .oo-ui-popupWidget-popup {
| |
| background: var( --edfm-surface-2 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| .oo-ui-buttonElement:not( .oo-ui-flaggedElement-primary ) > .oo-ui-buttonElement-button {
| |
| background: var( --edfm-surface-4 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| /* ==========================================================================
| |
| 17. OOUI TOOLBAR -- VisualEditor's persistent editing toolbar and its
| |
| dropdown menus (Cite, Insert, paragraph style, etc.), and the equivalent
| |
| toolbar/popups used when editing a single section. Same root cause as
| |
| 16. OOUI DIALOGS above (OOUI's own bundled theme, not touched by
| |
| anything else in this file), found separately because it's a different
| |
| set of OOUI classes (toolbar chrome, not dialog chrome). Icons are not
| |
| overridden here and don't need to be -- they're currentColor-based, so
| |
| they pick up the text colour set below automatically.
| |
| ========================================================================== */
| |
| .oo-ui-toolbar-bar,
| |
| .oo-ui-toolGroup-tools,
| |
| .oo-ui-popupToolGroup-tools {
| |
| background: var( --edfm-surface-3 ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| .oo-ui-tool-title,
| |
| .oo-ui-tool-link,
| |
| .oo-ui-toolGroup-tools .oo-ui-optionWidget,
| |
| .oo-ui-menuOptionWidget,
| |
| .oo-ui-labelElement-label {
| |
| color: var( --edfm-text ) !important;
| |
| }
| |
| .oo-ui-optionWidget.oo-ui-optionWidget-selected,
| |
| .oo-ui-optionWidget:hover,
| |
| .oo-ui-tool:hover .oo-ui-tool-link {
| |
| background: var( --edfm-surface-4 ) !important;
| |
| }
| |
| /* ==========================================================================
| |
| 18. OOUI GENERIC MENUS -- .oo-ui-menuSelectWidget is OOUI's general
| |
| dropdown/autocomplete menu class (paragraph-style picker, citation-type
| |
| picker, link/media search suggestions, etc.) -- a different class from
| |
| the toolbar-specific popups in 17. above, confirmed separately via
| |
| computed-style inspection to default to the same white OOUI theme
| |
| background.
| |
| ========================================================================== */
| |
| .oo-ui-menuSelectWidget {
| |
| background: var( --edfm-surface-3 ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| .oo-ui-menuOptionWidget {
| |
| color: var( --edfm-text ) !important;
| |
| }
| |
| .oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted,
| |
| .oo-ui-menuOptionWidget:hover {
| |
| background: var( --edfm-surface-4 ) !important;
| |
| }
| |
| /* ==========================================================================
| |
| 19. OOUI ICONS -- the toolbar/menu icons themselves (Bold, link, list,
| |
| Cite, undo/redo, etc.) are rendered as background-image SVGs with a
| |
| colour baked into the SVG markup, not currentColor-based masks -- so
| |
| 16-18 above (which only recolour backgrounds/text) left them dark and
| |
| low-contrast against the now-dark surfaces. OOUI ships its own fix for
| |
| exactly this, gated behind a narrow accessibility media query
| |
| (forced-colors + prefers-color-scheme: dark) that doesn't apply to this
| |
| site's own always-on dark theme -- reusing that exact technique
| |
| unconditionally rather than inventing a different one. `:not(
| |
| .oo-ui-image-invert )` is OOUI's own exclusion for icons already meant
| |
| to render light (e.g. on the orange primary-button background) --
| |
| inverting those too would flip them back to dark.
| |
| ========================================================================== */
| |
| .oo-ui-iconElement-icon:not( .oo-ui-image-invert ),
| |
| .oo-ui-indicatorElement-indicator:not( .oo-ui-image-invert ) {
| |
| filter: invert( 1 ) hue-rotate( 180deg );
| |
| }
| |
| /* ==========================================================================
| |
| 20. EDIT SOURCE FORM -- MediaWiki core + WikiEditor + CodeMirror
| |
|
| |
| The source editor is not covered by the article/component selectors above:
| |
| `action=edit` loads core edit-form CSS, WikiEditor chrome, and sometimes
| |
| CodeMirror with their own light neutral surfaces. Force the same EDFM dark
| |
| surface stack here so the source page no longer flashes as a white island.
| |
| ========================================================================== */
| |
| .mw-editform,
| |
| #editform,
| |
| #toolbar,
| |
| .editOptions,
| |
| .mw-editTools,
| |
| .mw-summary-preview,
| |
| .mw-datatable,
| |
| .wikiEditor-ui,
| |
| .wikiEditor-ui-view,
| |
| .wikiEditor-ui-text,
| |
| .wikiEditor-ui-toolbar,
| |
| .wikiEditor-ui-top,
| |
| .wikiEditor-ui-controls,
| |
| .wikiEditor-ui-tabs,
| |
| .wikiEditor-ui-buttons,
| |
| .CodeMirror,
| |
| .CodeMirror-scroll {
| |
| background: var( --edfm-surface-1 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| .mw-editform textarea,
| |
| #wpTextbox1,
| |
| #wpSummary,
| |
| #wpSummaryWidget input,
| |
| #editform input[type='text'],
| |
| #editform input[type='search'],
| |
| #editform textarea,
| |
| .wikiEditor-ui-text textarea,
| |
| .CodeMirror-code,
| |
| .CodeMirror-lines,
| |
| .CodeMirror pre {
| |
| background: var( --edfm-bg-deep ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| caret-color: var( --edfm-orange-bright );
| |
| }
| |
| .wikiEditor-ui-toolbar,
| |
| .wikiEditor-ui-toolbar .group,
| |
| .wikiEditor-ui-toolbar .tabs,
| |
| .wikiEditor-ui-toolbar .page,
| |
| .wikiEditor-ui-toolbar .sections,
| |
| .wikiEditor-ui-toolbar .section,
| |
| .wikiEditor-ui-toolbar .options,
| |
| .wikiEditor-ui-toolbar .booklet,
| |
| .wikiEditor-ui-toolbar .pages,
| |
| .CodeMirror-gutters {
| |
| background: var( --edfm-surface-2 ) !important;
| |
| color: var( --edfm-text-muted ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| .wikiEditor-ui-toolbar a,
| |
| .wikiEditor-ui-toolbar .label,
| |
| .wikiEditor-ui-toolbar .tab a,
| |
| .mw-editTools a,
| |
| .editOptions label,
| |
| .mw-editform label,
| |
| .CodeMirror-linenumber {
| |
| color: var( --edfm-text ) !important;
| |
| }
| |
| .wikiEditor-ui-toolbar .tab a:hover,
| |
| .wikiEditor-ui-toolbar .tool-button:hover,
| |
| .wikiEditor-ui-toolbar .tool-select:hover,
| |
| .wikiEditor-ui-toolbar .page-table th,
| |
| .wikiEditor-ui-toolbar .page-table td,
| |
| .CodeMirror-activeline-background {
| |
| background: var( --edfm-surface-3 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| }
| |
| .wikiEditor-ui-toolbar .tab.current a,
| |
| .wikiEditor-ui-toolbar .section-main,
| |
| .CodeMirror-selected {
| |
| background: var( --edfm-surface-4 ) !important;
| |
| }
| |
| .CodeMirror-cursor {
| |
| border-left-color: var( --edfm-orange-bright ) !important;
| |
| }
| |
| .CodeMirror-matchingbracket {
| |
| color: var( --edfm-orange-bright ) !important;
| |
| }
| |
|
| |
| /* ==========================================================================
| |
| 21. FILE PAGE CHROME -- #filetoc (the File / File history / File usage /
| |
| Metadata nav on File: description pages) is defined in MediaWiki core's
| |
| mediawiki.action.view.filepage.less, entirely separate from both the
| |
| .edfm-* system and the OOUI fixes in 16-19 above -- a different
| |
| subsystem again, only loaded on File: pages, which is why it was never
| |
| touched by anything else in this file. Link colour inside it already
| |
| correctly inherits the site's normal link blue; only the light neutral
| |
| background/border needed overriding.
| |
| ========================================================================== */
| |
| #filetoc {
| |
| background: var( --edfm-surface-2 ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| /* ==========================================================================
| |
| 22. FILE PAGE: METADATA TABLE + MEDIA VIEWER BUTTON -- #mw_metadata is
| |
| the EXIF-style metadata table (separate from the File history table
| |
| above -- that one already carries the .wikitable class and picked up
| |
| dark styling from 7. TABLES automatically; this one doesn't have that
| |
| class, so it never matched). The "Open in Media Viewer" button is a
| |
| Codex component (MultimediaViewer extension) -- a third distinct
| |
| styling subsystem from OOUI and MediaWiki core skinning, again never
| |
| touched by anything else in this file.
| |
| ========================================================================== */
| |
| #mw_metadata th,
| |
| #mw_metadata td {
| |
| background: var( --edfm-surface-2 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
| .mw-mmv-view-expanded.cdx-button {
| |
| background: var( --edfm-surface-4 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
|
| |
| /* ===========================================================================
| |
| 23. RUNE-WIKI-INSPIRED MOBILE APP SHELL
| |
| =========================================================================== */
| |
| /* Inspired by RuneScape.wiki's mobile ergonomics -- persistent top app bar,
| |
| large touch targets, off-canvas navigation, search-forward layout, and
| |
| single-column readable article flow -- while preserving EDFM's dark field
| |
| manual identity and not copying RuneScape.wiki assets/CSS.
| |
| The close button is injected into #mw-panel by Common.js, so it must be
| |
| explicitly hidden by default; otherwise a tiny native white button appears
| |
| in the desktop sidebar's top-left corner. */
| |
| .edfm-mobile-appbar,
| |
| .edfm-mobile-scrim,
| |
| .edfm-mobile-close-button {
| |
| display: none;
| |
| }
| |
| @media ( max-width: 800px ) {
| |
| html {
| |
| -webkit-text-size-adjust: 100%;
| |
| }
| |
| body {
| |
| background: var( --edfm-bg-page );
| |
| overflow-x: hidden;
| |
| }
| |
| body.edfm-mobile-menu-open {
| |
| overflow: hidden;
| |
| }
| |
| .edfm-mobile-appbar {
| |
| display: grid;
| |
| grid-template-columns: 48px 1fr 48px;
| |
| align-items: center;
| |
| position: sticky;
| |
| top: 0;
| |
| z-index: 1200;
| |
| min-height: 56px;
| |
| padding: 0 0.35rem;
| |
| background:
| |
| linear-gradient( 90deg, rgba( 255, 138, 0, 0.18 ), transparent 38% ),
| |
| var( --edfm-surface-2 );
| |
| border-bottom: 1px solid var( --edfm-border );
| |
| box-shadow: 0 10px 24px rgba( 0, 0, 0, 0.35 );
| |
| }
| |
| .edfm-mobile-brand {
| |
| min-width: 0;
| |
| color: var( --edfm-text ) !important;
| |
| font-family: var( --edfm-mono );
| |
| font-weight: 800;
| |
| letter-spacing: 0.05em;
| |
| text-transform: uppercase;
| |
| text-decoration: none;
| |
| white-space: nowrap;
| |
| overflow: hidden;
| |
| text-overflow: ellipsis;
| |
| }
| |
| .edfm-mobile-brand::before {
| |
| content: 'EDFM // ';
| |
| color: var( --edfm-orange );
| |
| }
| |
| .edfm-mobile-menu-button,
| |
| .edfm-mobile-search-button,
| |
| .edfm-mobile-close-button {
| |
| appearance: none;
| |
| -webkit-appearance: none;
| |
| display: inline-flex;
| |
| align-items: center;
| |
| justify-content: center;
| |
| min-width: 44px;
| |
| min-height: 44px;
| |
| margin: 0;
| |
| border: 0;
| |
| border-radius: 0;
| |
| background: transparent;
| |
| color: var( --edfm-text );
| |
| font: 700 1.5rem/1 var( --edfm-mono );
| |
| cursor: pointer;
| |
| }
| |
| .edfm-mobile-menu-button:focus-visible,
| |
| .edfm-mobile-search-button:focus-visible,
| |
| .edfm-mobile-close-button:focus-visible {
| |
| outline: 2px solid var( --edfm-cyan );
| |
| outline-offset: -4px;
| |
| }
| |
| .edfm-mobile-menu-button::before {
| |
| content: '☰';
| |
| color: var( --edfm-orange );
| |
| }
| |
| .edfm-mobile-search-button::before {
| |
| content: '⌕';
| |
| font-size: 1.85rem;
| |
| color: var( --edfm-cyan );
| |
| }
| |
| .edfm-mobile-close-button::before {
| |
| content: '×';
| |
| color: var( --edfm-text );
| |
| }
| |
| .edfm-mobile-scrim {
| |
| display: block;
| |
| position: fixed;
| |
| inset: 0;
| |
| z-index: 1000;
| |
| background: rgba( 0, 0, 0, 0.58 );
| |
| opacity: 0;
| |
| pointer-events: none;
| |
| transition: opacity 0.18s ease;
| |
| }
| |
| body.edfm-mobile-menu-open .edfm-mobile-scrim {
| |
| opacity: 1;
| |
| pointer-events: auto;
| |
| }
| |
| #mw-navigation {
| |
| background: var( --edfm-surface-2 );
| |
| box-shadow: none;
| |
| }
| |
| #mw-head {
| |
| position: relative;
| |
| z-index: 1100;
| |
| border-bottom: 1px solid var( --edfm-border );
| |
| }
| |
| #mw-head .vector-search-box {
| |
| display: none;
| |
| margin: 0;
| |
| padding: 0.65rem;
| |
| background: var( --edfm-surface-2 );
| |
| border-top: 1px solid var( --edfm-border-soft );
| |
| }
| |
| body.edfm-mobile-search-open #mw-head .vector-search-box {
| |
| display: block;
| |
| }
| |
| #mw-head .vector-search-box-inner,
| |
| #mw-head #searchform {
| |
| width: 100%;
| |
| }
| |
| #mw-head #searchInput {
| |
| min-height: 44px;
| |
| box-sizing: border-box;
| |
| width: 100%;
| |
| font-size: 1rem;
| |
| }
| |
| #left-navigation,
| |
| #right-navigation {
| |
| padding: 0 0.45rem 0.35rem;
| |
| background: var( --edfm-surface-2 );
| |
| overflow-x: auto;
| |
| white-space: nowrap;
| |
| -webkit-overflow-scrolling: touch;
| |
| }
| |
| .vector-menu-tabs-legacy ul {
| |
| flex-wrap: nowrap;
| |
| }
| |
| .vector-menu-tabs-legacy li a,
| |
| .vector-menu-tabs-legacy li a:visited,
| |
| .vector-menu-dropdown .vector-menu-heading {
| |
| min-height: 36px;
| |
| display: inline-flex;
| |
| align-items: center;
| |
| }
| |
| #p-personal {
| |
| display: none;
| |
| }
| |
| #mw-panel {
| |
| position: fixed;
| |
| top: 0;
| |
| left: 0;
| |
| z-index: 1300;
| |
| width: min( 82vw, 22rem );
| |
| height: 100dvh;
| |
| box-sizing: border-box;
| |
| padding: 0;
| |
| background: var( --edfm-surface-1 );
| |
| border: 0;
| |
| border-right: 1px solid var( --edfm-border );
| |
| box-shadow: 18px 0 36px rgba( 0, 0, 0, 0.45 );
| |
| overflow-y: auto;
| |
| -webkit-overflow-scrolling: touch;
| |
| transform: translateX( -105% );
| |
| transition: transform 0.2s ease;
| |
| }
| |
| body.edfm-mobile-menu-open #mw-panel {
| |
| transform: translateX( 0 );
| |
| }
| |
| #mw-panel::before {
| |
| content: 'EDFM Navigation';
| |
| display: block;
| |
| position: sticky;
| |
| top: 0;
| |
| z-index: 1;
| |
| padding: 1rem 3.4rem 1rem 1rem;
| |
| background: var( --edfm-surface-2 );
| |
| border-bottom: 1px solid var( --edfm-border );
| |
| color: var( --edfm-orange );
| |
| font: 800 0.86rem/1.2 var( --edfm-mono );
| |
| letter-spacing: 0.08em;
| |
| text-transform: uppercase;
| |
| }
| |
| #mw-panel .edfm-mobile-close-button {
| |
| position: absolute;
| |
| top: 0.3rem;
| |
| right: 0.35rem;
| |
| z-index: 2;
| |
| }
| |
| #mw-panel .portal,
| |
| #mw-panel .vector-menu-portal {
| |
| margin: 0;
| |
| padding: 0.75rem 0;
| |
| border-bottom: 1px solid var( --edfm-border-soft );
| |
| }
| |
| #mw-panel .vector-menu-heading {
| |
| margin: 0.25rem 1rem 0.45rem;
| |
| }
| |
| #mw-panel .vector-menu-content-list li a,
| |
| #mw-panel .vector-menu-content-list li a:visited {
| |
| display: flex;
| |
| align-items: center;
| |
| min-height: 46px;
| |
| box-sizing: border-box;
| |
| padding: 0.55rem 1rem;
| |
| border-left: 3px solid transparent;
| |
| color: var( --edfm-text-muted );
| |
| font-size: 1rem;
| |
| text-decoration: none;
| |
| }
| |
| #mw-panel .vector-menu-content-list li a:hover,
| |
| #mw-panel .vector-menu-content-list li a:focus {
| |
| background: var( --edfm-surface-3 );
| |
| border-left-color: var( --edfm-cyan );
| |
| color: var( --edfm-text );
| |
| }
| |
| #mw-panel .edfm-nav-current > a,
| |
| #mw-panel .edfm-nav-current > a:visited {
| |
| background: rgba( 255, 138, 0, 0.12 );
| |
| border-left-color: var( --edfm-orange );
| |
| color: var( --edfm-orange ) !important;
| |
| }
| |
| .mw-body {
| |
| padding: clamp( 1rem, 4vw, 1.35rem );
| |
| font-size: 1rem;
| |
| line-height: 1.68;
| |
| }
| |
| #siteNotice {
| |
| margin-bottom: 1rem;
| |
| padding-bottom: 0.85rem;
| |
| }
| |
| #firstHeading {
| |
| font-size: clamp( 1.65rem, 8vw, 2.25rem );
| |
| line-height: 1.1;
| |
| letter-spacing: -0.015em;
| |
| }
| |
| .mw-body h2 {
| |
| font-size: 1.18rem;
| |
| line-height: 1.25;
| |
| }
| |
| .mw-body p,
| |
| .mw-body li {
| |
| max-width: none;
| |
| }
| |
| .mw-body img,
| |
| .mw-body .thumb,
| |
| .mw-body .thumbinner,
| |
| .mw-body .thumbimage {
| |
| max-width: 100% !important;
| |
| height: auto !important;
| |
| box-sizing: border-box;
| |
| }
| |
| .mw-body .thumb,
| |
| .mw-body .tright,
| |
| .mw-body .tleft {
| |
| float: none !important;
| |
| clear: both;
| |
| width: auto !important;
| |
| margin: 1rem 0 !important;
| |
| }
| |
| .mw-parser-output > table.wikitable,
| |
| .mw-parser-output > table.mw-datatable {
| |
| display: block;
| |
| width: 100% !important;
| |
| max-width: 100%;
| |
| overflow-x: auto;
| |
| -webkit-overflow-scrolling: touch;
| |
| white-space: nowrap;
| |
| }
| |
| .mw-parser-output > table.wikitable th,
| |
| .mw-parser-output > table.wikitable td,
| |
| .mw-parser-output > table.mw-datatable th,
| |
| .mw-parser-output > table.mw-datatable td {
| |
| white-space: normal;
| |
| min-width: 8rem;
| |
| }
| |
| .edfm-infobox {
| |
| font-size: 0.95rem;
| |
| }
| |
| .edfm-infobox-row {
| |
| display: grid;
| |
| grid-template-columns: minmax( 7.5rem, 40% ) 1fr;
| |
| gap: 0.5rem;
| |
| padding: 0.65rem 0.8rem;
| |
| }
| |
| .edfm-infobox-label,
| |
| .edfm-infobox-value {
| |
| width: auto;
| |
| }
| |
| body.page-Main_Page .mw-parser-output > table.wikitable:first-of-type,
| |
| body.page-Main_Page .mw-parser-output > table.wikitable:first-of-type tbody,
| |
| body.page-Main_Page .mw-parser-output > table.wikitable:first-of-type tr,
| |
| body.page-Main_Page .mw-parser-output > table.wikitable:first-of-type th,
| |
| body.page-Main_Page .mw-parser-output > table.wikitable:first-of-type td {
| |
| display: block;
| |
| width: 100% !important;
| |
| box-sizing: border-box;
| |
| }
| |
| body.page-Main_Page .mw-parser-output > table.wikitable:first-of-type {
| |
| overflow: visible;
| |
| white-space: normal;
| |
| background: transparent;
| |
| border: 0;
| |
| }
| |
| body.page-Main_Page .mw-parser-output > table.wikitable:first-of-type th {
| |
| margin-top: 0.75rem;
| |
| border-left: 3px solid var( --edfm-orange );
| |
| }
| |
| body.page-Main_Page .mw-parser-output > table.wikitable:first-of-type td {
| |
| margin-bottom: 0.75rem;
| |
| background: var( --edfm-surface-2 );
| |
| border-left: 3px solid var( --edfm-border );
| |
| }
| |
| .mw-footer {
| |
| padding: 1rem;
| |
| margin-top: 1.5rem;
| |
| }
| |
| }
| |
| @media ( max-width: 430px ) {
| |
| .edfm-mobile-brand::before {
| |
| content: 'EDFM';
| |
| margin-right: 0.45rem;
| |
| }
| |
| .edfm-mobile-brand {
| |
| font-size: 0.88rem;
| |
| }
| |
| .edfm-infobox-row {
| |
| grid-template-columns: 1fr;
| |
| gap: 0.2rem;
| |
| }
| |
| }
| |
|
| |
| /* 22a. Mobile action tabs refinement: keep Vector's page/discussion/read/
| |
| source/history controls available, but put them on one compact horizontal
| |
| action rail so the first phone viewport feels like a real mobile app shell
| |
| instead of two stacked desktop tab bars. */
| |
| @media ( max-width: 800px ) {
| |
| body:not( .edfm-mobile-search-open ) #mw-head {
| |
| display: flex;
| |
| align-items: stretch;
| |
| gap: 0;
| |
| overflow-x: auto;
| |
| overflow-y: hidden;
| |
| -webkit-overflow-scrolling: touch;
| |
| scrollbar-width: thin;
| |
| }
| |
| body:not( .edfm-mobile-search-open ) #left-navigation,
| |
| body:not( .edfm-mobile-search-open ) #right-navigation {
| |
| flex: 0 0 auto;
| |
| clear: none !important;
| |
| float: none !important;
| |
| width: auto;
| |
| padding: 0 0.25rem;
| |
| margin: 0 !important;
| |
| border-right: 1px solid var( --edfm-border-soft );
| |
| }
| |
| body:not( .edfm-mobile-search-open ) .vector-menu-tabs-legacy,
| |
| body:not( .edfm-mobile-search-open ) .vector-menu-dropdown {
| |
| float: none !important;
| |
| display: inline-block;
| |
| }
| |
| body:not( .edfm-mobile-search-open ) .vector-menu-tabs-legacy li a,
| |
| body:not( .edfm-mobile-search-open ) .vector-menu-tabs-legacy li a:visited,
| |
| body:not( .edfm-mobile-search-open ) .vector-menu-dropdown .vector-menu-heading {
| |
| min-height: 40px;
| |
| padding-left: 0.55rem;
| |
| padding-right: 0.55rem;
| |
| font-size: 0.68rem;
| |
| }
| |
| body.edfm-mobile-search-open #mw-head {
| |
| display: block;
| |
| }
| |
| }
| |
|
| |
| /* ===========================================================================
| |
| 24. HARD OVERRIDE: JUMP TILE LEFT RAIL
| |
|
| |
| The earlier border-left rail can be swallowed by ResourceLoader/cascade or
| |
| visually read as part of the tile edge. Draw the rail as a high-specificity
| |
| gradient on the actual top-level TOC anchors so it is unmistakable on the
| |
| live jump grid.
| |
| =========================================================================== */
| |
| #toc.toc > ul > li > a,
| |
| .mw-parser-output #toc > ul > li > a,
| |
| .mw-parser-output .toc > ul > li > a {
| |
| background-image: linear-gradient( 90deg, var( --edfm-orange ) 0, var( --edfm-orange ) 6px, transparent 6px ) !important;
| |
| border-left: 0 !important;
| |
| padding-left: 1rem !important;
| |
| }
| |
| #toc.toc > ul > li > a:hover,
| |
| #toc.toc > ul > li > a:focus-visible,
| |
| .mw-parser-output #toc > ul > li > a:hover,
| |
| .mw-parser-output #toc > ul > li > a:focus-visible,
| |
| .mw-parser-output .toc > ul > li > a:hover,
| |
| .mw-parser-output .toc > ul > li > a:focus-visible {
| |
| background-image: linear-gradient( 90deg, var( --edfm-cyan ) 0, var( --edfm-cyan ) 6px, transparent 6px ) !important;
| |
| }
| |
|
| |
| /* ===========================================================================
| |
| 25. SOURCE EDIT CONFLICT / WIKITEXT DIFF THEME
| |
|
| |
| Source-edit conflict review uses MediaWiki's diff table classes, not the
| |
| normal edit textarea/WikiEditor chrome. Without this, unchanged rows and
| |
| inline change pills fall back to stark white/yellow/blue defaults. Keep the
| |
| old/new meaning, but render it in EDFM's dark surfaces with restrained
| |
| orange/cyan accents.
| |
| =========================================================================== */
| |
| .mw-parser-output table.diff,
| |
| table.diff,
| |
| .diff {
| |
| background: var( --edfm-bg-deep ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-collapse: separate !important;
| |
| border-spacing: 0 0.12rem !important;
| |
| }
| |
| .diff-title,
| |
| .diff-otitle,
| |
| .diff-ntitle,
| |
| #mw-diff-otitle1,
| |
| #mw-diff-ntitle1 {
| |
| background: var( --edfm-bg-deep ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| font-family: var( --edfm-mono );
| |
| }
| |
| td.diff-lineno,
| |
| .diff-lineno {
| |
| background: transparent !important;
| |
| color: var( --edfm-text ) !important;
| |
| font-family: var( --edfm-mono );
| |
| font-weight: 700;
| |
| border: 0 !important;
| |
| padding: 0.35rem 0.5rem !important;
| |
| }
| |
| td.diff-marker,
| |
| .diff-marker {
| |
| background: transparent !important;
| |
| color: var( --edfm-text ) !important;
| |
| font-family: var( --edfm-mono );
| |
| font-weight: 700;
| |
| padding: 0.25rem 0.45rem !important;
| |
| text-align: center;
| |
| }
| |
| td.diff-context,
| |
| td.diff-addedline,
| |
| td.diff-deletedline,
| |
| .diff-context,
| |
| .diff-addedline,
| |
| .diff-deletedline,
| |
| .mw-diff-inline-context,
| |
| .mw-diff-inline-added,
| |
| .mw-diff-inline-deleted,
| |
| .mw-diff-inline-changed,
| |
| .mw-diff-inline-moved {
| |
| background: var( --edfm-surface-1 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| font-family: var( --edfm-mono );
| |
| box-shadow: none !important;
| |
| }
| |
| td.diff-context:empty,
| |
| td.diff-addedline:empty,
| |
| td.diff-deletedline:empty,
| |
| .diff-context:empty,
| |
| .diff-addedline:empty,
| |
| .diff-deletedline:empty {
| |
| /* Empty diff cells are alignment placeholders. Keep their card boundary so
| |
| the two-column source-conflict diff does not look broken, but make them
| |
| compact and neutral instead of tall blank blocks. */
| |
| background: var( --edfm-surface-1 ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| box-shadow: none !important;
| |
| min-height: 0;
| |
| padding-top: 0.08rem !important;
| |
| padding-bottom: 0.08rem !important;
| |
| }
| |
| td.diff-deletedline,
| |
| .diff-deletedline,
| |
| .mw-diff-inline-deleted {
| |
| background: rgba( 255, 138, 0, 0.08 ) !important;
| |
| border-color: rgba( 255, 138, 0, 0.6 ) !important;
| |
| border-left-color: var( --edfm-orange ) !important;
| |
| }
| |
| td.diff-addedline,
| |
| .diff-addedline,
| |
| .mw-diff-inline-added {
| |
| background: rgba( 66, 199, 217, 0.08 ) !important;
| |
| border-color: rgba( 66, 199, 217, 0.6 ) !important;
| |
| border-left-color: var( --edfm-cyan ) !important;
| |
| }
| |
| .diffchange,
| |
| .diff-addedline .diffchange,
| |
| .diff-deletedline .diffchange,
| |
| .mw-diff-inline-added ins,
| |
| .mw-diff-inline-changed ins,
| |
| .mw-diff-inline-moved ins,
| |
| .mw-diff-inline-deleted del,
| |
| .mw-diff-inline-changed del,
| |
| .mw-diff-inline-moved del {
| |
| border-radius: 3px !important;
| |
| padding: 0.08rem 0.22rem !important;
| |
| font-weight: 700;
| |
| text-decoration: none !important;
| |
| color: var( --edfm-bg-deep ) !important;
| |
| }
| |
| .diff-deletedline .diffchange,
| |
| .mw-diff-inline-deleted del,
| |
| .mw-diff-inline-changed del,
| |
| .mw-diff-inline-moved del {
| |
| background: var( --edfm-orange-bright ) !important;
| |
| }
| |
| .diff-addedline .diffchange,
| |
| .mw-diff-inline-added ins,
| |
| .mw-diff-inline-changed ins,
| |
| .mw-diff-inline-moved ins {
| |
| background: var( --edfm-cyan ) !important;
| |
| }
| |
| .mw-explainconflict,
| |
| #wpTextbox2,
| |
| textarea#wpTextbox2,
| |
| textarea.mw-textarea-oldrev {
| |
| background: var( --edfm-surface-1 ) !important;
| |
| color: var( --edfm-text ) !important;
| |
| border-color: var( --edfm-border ) !important;
| |
| }
| |
|
| |
|
| |
| /* Engineer directory portrait chips -- intentionally quiet so table rows still
| |
| read like data rows, not card/list hybrids. */
| |
| .edfm-engineer-entry {
| |
| display: inline-flex;
| |
| align-items: center;
| |
| gap: 0.45rem;
| |
| min-width: max-content;
| |
| }
| |
| .edfm-engineer-entry .mw-file-element {
| |
| width: 30px;
| |
| height: 30px;
| |
| object-fit: cover;
| |
| border-radius: 3px;
| |
| border: 1px solid var( --edfm-border );
| |
| background: var( --edfm-surface-0 );
| |
| box-shadow: none;
| |
| }
| |
| .edfm-engineer-entry__name {
| |
| line-height: 1.2;
| |
| }
| |
|
| |
| /* Frontier official news feed image treatment */
| |
| .edfm-frontier-news .edfm-news-card-art-image {
| |
| display: block;
| |
| position: relative;
| |
| padding: 0;
| |
| min-height: 9.5rem;
| |
| background: var( --edfm-surface-4 );
| |
| overflow: hidden;
| |
| }
| |
| .edfm-frontier-news .edfm-news-card-primary .edfm-news-card-art-image {
| |
| min-height: 13.5rem;
| |
| }
| |
| .edfm-frontier-news .edfm-news-card-art-image > span,
| |
| .edfm-frontier-news .edfm-news-card-art-image .mw-default-size,
| |
| .edfm-frontier-news .edfm-news-card-art-image .mw-file-description {
| |
| display: block !important;
| |
| position: absolute;
| |
| inset: 0;
| |
| width: 100% !important;
| |
| height: 100% !important;
| |
| max-width: none !important;
| |
| margin: 0 !important;
| |
| }
| |
| .edfm-frontier-news .edfm-news-card-art-image .mw-file-element {
| |
| display: block !important;
| |
| width: 100% !important;
| |
| height: 100% !important;
| |
| max-width: none !important;
| |
| object-fit: cover;
| |
| transition: transform 0.2s ease, filter 0.2s ease;
| |
| }
| |
| .edfm-frontier-news .edfm-news-card:hover .edfm-news-card-art-image .mw-file-element {
| |
| filter: brightness( 1.08 ) contrast( 1.05 );
| |
| transform: scale( 1.035 );
| |
| }
| |
| .edfm-frontier-news .edfm-news-source-badge {
| |
| display: inline-flex !important;
| |
| align-items: center;
| |
| position: absolute !important;
| |
| left: 0.8rem !important;
| |
| right: auto !important;
| |
| bottom: 0.75rem !important;
| |
| z-index: 2;
| |
| max-width: calc( 100% - 1.6rem );
| |
| padding: 0.25rem 0.55rem;
| |
| background: rgba( 10, 13, 17, 0.82 );
| |
| border: 1px solid rgba( 255, 138, 0, 0.48 );
| |
| box-shadow: 0 8px 18px rgba( 0, 0, 0, 0.34 );
| |
| color: var( --edfm-text );
| |
| font-family: var( --edfm-mono );
| |
| font-size: 0.68rem;
| |
| font-weight: 800;
| |
| letter-spacing: 0.08em;
| |
| line-height: 1;
| |
| text-transform: uppercase;
| |
| white-space: nowrap;
| |
| pointer-events: none;
| |
| }
| |
|
| |
| .edfm-news-attribution {
| |
| margin-top: 0.85rem;
| |
| padding-top: 0.75rem;
| |
| border-top: 1px solid var( --edfm-border-soft );
| |
| color: var( --edfm-text-dim );
| |
| font-family: var( --edfm-mono );
| |
| font-size: var( --edfm-fs-meta );
| |
| line-height: 1.45;
| |
| }
| |