/* NovaWiki — dark "instrument" theme.
   Palette anchored to the warm-up screen so the load→site transition is seamless. */

:root {
    color-scheme: dark;

    --bg: #0f1115;
    --surface: #161920;
    --surface-2: #1c2029;
    --border: #242833;
    --border-soft: #1e222b;

    /* THE INK SCALE, AND THESE TWO VALUES ARE MEASURED RATHER THAN CHOSEN.
       _verify/_contrast.py prints the table; run it after touching anything here.

       --faint was #6b7280, which measures 3.37:1 against --surface-2. WCAG AA for text under
       18.66px is 4.5:1, and every single use of --faint in this file is at 15px or below — three
       of them at 10px. It failed on every surface, and it is the ink behind the rail labels, the
       contents card, the search metadata and the gallery captions: the whole complaint that
       system-generated text reads too dark was this one token.

       --muted was #9aa0aa at 6.20:1, which passes but sits close enough to the floor to be worth
       lifting while the file is open.

       The replacements clear AA everywhere — 8.27:1 and 5.48:1 at worst — and the luminance step
       BETWEEN them widens from 1.32x to 1.60x, so the three tiers separate better than before
       rather than collapsing toward each other. A --faint lifted until it matches --muted would
       have fixed the contrast by destroying the distinction it exists to make. */
    --text: #e7e9ee;
    --muted: #b3b9c4;
    --faint: #8f96a2;

    --accent: #5b8cff;
    --accent-quiet: #33406b;
    --ok: #6ee7a8;
    --warn: #f0c674;
    --danger: #ff6b6b;

    /* Page provenance (frame-relative): a page this wiki owns vs one inherited
       through the cascade. Used by the sidebar search; tune both in one place. */
    --origin-local: #7aa2ff;
    --origin-upstream: #58c7b0;

    --mono: ui-monospace, "SFMono-Regular", "JetBrains Mono", "Cascadia Code", Consolas, monospace;
    --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

    --header-h: 44px;
    --pad: clamp(16px, 3vw, 32px);
    --rail-w: 15rem;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--sans);
    font-size: 15px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

/* ---- Thin header, full width ---------------------------------------------------------- */

.site-header {
    display: flex;
    align-items: center;
    gap: 24px;
    height: var(--header-h);
    padding: 0 var(--pad);
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 10;
}

.site-header .brand {
    font-family: var(--mono);
    font-weight: 600;
    font-size: 14px;
    letter-spacing: 0.02em;
    color: var(--text);
    text-decoration: none;
    white-space: nowrap;
}
.site-header .brand::before {
    content: "◆";
    color: var(--accent);
    margin-right: 8px;
    font-size: 11px;
    vertical-align: 1px;
}

.site-nav {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: 1;
}
.site-nav a {
    color: var(--muted);
    text-decoration: none;
    font-size: 13px;
    padding: 4px 10px;
    border-radius: 6px;
    line-height: 1.4;
}
.site-nav a:hover { color: var(--text); background: var(--surface-2); }
.site-nav a.active { color: var(--text); }

.site-auth { display: flex; align-items: center; }
.site-auth ul { list-style: none; display: flex; align-items: center; gap: 4px; margin: 0; padding: 0; }
.site-auth a,
.site-auth button {
    color: var(--muted);
    background: none;
    border: 0;
    text-decoration: none;
    font-size: 13px;
    font-family: var(--sans);
    padding: 4px 10px;
    border-radius: 6px;
    cursor: pointer;
}
.site-auth a:hover,
.site-auth button:hover { color: var(--text); background: var(--surface-2); }

/* ---- Full-width main ------------------------------------------------------------------ */

.site-main {
    padding: var(--pad);
    max-width: none;
}

/* ---- App shell: optional left rail + main --------------------------------------------- */

.site-shell { display: flex; align-items: flex-start; }

/* Main fills the row; min-width:0 lets wide tables / <pre> scroll instead of stretching it. */
.site-shell > .site-main { flex: 1 1 auto; min-width: 0; }

