/* 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;

    --text: #e7e9ee;
    --muted: #9aa0aa;
    --faint: #6b7280;

    --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);
    font-size: 13px;
}

/* 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); }

/* ---- 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: 11px;
    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);
    font-size: 10px;
    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: 11.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: 10px;
    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: 10px;
    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;
}
.site-main h1 { font-size: 1.7rem; margin-top: 0; }
.site-main h2 { font-size: 1.35rem; border-bottom: 1px solid var(--border); padding-bottom: 0.3em; }
.site-main h3 { font-size: 1.12rem; }

.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; }

.site-main pre {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 14px 16px;
    overflow-x: auto;
    font-family: var(--mono);
    font-size: 13px;
}
.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; }

/* 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;
    font-size: 13px;
    line-height: 1.5;
}
.toc .toc-title {
    font-size: 11px;
    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: 11px; 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: 0.85rem;
    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;
    font-size: 0.82rem;
    line-height: 1.4;
    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: 0.9rem;
    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; }
.site-main figure.thumb figcaption {
    margin-top: 6px;
    font-size: 0.85rem;
    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: 0.85rem;
    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; }
.site-main .gallery .gallerytext > a { font-weight: 600; display: block; margin-bottom: 2px; }
.site-main .gallery .gallerytext > div { color: var(--muted); }
.site-main .gallery .thumb-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 120px;
    color: var(--faint);
    font-size: 0.8rem;
    border: 1px dashed var(--border);
    border-radius: 4px;
}