/* Left rail: continues the header's surface chrome down the page, sticky beneath the header.
   Pages that don't define a Sidebar section render no <aside>, so main stays full width. */
.site-sidebar {
    flex: 0 0 var(--rail-w);
    position: sticky;
    top: var(--header-h);
    height: calc(100vh - var(--header-h));
    overflow-y: auto;
    padding: var(--pad) 16px;
    background: var(--surface);
    border-right: 1px solid var(--border);
    /* 15px — the same size as body text, reached in two steps because 14 was still too small.
       This one declaration sizes everything in the rail that does not set its own size, and the
       rail is navigation people READ rather than a caption they glance at. There is no reason for
       it to be smaller than the article beside it. */
    font-size: 15px;
}

/* Rail nav links mirror the header nav: muted, lifting to full text on hover. */
.site-sidebar .wiki-nav a {
    display: block;
    color: var(--muted);
    text-decoration: none;
    padding: 4px 8px;
    border-radius: 6px;
    line-height: 1.4;
}
.site-sidebar .wiki-nav a:hover { color: var(--text); background: var(--surface-2); }

/* ---- MediaWiki:Sidebar portlets ---------------------------------------------------------
   The rail's actual navigation on a wiki page: _SidebarSections.cshtml renders one .sb-portlet
   per section of MediaWiki:Sidebar, plus the built-in Toolbox.

   THESE RULES WERE MISSING ENTIRELY. They were written and delivered as a separate
   sidebar-portlets.css "to append to site.css", and the appending never happened — so every link
   in the wiki sidebar has been falling back to the user agent's default styling, with default link
   colour and default list bullets, on a dark background. That is why lifting --muted and --faint
   improved every other surface and left this one looking wrong: none of these elements was reading
   a token at all.

   The lesson is in where they live now. A stylesheet delivered "to be appended" is a change that
   has to be performed by hand, and a hand can miss it silently — nothing errors, nothing logs, the
   page simply renders with default styling and looks slightly off for months. Rules belong in the
   file that ships. */

.sb-portlet { margin: 0 0 18px; }

.sb-portlet-title {
    margin: 0 0 6px;
    padding: 0 8px 4px;
    /* 12px, not the 11 originally drafted: this is the only label naming what a group of links IS,
       and it is set in caps where every lost pixel costs more than it does in lower case. */
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    border-bottom: 1px solid var(--border);
}

.sb-portlet-body { list-style: none; margin: 0; padding: 0; }
.sb-portlet-body li { margin: 0; }

/* The links themselves. Deliberately no font-size: they inherit the rail's 15px, so the rail is
   sized in ONE place and cannot drift from itself. */
.sb-link {
    display: block;
    padding: 4px 8px;
    border-radius: 6px;
    line-height: 1.45;
    color: var(--muted);
    text-decoration: none;
}
.sb-link:hover,
.sb-link:focus-visible { color: var(--text); background: var(--surface-2); }

/* External links leave the mirror — marked, quietly. */
.sb-external::after { content: " \2197"; font-size: 0.82em; color: var(--faint); }

/* The toolbox reads a step quieter than primary navigation.

   BY INK, NOT BY OPACITY. The draft used opacity: 0.85, which multiplies against the background
   and silently drops the contrast of whatever colour it is applied to — --muted at 85% lands back
   near the value that failed AA in the first place. --faint says the same thing, is measured, and
   stays measured when the tokens move. */
.sb-toolbox .sb-link { color: var(--faint); }
.sb-toolbox .sb-link:hover,
.sb-toolbox .sb-link:focus-visible { color: var(--text); }

/* ---- Special/RecentChanges --------------------------------------------------------------
   Missing for the same reason and shipped in the same file. */

.recentchanges { list-style: none; margin: 0; padding: 0; }
.recentchanges li {
    display: flex;
    gap: 12px;
    align-items: baseline;
    padding: 6px 0;
    border-bottom: 1px solid var(--border);
}
.rc-time {
    flex: 0 0 auto;
    font-family: var(--mono);
    font-size: 13px;
    color: var(--muted);
}
.rc-page { text-decoration: none; }
.rc-page:hover { text-decoration: underline; }

/* ---- Rail search (autocomplete) -------------------------------------------------------- */

/* Rail search sits at the top of the rail; nav follows it. */
.rail-search { margin-bottom: 20px; }

.rail-label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin: 0 8px 6px;
}

.search-box { position: relative; }

.search-box input {
    width: 100%;
    padding: 6px 10px;
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-family: var(--sans);
    font-size: 13px;
    line-height: 1.4;
}
.search-box input::placeholder { color: var(--faint); }
.search-box input:focus { outline: none; border-color: var(--accent-quiet); }
.search-box input::-webkit-search-cancel-button { filter: invert(0.6); }

/* Dropdown overlays the rail rather than pushing content down. */
.search-panel {
    position: absolute;
    z-index: 20;
    left: 0;
    right: 0;
    top: calc(100% + 4px);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 24px -6px rgba(0, 0, 0, 0.6);
    overflow: hidden;
}

.search-results {
    max-height: 300px;
    overflow-y: auto;
    margin: 0;
    padding: 4px;
    list-style: none;
}

.search-results .result {
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding: 4px 8px;
    border-radius: 5px;
    border-left: 2px solid transparent;
    margin: 1px 0;
}
.search-results .result:hover,
.search-results .result.active { background: var(--surface); }

.search-results .result-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-decoration: none;
    font-size: 13px;
}

/* The wrinkle: provenance is carried by color (plus a left edge, so it does not
   rely on hue alone) — local pages in accent blue, inherited ones in teal. */
.search-results .result.local { border-left-color: var(--origin-local); }
.search-results .result.local .result-name { color: var(--origin-local); }
.search-results .result.inherited { border-left-color: var(--origin-upstream); }
.search-results .result.inherited .result-name { color: var(--origin-upstream); }

/* Which ancestor layer an inherited page came from. */
.search-results .result-from {
    flex: none;
    font-family: var(--mono);
    /* 10px was below the size at which the contrast rules even permit --faint, and it named the
       wiki a result came from — which is the single most useful thing in the row for anybody
       working across a cascade. */
    font-size: 12px;
    color: var(--faint);
    max-width: 45%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Escalation row: what Enter does when no suggestion was chosen. */
.search-all {
    display: block;
    padding: 7px 10px;
    border-top: 1px solid var(--border);
    background: var(--surface);
    color: var(--muted);
    font-size: 12.5px;
    text-decoration: none;
    line-height: 1.35;
}
.search-all:hover { color: var(--text); background: var(--accent-quiet); }

.search-legend {
    display: flex;
    gap: 12px;
    margin: 8px 8px 0;
    font-size: 12px;
    color: var(--faint);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.search-legend .key::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 2px;
    margin-right: 4px;
    vertical-align: 1px;
}
.search-legend .key.local::before { background: var(--origin-local); }
.search-legend .key.inherited::before { background: var(--origin-upstream); }

/* ---- Full search page ------------------------------------------------------------------ */

.search-page { max-width: 760px; }
.search-page h1 { font-size: 1.3rem; margin: 0 0 16px; }

.search-page-form { display: flex; gap: 8px; margin-bottom: 18px; }
.search-page-form input {
    flex: 1 1 auto;
    padding: 7px 12px;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 7px;
    font-family: var(--sans);
    font-size: 14px;
}
.search-page-form input:focus { outline: none; border-color: var(--accent-quiet); }
.search-page-form button {
    flex: none;
    padding: 7px 16px;
    background: var(--accent-quiet);
    color: var(--text);
    border: 0;
    border-radius: 7px;
    font-family: var(--sans);
    font-size: 13px;
    cursor: pointer;
}
.search-page-form button:hover { background: var(--accent); }

.search-summary { color: var(--muted); font-size: 13px; margin: 0 0 14px; }
.search-summary .search-note { color: var(--faint); }

.search-hits { list-style: none; margin: 0; padding: 0; }
.search-hit {
    padding: 10px 0 10px 12px;
    border-left: 2px solid transparent;
    border-bottom: 1px solid var(--border-soft);
}
.search-hit.local { border-left-color: var(--origin-local); }
.search-hit.inherited { border-left-color: var(--origin-upstream); }

.search-hit .hit-name { font-size: 14px; text-decoration: none; }
.search-hit.local .hit-name { color: var(--origin-local); }
.search-hit.inherited .hit-name { color: var(--origin-upstream); }
.search-hit .hit-name:hover { text-decoration: underline; }

.search-hit .hit-from {
    font-family: var(--mono);
    font-size: 12px;
    color: var(--faint);
    margin-left: 8px;
}

.search-hit .hit-snippet {
    margin: 4px 0 0;
    color: var(--muted);
    font-size: 12.5px;
    line-height: 1.55;
}
.search-hit .hit-snippet mark {
    background: var(--accent-quiet);
    color: var(--text);
    border-radius: 2px;
    padding: 0 1px;
}

/* ---- Page view: rendered / source tabs ----------------------------------------------- */

.tabstrip {
    display: flex;
    gap: 2px;
    border-bottom: 1px solid var(--border);
    margin-bottom: var(--pad);
}
.tabstrip .tab {
    appearance: none;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;                 /* overlap the strip's own 1px border */
    padding: 8px 14px;
    color: var(--muted);
    font-family: var(--sans);
    font-size: 13px;
    line-height: 1.4;
    cursor: pointer;
}
.tabstrip .tab:hover { color: var(--text); }
.tabstrip .tab[aria-selected="true"] {
    color: var(--text);
    border-bottom-color: var(--accent);
}

/* Raw source: echoes the .site-main <pre> code-block treatment. */
.source-editor {
    display: block;
    width: 100%;
    min-height: 60vh;
    resize: vertical;
    padding: 14px 16px;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-family: var(--mono);
    font-size: 13px;
    line-height: 1.6;
    tab-size: 4;
}

/* ---- Content: wiki tree, page lists, rendered page HTML ------------------------------- */

.site-main a { color: var(--accent); text-decoration: none; }
.site-main a:hover { text-decoration: underline; }

.site-main h1, .site-main h2, .site-main h3, .site-main h4 {
    line-height: 1.25;
    font-weight: 650;
    margin: 1.6em 0 0.6em;
}
/* HEADINGS SCALE WITH THE ARTICLE TOO — em, not rem. A wiki that sets its body to 120% and picks
   a display face for its headings (several in this corpus do exactly that) means it for the
   headings as much as the prose; leaving them in rem pinned them to the root while the text around
   them grew. */
.site-main h1 { font-size: 1.7em; margin-top: 0; }
.site-main h2 { font-size: 1.35em; border-bottom: 1px solid var(--border); padding-bottom: 0.3em; }
.site-main h3 { font-size: 1.12em; }

.site-main p { margin: 0 0 1em; }

.site-main ul, .site-main ol { padding-left: 1.3em; margin: 0.4em 0; }
.site-main li { margin: 0.15em 0; }

/* Code blocks scale too, floored so a wiki with no override does not drop them to 11px. */
.site-main pre {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 14px 16px;
    overflow-x: auto;
    font-family: var(--mono);
    /* Floored, so a wiki with no body override does not drop code to eleven pixels. */
    font-size: max(13px, 0.82em);
}
.site-main code {
    font-family: var(--mono);
    font-size: 0.9em;
    background: var(--surface-2);
    padding: 0.1em 0.35em;
    border-radius: 4px;
}
.site-main pre code { background: none; padding: 0; }

.site-main blockquote {
    margin: 1em 0;
    padding: 0.2em 1em;
    border-left: 3px solid var(--accent-quiet);
    color: var(--muted);
}

/* Tables. MediaWiki decorates .wikitable and NOTHING else: a raw <table> in wikitext, and a {|
   that carries its own attributes, are layout — they get no borders, no cell padding, no forced
   alignment. These rules used to apply to every table in the content area, which broke raw layout
   tables two ways at once: "border: 1px" drew lines the author never asked for, and "width: auto"
   silently beat the width="100%" attribute, because author CSS outranks HTML presentational hints.
   That is why "<table width=100%>" collapsed to less than the container.

   RenderBlocks already draws the line for us — a bare {| is emitted as class="wikitable", while
   {| with attributes keeps only its own — so wikitext data tables look exactly as they did, and
   what changes is that raw HTML tables are left alone. No width, valign or align is overridden
   anywhere now, so presentational attributes behave as they do on MediaWiki.

   Nothing constrains an undecorated table's width on purpose: min-width:0 on .site-main (see the
   shell rules above) already stops a wide table pushing the rail off-screen, and clamping it would
   squash tables MediaWiki lets overflow. */
.site-main table.wikitable {
    border-collapse: collapse;
    margin: 1em 0;
}
.site-main table.wikitable th, .site-main table.wikitable td {
    border: 1px solid var(--border);
    padding: 6px 12px;
    text-align: left;
}
.site-main table.wikitable th { background: var(--surface); }

/* Caption sits above the table as a label, MediaWiki-style. */
.site-main table > caption {
    caption-side: top;
    font-weight: 600;
    color: var(--text);
    padding: 0 0 0.4em;
    text-align: center;
}

/* ---- Sortable tables (wwwroot/js/wikitable.js) ---------------------------------------------
   The script marks each clickable header .sortable-header and tracks direction in aria-sort, so
   the indicator is driven by the same attribute a screen reader announces rather than a parallel
   class. A header the script skipped — class="unsortable", or a colspan that doesn't map to one
   column — gets neither, so it simply reads as an ordinary header. */
.site-main th.sortable-header {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.site-main th.sortable-header:hover { background: var(--surface-2); }
.site-main th.sortable-header:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.site-main th[aria-sort]::after {
    font-size: 0.75em;
    margin-left: 5px;
    opacity: 0.55;
}
.site-main th[aria-sort="none"]::after { content: "\2195"; opacity: 0.3; }   /* ↕ */
.site-main th[aria-sort="ascending"]::after { content: "\25B2"; }            /* ▲ */
.site-main th[aria-sort="descending"]::after { content: "\25BC"; }           /* ▼ */

/* A totals/footer row pinned by class="sortbottom" stays put however the table is sorted. */
.site-main tr.sortbottom { font-weight: 600; }

/* ---- Collapsible tables --------------------------------------------------------------------
   The script hides rows with the hidden attribute; spelling out display:none guards against a
   browser's default table-row display winning over [hidden]. */
.site-main tr[hidden] { display: none; }

.mw-collapsible-toggle {
    float: right;
    margin-left: 12px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    font: inherit;
    font-size: 0.85em;
    font-weight: 400;
    cursor: pointer;
}
.mw-collapsible-toggle:hover { text-decoration: underline; }

/* ---- Remaining wikitable/wikitext classes MediaWiki honours --------------------------------- */

/* Suppress the external-link arrow inside a .plainlinks region. */
.site-main .plainlinks a.external::after { content: none; }

.site-main .floatright { float: right; margin: 0 0 1em 1em; }
.site-main .floatleft { float: left; margin: 0 1em 1em 0; }
.site-main table.center { margin-left: auto; margin-right: auto; }
.site-main .nowrap,
.site-main .nowrap td,
.site-main .nowrap th { white-space: nowrap; }

/* The bordered box MediaWiki uses for navboxes and side notes. */
.site-main table.toccolours {
    border: 1px solid var(--border);
    background: var(--surface);
    border-radius: 6px;
    padding: 5px;
    margin: 1em 0;
    font-size: 0.95em;
}

.site-main img { max-width: 100%; height: auto; border-radius: 6px; }

.site-main hr { border: 0; border-top: 1px solid var(--border); margin: 1.5em 0; }

/* Parser output hooks. Missing pages follow the MediaWiki red-link convention. */
.site-main .dpl-empty { color: var(--faint); font-style: normal; font-size: 0.9em; }
.site-main .new-page { color: var(--danger); font-weight: 550; }
.site-main a.new { color: var(--danger); }
.site-main a.external::after { content: "\2197"; font-size: 0.7em; margin-left: 2px; opacity: 0.7; }
.site-main img.wikiimage { max-width: 100%; height: auto; border-radius: 6px; }

/* ==========================================================================================
   ARTICLE CHROME SCALES WITH THE ARTICLE. Read this before changing a font-size below.

   A wiki's own MediaWiki:Common.css may resize the body — several in this corpus carry
   `body { font-size: 120% !important; }` alongside a serif face, deliberately — and everything
   rendered INSIDE the article has to move with it. A DPL table does, because table.wikitable sets
   no size and inherits. The contents card and the gallery captions did not, because they were set
   in px and rem, and both ignore that override: px obviously, and rem because it resolves against
   the ROOT element, which the body rule never touches.

   So: inside .site-main, size in `em`. Never px, never rem.

   Where a label must stay legible at the SMALL end — a wiki with no override renders body at 15px,
   and 0.7em of that is 10.5px — use max(floor, em). It scales up with the wiki and refuses to go
   below the readable floor, which no single unit can do on its own.

   SITE CHROME IS THE OPPOSITE and stays absolute: the rail, the header, the search panel and the
   ledger dialog are NovaWiki's furniture, and a page's stylesheet has no business resizing them.
   ========================================================================================== */

/* Table of contents card. */
.toc {
    display: inline-block;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 20px;
    margin: 0.4em 0 1.4em;
    /* 1em: the size of the article it indexes, whatever that turns out to be. A contents card is
       a reading aid, and setting it below the text it indexes makes the aid harder to read than
       the thing it helps with. Three attempts before this — 13px, 14px, 15px — all of which were
       absolute and therefore all of which missed on any wiki scaling its own body. */
    font-size: 1em;
    line-height: 1.6;
}
.toc .toc-title {
    /* Below the entries, because an uppercase tracked label should not compete with them — but
       floored, because 0.7em of an unscaled 15px body is 10.5px. */
    font-size: max(12px, 0.7em);
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 6px;
}
.toc ul { list-style: none; margin: 0; padding-left: 0; }
.toc ul ul { padding-left: 16px; }
.toc li { margin: 1px 0; }
.toc a { text-decoration: none; }
.toc a:hover .toctext { text-decoration: underline; }
.toc .tocnumber { font-family: var(--mono); font-size: max(12px, 0.8em); color: var(--muted); margin-right: 6px; }

/* Anchor jumps (TOC, [[Page#Section]]) must not land under the sticky header. */
.site-main :is(h1, h2, h3, h4, h5, h6) span[id] { scroll-margin-top: calc(var(--header-h) + 10px); }

/* Redirect affordances. */
.redirected-from { color: var(--muted); font-size: 12px; margin: -4px 0 12px; }
.site-main .redirect-note { color: var(--muted); font-style: italic; }

/* Nested wiki tree on the home page reads as a hierarchy, not bullets. */
.wiki-tree, .wiki-tree ul { list-style: none; padding-left: 0; margin: 0; }
.wiki-tree ul { padding-left: 16px; border-left: 1px solid var(--border-soft); margin-left: 6px; }
.wiki-tree li { margin: 2px 0; }
.wiki-tree a { display: inline-block; padding: 2px 0; }

/* ---- Status page ---------------------------------------------------------------------- */

.status { max-width: 640px; }
.status h1 { font-size: 1.3rem; margin: 0 0 4px; }
.status .lede { color: var(--muted); margin: 0 0 24px; font-size: 0.95rem; }

.status-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 20px 22px;
}

.status-state { display: flex; align-items: center; gap: 10px; font-size: 1.05rem; font-weight: 550; }
.status-dot {
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--faint);
    box-shadow: 0 0 0 0 rgba(0,0,0,0);
    flex: none;
}
.status-dot.live { background: var(--ok); box-shadow: 0 0 10px -1px var(--ok); }
.status-dot.busy { background: var(--accent); animation: pulse 1.4s ease-in-out infinite; }
.status-dot.error { background: var(--danger); }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }

.status-detail { color: var(--muted); font-size: 0.9rem; margin: 6px 0 0; }

.track { height: 6px; border-radius: 999px; background: var(--surface-2); overflow: hidden; margin: 18px 0 6px; }
.track .bar { height: 100%; width: 0; background: var(--accent); border-radius: 999px; transition: width 0.4s ease; }
.track .bar.indet { width: 35%; animation: slide 1.2s ease-in-out infinite; }
@keyframes slide { from { margin-left: -35%; } to { margin-left: 100%; } }
.track-label { font-family: var(--mono); font-size: 12px; color: var(--muted); }

.metrics { display: flex; gap: 40px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
.metric .value { font-family: var(--mono); font-size: 1.5rem; color: var(--text); }
.metric .label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }

.status-error {
    display: none;
    margin-top: 16px;
    padding: 12px 14px;
    border-radius: 8px;
    background: #2a1616;
    color: #ffb4b4;
    font-size: max(13px, 0.85em);
    white-space: pre-wrap;
}

/* ---- Quality floor -------------------------------------------------------------------- */

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

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}


/* "Categories: A • B • C" footer at the bottom of a rendered page. */
.catlinks {
    margin-top: 1.5rem;
    padding: .5rem .75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface-2);
    font-size: .85rem;
}

.catlinks-label {
    color: var(--muted);
    font-weight: 600;
    margin-right: .5rem;
}

.catlinks ul {
    display: inline;
    margin: 0;
    padding: 0;
    list-style: none;
}

.catlinks li {
    display: inline;
}

    .catlinks li + li::before {
        content: "•";
        color: var(--muted);
        margin: 0 .5rem;
    }

/* ---- Definition / indent lists (: and ;) — align with the '*'/'#' list indent -----------
   .site-main ul/ol are already indented 1.3em, but dl/dd/dt were unstyled, so ':' lines fell back
   to the browser's ~2.6em dd margin and read as over-indented and detached. Matching dd to the ul
   indent lines a ':' line up under a '*' line's text, MediaWiki-style; dt stays flush-left (the
   definition term). */
.site-main dl { margin: 0.4em 0; }
.site-main dd { margin: 0.15em 0 0.15em 1.3em; }   /* 1.3em == the ul/ol indent → ':' aligns under '*' */
.site-main dt { margin: 0.15em 0; font-weight: 600; }

/* A '*' block followed by a ':' block are separate lists (as in MediaWiki); collapse the gap
   between adjacent list containers so they read as one continuous run. */
.site-main :is(ul, ol, dl) + :is(ul, ol, dl) { margin-top: 0; }

/* ---- <gallery> grid ------------------------------------------------------------------- */
.site-main .gallerycaption { font-weight: 600; color: var(--text); margin: 1.2em 0 0.4em; }
.site-main .gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    list-style: none;
    padding: 0;
    margin: 1em 0;
}
.site-main .gallery .gallerybox {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 6px;
}
.site-main .gallery .thumb {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    flex: 1;
}
/* Inline max-width:100% (+ optional max-height) rides on each <img>; the box width comes from
   the gallery's widths= attribute, so the image fits its box without overflowing the padding. */
.site-main .gallery .thumb img.wikiimage { height: auto; border-radius: 4px; }
.site-main .gallery .gallerytext {
    margin-top: 6px;
    /* 1em — the article's size. In a portrait gallery these lines are not captions, they are the
       character's DATA lifted out of the datalist, and reading them at a glance is the entire point
       of the mode. This was 1rem, which LOOKS like the same thing and is not: rem resolves against
       the root element, so a wiki scaling its own body left these behind at 15px beside 18px prose.
       A gallery box has a fixed width from its widths= attribute, so this costs some wrapping; a
       line that wraps and can be read beats one that fits and cannot. */
    font-size: 1em;
    line-height: 1.5;
    color: var(--muted);
    text-align: center;
    word-break: break-word;
}

/* ---- <ref> footnotes + <references/> list --------------------------------------------- */
.site-main sup.reference { font-size: 0.75em; line-height: 1; white-space: nowrap; }
.site-main sup.reference a { text-decoration: none; }
.site-main sup.reference a::before { content: ""; }   /* keep the [n] literal, no extra glyphs */

.site-main ol.references {
    margin: 1.2em 0 0;
    padding-left: 1.6em;
    font-size: max(13px, 0.9em);
    color: var(--muted);
    line-height: 1.5;
}
.site-main ol.references li { margin: 0.25em 0; }
.site-main ol.references li:target { background: var(--accent-quiet); border-radius: 4px; }
.site-main ol.references .ref-backlink,
.site-main ol.references .ref-backlinks a { text-decoration: none; color: var(--accent); }
.site-main ol.references .ref-backlinks { font-size: 0.85em; margin-right: 2px; }
.site-main ol.references .ref-missing { color: var(--danger); font-style: italic; }

/* A cited marker jumped to from its back-link must clear the sticky header, like heading anchors. */
.site-main sup.reference[id] { scroll-margin-top: calc(var(--header-h) + 10px); }

/* ---- [[File:…]] framing + placement (thumb/frame/frameless, left/right/center/none, border) --
   Alignment classes (.wimg-*) are applied to a bare <img>, a boxed <figure class="thumb">, or a
   plain captioned <figure class="image-fig">. The figure rules set only top/bottom margins so the
   alignment classes own left/right placement without a specificity fight. */
.site-main figure.thumb {
    margin-top: 0.4em;
    margin-bottom: 0.4em;
    padding: 4px;
    width: max-content;
    max-width: 100%;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.site-main figure.thumb img.wikiimage { display: block; border-radius: 4px; }
/* Captions, footnotes and code blocks: all article content, all em. */
.site-main figure.thumb figcaption {
    margin-top: 6px;
    font-size: max(13px, 0.85em);
    line-height: 1.4;
    color: var(--muted);
}

.site-main figure.image-fig {
    margin-top: 0.6em;
    margin-bottom: 0.6em;
    width: max-content;
    max-width: 100%;
}
.site-main figure.image-fig figcaption {
    margin-top: 4px;
    font-size: max(13px, 0.85em);
    color: var(--muted);
    text-align: center;
}

.site-main .wimg-left   { float: left;  margin-right: 1em; margin-bottom: 0.4em; }
.site-main .wimg-right  { float: right; margin-left: 1em;  margin-bottom: 0.4em; }
.site-main .wimg-center { display: block; float: none; margin-left: auto; margin-right: auto; }
.site-main .wimg-none   { float: none; }
.site-main img.wimg-border { border: 1px solid var(--border); padding: 2px; background: var(--surface); }

/* ---- DPL portrait gallery (mode=portraitgallery) --------------------------------------------
   Reuses the .gallery / .gallerybox / .thumb / .gallerytext structure from the <gallery> tag, and
   the same fixed box width, so portraits render at the same size as a regular gallery. Beyond that
   it only adds the page link + per-field text lines. */
.site-main .gallery .gallerybox > a { display: block; width: 100%; }
.site-main .gallery .gallerybox > a:hover { text-decoration: none; }
/* The name is the heading of the box: full ink, a size above the fields, so the eye lands on it
   first. Both were --muted at one size, which flattened the box into a single grey block. */
.site-main .gallery .gallerytext > a {
    display: block;
    margin-bottom: 4px;
    font-size: 1.05em;
    font-weight: 600;
    color: var(--text);
    line-height: 1.35;
}
.site-main .gallery .gallerytext > div { color: var(--muted); line-height: 1.5; }
.site-main .gallery .thumb-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 120px;
    color: var(--faint);
    font-size: max(13px, 0.85em);
    border: 1px dashed var(--border);
    border-radius: 4px;
}
