/* ============================================================================
 * GMNET stylesheet — globalmilitary.net
 *
 * TABLE OF CONTENTS
 *   01. Design tokens             :root vars (typography, spacing, colors, semantic, dark)
 *   02. Base & global styles      body, headings, links, tables, breadcrumb
 *   03. Layout & card system      #page wrapper, .card / .card-header variants
 *   04. Charts & progress bars    barploth, bar-track, ordnance-bar-fill
 *   05. Podium medals & row states  medal-*, navy-*-row inventory tints
 *   06. Shared page furniture     pagination, ordnance scale diagram, flag pills
 *   07. Navigation                navbar, dropdowns, mobile menu
 *   08. Header search box         the search field inside the navbar
 *   09. FAQ accordion             pure-CSS <details> accordion
 *   10. Admin UI                  importjob form + Wikipedia autofill
 *   11. Leaflet maps              conflict events map, airbases maps
 *   12. Site shell                .cmd header, .foot footer, svg.ic sprite
 *   13. Components                THE design system — page-flat, eyebrow, hero variants
 *                                 (achero/afhero/herogrid), statband, herostat, console,
 *                                 tablecard/ledger, spec, table.data, ops/bar/fleetbars,
 *                                 arm, masonry, roster, prose, faq, vscard, cmpswitch,
 *                                 indexbadge, evochart, accard/fleetgrid, regtable,
 *                                 newscard, flagpanel, flagwall, board
 *   14. Quiz pages                quiz-* game shell, per-game .quiz-<slug> variants
 *
 * CONVENTIONS
 *   - Section 13 is where page work happens. Sections 02-11 are the pre-redesign
 *     layer: still live, but only for the handful of includes and django-tables2
 *     renderers that predate the ops-room components. Build on section 13.
 *   - Reuse tokens before adding new values. See CLAUDE.md "Design System".
 *   - No inline `style="..."` in templates except CSS-variable injection (--bar-pct, etc).
 *   - Wargame styling lives in a separate stylesheet (wargame.css), not converged with this one.
 *   - Breakpoints (canonical, in @media): 576 / 768 / 992 / 1200 px.
 *     CSS variables can't be used inside @media, so the values are inlined.
 *     Exceptions (480 / 860 / 900 / 1100) are intentional content-driven breaks.
 * ============================================================================ */


/* ============================================================================
 * 01 — DESIGN TOKENS
 * ============================================================================ */

/* Self-hosted fonts (latin subsets) — redesign 2026, see docs/design/ */
@font-face {
    font-family:"Barlow Condensed";
    font-style:normal;
    font-weight:500;
    font-display:swap;
    src:url("../fonts/barlow-condensed-500.woff2") format("woff2");
}
@font-face {
    font-family:"Barlow Condensed";
    font-style:normal;
    font-weight:600;
    font-display:swap;
    src:url("../fonts/barlow-condensed-600.woff2") format("woff2");
}
@font-face {
    font-family:"IBM Plex Mono";
    font-style:normal;
    font-weight:400;
    font-display:swap;
    src:url("../fonts/ibm-plex-mono-400.woff2") format("woff2");
}
@font-face {
    font-family:"IBM Plex Mono";
    font-style:normal;
    font-weight:500;
    font-display:swap;
    src:url("../fonts/ibm-plex-mono-500.woff2") format("woff2");
}

:root {
    /* Brand colors */
    --primary-color:#406880;
    --secondary-color:#4e6b84;
    --accent-color:#00991A;
    --accent-color-dark:#006600;
    --accent-color-light:#00CC33;
    --accent-blue:#89a6bd;

    /* Text & surfaces */
    --text-color:#1e2d3a;
    --text-muted:#5b7080;
    --light-gray:#e9ecef;
    --border-color:#dee2e6;
    --bg-gray:#f8f9fa;
    --color-white:#fff;
    --surface-color:#fff;
    --surface-muted:var(--bg-gray);
    --surface-subtle:var(--light-gray);

    /* Gradient palette (used in card-header variants) */
    --color-warm-orange:#c2590a;
    --color-warm-amber:#e8860c;

    /* Semantic colors (success / danger / warning / info)
     * Each family: solid, -text (dark variant for text on white),
     * -bg (pale background pill/row), -bg-text (text on the pale bg). */
    --color-success:#28a745;
    --color-success-text:#1e7e34;
    --color-success-bg:#d4edda;
    --color-success-bg-text:#155724;
    --color-danger:#dc3545;
    --color-danger-text:#b02a37;
    --color-danger-bg:#f8d7da;
    --color-danger-bg-text:#721c24;
    --color-warning:#f59f00;
    --color-warning-text:#9c6f00;
    --color-warning-bg:#fff3cd;
    --color-warning-bg-text:#856404;
    --color-info:#0d6efd;
    --color-info-text:#1d4b80;
    --color-info-bg:#d9e7f7;
    --color-info-bg-text:#1d4b80;

    /* Dark mode shades (referenced by body.dark overrides further down) */
    --dark-bg-page:#121212;
    --dark-link:#64b5f6;

    /* Shadows */
    --shadow-sm:0 2px 4px rgba(0, 0, 0, 0.05);
    --shadow-md:0 4px 12px rgba(0, 0, 0, 0.1);
    --shadow-lg:0 8px 24px rgba(0, 0, 0, 0.15);

    /* Borders & motion */
    --border-radius:8px;
    --border-radius-sm:4px;
    --transition:all 0.2s ease-in-out;
    --bg-hover:rgba(78, 107, 132, 0.08);

    /* Typography */
    --font-primary:-apple-system,"BlinkMacSystemFont","Segoe UI","Roboto","Helvetica Neue",Arial,sans-serif;
    --font-size-base:15px;
    --font-size-xs:0.8rem;
    --font-size-lg:1.2rem;
    --font-size-xl:1.5rem;
    --font-size-2xl:2rem;
    --line-height-base:1.3;

    /* Spacing scale (4px base) */
    --spacing-xs:4px;
    --spacing-sm:8px;
    --spacing-md:12px;
    --spacing-lg:16px;
    --spacing-xl:20px;
    --spacing-3xl:32px;

    /* Icons & table */
    --table-cell-padding:5px 8px;

    /* Links */
    --link-color:var(--secondary-color);
    --link-hover-color:var(--text-color);

    /* Card system */
    --card-bg:var(--surface-color);
    --card-border:var(--border-color);
    --card-radius:var(--border-radius);
    --card-shadow:var(--shadow-sm);
    --card-header-bg:linear-gradient(315deg,var(--accent-blue) 0,var(--secondary-color) 100%);

    /* Form controls */
    --control-bg:var(--surface-color);
    --control-border:var(--border-color);

    /* Badges */

    /* Redesign 2026 — ops-room tokens (contract: docs/design/README.md).
     * Dark values in body.dark. */
    --font-display:"Barlow Condensed","Arial Narrow",sans-serif;
    --font-mono:"IBM Plex Mono",ui-monospace,"SF Mono",Menlo,monospace;
    --ground:#eef2f5;              /* page background */
    --panel:#fff;                  /* card surface */
    --panel-2:#f5f8fa;             /* card header strip */
    --hairline:#d7e0e7;
    --hairline-strong:#b9c8d3;
    --signal:#0d6c93;              /* accent (links, active markers); >=4.5:1 on all light panels */
    --signal-soft:rgba(13,108,147,.10);
    --amber:#b36a00;
    --amber-soft:rgba(179,106,0,.12);
    --good:#2e8b47;
    --good-soft:rgba(46,139,71,.12);
    --bad:#be4239;
    --bad-soft:rgba(190,66,57,.10);
    --bar-a:#1a8ab8;
    --bar-b:#4fb3d9;
    --photo-ground:#0d1824;        /* photo/profile backdrop, dark in both themes */
    --shadow-panel:0 1px 2px rgba(24,42,58,.06), 0 8px 24px rgba(24,42,58,.07);
}


/* ============================================================================
 * 02 — BASE & GLOBAL STYLES
 *      Document-level resets: body, headings, links, form-control fonts,
 *      sticky pagination arrow positioning, table primitives. Component
 *      definitions live in their dedicated sections (.card → 03, .actbtn → 13).
 * ============================================================================ */
body,li,p,ul {
    line-height:var(--line-height-base);
}

.breadcrumb-item.active {
    font-weight:600;
}


.pagination li.next a::after,.pagination li.previous a::before {
    top:50%;
    left:50%;
    transform:translate(-50%,-50%);
    position:absolute;
}

.card {
    transition:var(--transition);
}

/* Column flex so .foot is pushed to the viewport bottom on pages too short to
 * fill it (empty states, 404, "not found" comparisons) instead of leaving a
 * band of --ground below the footer. The icon sprite is position:absolute and
 * the AdSense side rails are position:fixed, so neither becomes a flex item;
 * the wargames shell loads only wargame.css and is unaffected. */
body {
    background-color:var(--ground);
    padding:0;
    margin:0;
    color:var(--text-color);
    min-height:100vh;
    display:flex;
    flex-direction:column;
}

/* #page must NOT be the flex item: it centres itself with `margin:0 auto`, and
 * auto margins beat `align-self:stretch`, so as a flex item it would size to its
 * max-content width and overflow narrow viewports. The wrapper takes the flex
 * role and #page keeps its plain block geometry (max-width + auto margins). */
.page-wrap { flex:1 0 auto; min-width:0; }
.foot { flex:none; min-width:0; }

body,input,select,table,textarea {
    font-family:var(--font-primary);
    font-size:var(--font-size-base);
}

/* Redesign 2026: condensed display face for all headings site-wide */
h1,h2,h3 {
    font-family:var(--font-display);
    letter-spacing:.02em;
}

a:link,a:visited {
    color:var(--link-color);
    text-decoration:none;
}

a:active,a:hover,table th a:hover {
    color:var(--link-hover-color);
    text-decoration:underline;
}

/* Anchors inside chrome containers (breadcrumb, table headers, country
 * links, nav-cards) should not be underlined. */
.breadcrumb-item a,
.breadcrumb-item a:hover,
table th a {
    text-decoration:none;
}
.sources a {
    text-decoration:none;
    border-bottom:1px dotted currentColor;
    transition:color 0.2s ease, border-color 0.2s ease;
}
.sources a:hover, .sources a:focus {
    text-decoration:none;
    border-bottom-color:transparent;
}

hr {
    display:block;
    height:1px;
    background:var(--text-color);
    border:0;
}

small {
    font-size:.95em;
}

#page {
    max-width:1200px;
    margin:0 auto;
    background:var(--surface-color);
    padding:var(--spacing-lg);
    border:none;
    box-shadow:var(--shadow-lg);
    border-radius:var(--border-radius);
}

/* Dark mode: add muted surface to containers that are unstyled in light mode. */
body.dark #page,
body.dark table,
body.dark table th {
    background:var(--surface-muted);
}
h1,
h2 {
    position:relative;
}

/* ============================================================================
 * 03 — LAYOUT & CARD SYSTEM
 *      Page wrapper (#page, #content) and the .card / .card-header primitive
 *      with its green/orange/warning header variants. Only the includes that
 *      predate the ops-room components still use .card (faq, ordnance card);
 *      new work builds on .tablecard in section 13.
 * ============================================================================ */

#content {
    padding-bottom:10px;
}

.card {
    background:var(--card-bg);
    border-radius:var(--card-radius);
    box-shadow:var(--card-shadow);
    border:1px solid var(--card-border);
    overflow:hidden;
    margin-bottom:var(--spacing-lg);
    break-inside:avoid;
}

/* NB: body.dark .card / .card-header overrides are not needed here —
 * --card-bg, --card-border, --card-header-bg are all redefined in body.dark
 * so the light-mode rules above already adapt automatically. */
.card-header {
    position:relative;
    padding:var(--spacing-sm) var(--spacing-md) 6px;
    border-bottom:1px solid var(--surface-subtle);
    background:var(--card-header-bg);
    overflow:hidden;
}

.card-header::before {
    content:"";
    position:absolute;
    top:0;
    right:0;
    bottom:0;
    left:0;
    pointer-events:none;
    background:linear-gradient(45deg,rgba(255,255,255,.1) 0,transparent 50%,rgba(255,255,255,.05) 100%);
}

.card-header h2,.card-header h2 a {
    margin:0;
    font-size:1.1em;
    font-weight:600;
    color:var(--color-white);
    border:none;
    background:0 0;
    padding:0;
}

.text-right {
    text-align:right;
}

.breadcrumb::before {
    content:"";
    position:absolute;
    top:0;
    width:4px;
    height:100%;
    background:linear-gradient(180deg,var(--accent-color),var(--secondary-color));
    left:0;
}

#ai-comparison-content h3,
.breadcrumb-item.active {
    color:var(--text-color);
}


#ai-comparison-content h3 {
    background:0 0;
    border:none;
    padding:0;
}

/* --- Forms (used on /suggest/, comparison-hero, etc.) --- */
.breadcrumb-item a {
    color:var(--link-color);
    font-weight:500;
    transition:var(--transition);
}

@media (max-width:576px) {

    .aircraft-list-table th,
    .aircraft-list-table td {
        padding:5px 6px;
    }

    .aircraft-list-table .aircraft-col-country {
        width:56px;
        min-width:56px;
    }

    .aircraft-list-table .aircraft-col-image {
        width:76px!important;
        min-width:76px!important;
    }

    .aircraft-list-table .aircraft-col-built {
        width:72px;
        min-width:72px;
    }

    .aircraft-list-table .aircraft-col-name a,
    .aircraft-list-table .aircraft-col-name {
        overflow-wrap:anywhere;
        word-break:break-word;
    }

    .aircraft-list-table .aircraft-table-image {
        max-width:72px!important;
        max-height:32px!important;
        height:auto;
    }
}

/* --- Global table system (used in many listing pages) --- */
table {
    width:100%;
    overflow-x:auto;
    text-align:left;
    border-spacing:0px;
    border-radius:var(--border-radius);
    box-shadow:var(--shadow-sm);
    overflow:hidden;
    -webkit-text-size-adjust:100%;
    text-size-adjust:100%;
}

table th:first-child {
    border-top-left-radius:var(--border-radius);
}

table th:last-child {
    border-top-right-radius:var(--border-radius);
}

table thead {
    background:var(--surface-subtle);
}

table th {
    padding:var(--table-cell-padding);
    background:var(--surface-subtle);
    color:var(--text-color);
    font-size:var(--font-size-xs);
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:.5px;
}

table th a {
    color:var(--text-color);
}

table td {
    padding:var(--table-cell-padding);
    border-bottom:1px solid var(--surface-subtle);
    transition:background-color .2s;
    -webkit-text-size-adjust:100%;
    text-size-adjust:100%;
}

body.dark table td {
    border-bottom-color:var(--card-border);
}

table tr:hover td {
    background-color:var(--surface-muted);
}

/* --- Breadcrumb --- */
.breadcrumb-container {
    margin-bottom:var(--spacing-md);
}

.breadcrumb {
    position:relative;
    display:flex;
    flex-wrap:wrap;
    list-style:none;
    background:linear-gradient(135deg,var(--surface-muted) 0,rgba(255,255,255,.8) 100%);
    border:1px solid var(--card-border);
    border-radius:var(--border-radius);
    box-shadow:var(--shadow-sm);
    padding:var(--spacing-xs) var(--spacing-md);
    margin-bottom:var(--spacing-lg);
    overflow:hidden;
}

body.dark .breadcrumb {
    background:linear-gradient(135deg,var(--surface-muted) 0,var(--card-border) 100%);
}

.breadcrumb::before {
    border-radius:var(--border-radius-sm) 0 0 var(--border-radius-sm);
}

.breadcrumb-item {
    display:flex;
    align-items:center;
    font-size:.875rem;
}

.breadcrumb-item+.breadcrumb-item {
    padding-left:var(--spacing-sm);
}

.breadcrumb-item+.breadcrumb-item::before {
    display:inline-flex;
    align-items:center;
    justify-content:center;
    padding-right:var(--spacing-sm);
    color:var(--text-muted);
    content:"›";
    font-size:1.1em;
    font-weight:500;
    transition:var(--transition);
}

.breadcrumb-item a {
    background-color:transparent;
    border-radius:var(--border-radius-sm);
    position:relative;
}

.breadcrumb-item a:hover {
    background-color:var(--bg-hover);
    color:var(--primary-color);
    transform:translateY(-1px);
}


.block img,.card img {
    max-width:100%;
    height:auto;
}


@media (max-width:576px) {
    table td {
        padding:5px 4px;
    }

    .mobile-hide {
        display:none;
    }

}

/* ============================================================================
 * 04 — CHARTS & PROGRESS BARS
 *      Legacy bar primitives, still emitted by the django-tables2 renderers:
 *        .barploth               — h:12px, blue gradient, width from --bar-pct
 *        .bar-track              — full-width track wrapping a .barploth
 *        .ordnance-bar-fill      — h:18px, color via --bar-color (section 06)
 *      The ops-room `.bar > i` primitive (section 13) is what page templates use.
 * ============================================================================ */

.barploth {
    height:12px;
    border-radius:4px;
    display:inline-block;
    margin-left:var(--spacing-sm);
    vertical-align:middle;
    background:linear-gradient(90deg,#4e79a7,#a0c4ff);
    width:var(--bar-pct, 0%);
}

.bar-track {
    width:100%;
}

.bar-track .barploth {
    display:block;
    margin-left:0;
}

@media (min-width:769px) {

    .card {
        break-inside:avoid;
    }

}


h1 {
    font-size:var(--font-size-2xl);
    font-weight:600;
    letter-spacing:.01em;
    color:var(--text-color);
    margin:0 0 .75em;
    padding-bottom:.25em;
}

h2,h3 {
    font-size:var(--font-size-lg);
    font-weight:600;
}

h2 {
    color:var(--accent-color);
    margin:1.25em 0 .5em;
    padding:.35em 0 .35em .75em;
    border-left:3px solid var(--accent-color);
    background:linear-gradient(90deg,rgba(0,102,0,.12),transparent);
}

h3 {
    color:var(--text-color);
    margin:1em 0 .4em;
    padding:.3em .5em;
    border-left:4px solid var(--accent-blue);
    border-radius:0 var(--border-radius-sm) var(--border-radius-sm) 0;
    background:linear-gradient(90deg,rgba(137,166,189,.08),transparent);
}

/* ============================================================================
 * 05 — PODIUM MEDALS & TABLE ROW STATES
 *      Ranking podium medal colors + the navy inventory loss-state row tints
 *      (pages/page_navy.html pairs them with the semantic .chip labels).
 * ============================================================================ */

/* Medal colors for ranking podium — desaturated so the numerals stay
 * legible on light panels (raw `gold`/`silver` washed out); the same trio
 * drives the section-13 .podium tiles via --pd-medal. */
.medal-gold { color:#c9a227; }
.medal-silver { color:#8a97a1; }
.medal-bronze { color:#b0763d; }

/* Navy table loss-state row variants. The strike-through belongs to the <s>
 * around the ship name only: on the cell it leaked onto the SUNK chip and the
 * hull number, which read as struck-out data rather than a lost hull. */
.navy-sunk-row { background-color:rgba(220, 53, 69, 0.07); }
.navy-sunk-row td { color:var(--text-muted); }
.navy-retired-row { background-color:rgba(108, 117, 125, 0.07); }
.navy-retired-row td { color:var(--text-muted); }
.navy-captured-row { background-color:rgba(255, 153, 0, 0.07); }
.navy-captured-row td { color:var(--text-muted); }

/* ============================================================================
 * 06 — SHARED PAGE FURNITURE
 *      Pagination, the ordnance scale diagram, country-flag pills and other
 *      cross-page odds and ends that are not ops-room components.
 * ============================================================================ */


/* Pagination — list pages, search results */
.pagination {
    display:flex;
    flex-wrap:wrap;
    justify-content:center;
    align-items:center;
    gap:var(--spacing-xs);
    list-style:none;
    padding:0;
    margin:15px 0;
}

.pagination li {
    flex:0 0 auto;
}

.pagination li a,.pagination li span {
    display:inline-flex;
    align-items:center;
    justify-content:center;
    min-width:32px;
    height:32px;
    padding:0 6px;
    border:1px solid var(--control-border);
    border-radius:var(--border-radius-sm);
    text-decoration:none;
    background-color:var(--control-bg);
    color:var(--text-color);
    font-size:.875rem;
    transition:var(--transition);
}

body.dark .pagination li a,body.dark .pagination li span {
    background-color:var(--control-bg);
    color:var(--text-color);
    border-color:var(--control-border);
}

.pagination li.ellipsis span {
    min-width:auto;
    padding:0 4px;
    border-color:transparent;
    background-color:transparent;
}

.pagination li a:hover {
    background-color:var(--surface-muted);
    border-color:var(--secondary-color);
}

.pagination li.active a,.pagination li.active span {
    background-color:var(--secondary-color);
    border-color:var(--secondary-color);
    color:var(--color-white);
}

.pagination li.next a,.pagination li.previous a {
    min-width:32px;
    width:32px;
    padding:0;
    font-size:1rem;
}

.pagination li.next a span,.pagination li.previous a span {
    display:none;
}

.rank-image {
    height:16px!important;
    padding-right:var(--spacing-xl);
    display:block;
    margin-left:auto;
}


.sources {
    position:relative;
    border:1px solid var(--card-border);
    border-radius:var(--border-radius-sm);
    background:var(--surface-muted);
    padding:var(--spacing-sm) var(--spacing-md);
    margin:var(--spacing-lg) 0;
    font-size:.85em;
    color:var(--text-muted);
}

.sources::before {
    content:"Sources";
    position:absolute;
    top:-8px;
    left:var(--spacing-md);
    padding:0 var(--spacing-xs);
    background:var(--surface-muted);
    color:var(--text-color);
    font-size:.75em;
    font-style:normal;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:.5px;
}

.sources.sources-notice::before {
    content:"Notice";
}

.card+.card {
    margin-top:0;
}

table td img[alt*=category],table td img[src*="categories/"] {
    height:20px!important;
    width:auto;
    margin-right:var(--spacing-sm);
    vertical-align:middle;
}

table td p img[alt*=roundel],table td p img[src*="roundel/"] {
    height:auto!important;
}

.compare-higher {
    background-color:rgba(0,102,0,.1);
}

.compare-lower {
    background-color:rgba(255,0,0,.1);
}

.compare-equal {
    background-color:rgba(0,0,255,.05);
}

/* --- Score badges (power-index, "new" tag) --- */
.power-index-badge {
    display:inline-block;
    background:linear-gradient(135deg, #2c5282 0%, #1a365d 100%);
    color:var(--color-white);
    padding:var(--spacing-xs) 10px;
    border-radius:12px;
    font-size:.85em;
    font-weight:600;
    min-width:45px;
    text-align:center;
}


/* --- Site footer --- */
/* NB: `.footer` itself lives in wargame.css — the only markup using it is
 * wargames/base_wargame.html, which does not load this stylesheet. */

/* Footer link columns (internal navigation) */
.footer-links {
    display:flex;
    flex-wrap:wrap;
    justify-content:center;
    gap:var(--spacing-lg) var(--spacing-3xl);
    margin-bottom:var(--spacing-lg);
    text-align:left;
}

.footer-col {
    display:flex;
    flex-direction:column;
    gap:var(--spacing-xs);
}

.footer-col-title {
    font-weight:600;
    text-transform:uppercase;
    font-size:var(--font-size-xs);
    letter-spacing:.05em;
    margin-bottom:var(--spacing-xs);
}

.footer-col a {
    opacity:.85;
    padding-block:2px;             /* 24px touch target */
}

.footer-col a:hover {
    opacity:1;
    text-decoration:underline;
}

@media (max-width: 576px) {
    .footer-links {
        gap:var(--spacing-md) var(--spacing-xl);
    }
}

/* --- Dark mode token overrides (reactive to body.dark) --- */
body.dark {
    --primary-color:var(--dark-bg-page);
    --secondary-color:var(--dark-link);
    --accent-color:#acb632;
    --accent-blue:var(--dark-link);
    --text-color:#e4edf4;
    --text-muted:#8ba1b3;
    --light-gray:#495057;
    --border-color:#495057;
    --bg-gray:#343a40;
    --bg-hover:rgba(255, 255, 255, 0.1);
    --surface-color:var(--bg-gray);
    --surface-muted:var(--bg-gray);
    --surface-subtle:var(--light-gray);
    --link-color:var(--secondary-color);
    --link-hover-color:var(--text-color);
    --card-bg:var(--bg-gray);
    --card-border:var(--border-color);
    --card-header-bg:linear-gradient(315deg,#6a7d8a 0,#3e5762 100%);
    --control-bg:var(--bg-gray);
    --control-border:var(--border-color);
    /* Semantic backgrounds in dark mode (solid colors remain readable as-is) */
    --color-success-bg:#1f3b1c;
    --color-success-bg-text:#cde8c8;
    --color-danger-bg:#3b1c1f;
    --color-danger-bg-text:#f2c8cb;
    --color-warning-bg:#3a3018;
    --color-warning-bg-text:#f0d99e;
    --color-info-bg:#1c2f46;
    --color-info-bg-text:#bcd5f2;
    /* Redesign 2026 — ops-room tokens, dark values */
    --ground:#0c1621;
    --panel:#121f2d;
    --panel-2:#172736;
    --hairline:#233749;
    --hairline-strong:#31485d;
    --signal:#54c3ea;
    --signal-soft:rgba(84,195,234,.12);
    --amber:#efa22e;
    --amber-soft:rgba(239,162,46,.14);
    --good:#4cb765;
    --good-soft:rgba(76,183,101,.16);
    --bad:#e0655c;
    --bad-soft:rgba(224,101,92,.14);
    --bar-a:#2f9ec9;
    --bar-b:#6fd0f2;
    --shadow-panel:0 1px 2px rgba(0,0,0,.3), 0 10px 30px rgba(0,0,0,.35);
    background:var(--ground);
    color:var(--text-color);
}

/* --- Utility classes (visibility, alignment, layout helpers) --- */
.spinner-border {
    display:inline-block;
    width:2rem;
    height:2rem;
    vertical-align:-.125em;
    border:.25em solid currentColor;
    border-right-color:transparent;
    border-radius:50%;
    animation:.75s linear infinite spinner-border;
}

@keyframes spinner-border {
    0% {
        transform:rotate(0);
    }

    100% {
        transform:rotate(360deg);
    }

}

.text-primary {
    color:var(--primary-color)!important;
}

.sr-only {
    position:absolute!important;
    width:1px!important;
    height:1px!important;
    padding:0!important;
    margin:-1px!important;
    overflow:hidden!important;
    clip:rect(0,0,0,0)!important;
    white-space:nowrap!important;
    border:0!important;
}

.text-center {
    text-align:center!important;
}

.is-hidden {
    display:none;
}

.flex-center {
    display:flex;
    justify-content:center;
}

.ai-comparison-loading {
    padding:2rem;
}

.ai-comparison {
    line-height:1.6;
    margin-bottom:1rem;
}

.alert {
    border:1px solid var(--card-border);
    border-radius:var(--border-radius-sm);
    padding:var(--spacing-md);
    margin-bottom:var(--spacing-md);
}

.alert-warning {
    background:rgba(232,134,12,.12);
    border-color:rgba(194,89,10,.35);
    color:var(--text-color);
}

@media (max-width:576px) {
}


/* ============================================================================
 * 07 — NAVIGATION
 *      Navbar, dropdowns (desktop hover, mobile click), mobile menu trigger.
 *      Sub-sections marked below (main / active / dropdown / arrows / mobile).
 *      The navbar only ever renders inside <header class="cmd"> (section 12),
 *      which is dark in BOTH themes — so it needs no body.dark variant, and
 *      adding one would outrank the shell rules and break dark pages.
 * ============================================================================ */

/* ========================= NAVIGATION MAIN STRUCTURE ============================ */
.nav {
    background:linear-gradient(135deg, #2a3f54 0%, #2e70a7 100%);
    padding:0;
    margin:0;
    border-top:1px solid rgba(255,255,255,0.15);
    box-shadow:var(--shadow-md);
    position:relative;
    z-index:10;
    backdrop-filter:blur(10px);
}

.nav-list {
    list-style-type:none;
    padding:0;
    margin:0;
    display:flex;
}

.nav-list__item {
    margin:0;
    position:relative;
}

.nav-list__link {
    text-decoration:none;
    color:#fff !important;
    padding:var(--spacing-sm) 22px 11px 22px;
    display:flex;
    align-items:center;
    transition:all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    font-weight:500;
    position:relative;
    overflow:hidden;
    text-shadow:0 1px 2px rgba(0,0,0,0.3);
    border-radius:var(--border-radius-sm);
    margin:0 1px;
    border-top:3px solid transparent;
}

.nav-list__link:hover {
    background:linear-gradient(135deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.05) 100%);
    border-top:3px solid var(--accent-color-light);
}

/* ============================== ACTIVE STATE STYLING ============================ */
.nav-list__link.is-active {
    background:linear-gradient(135deg, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.05) 100%);
    font-weight:600;
    border-top:3px solid transparent;
    border-image:linear-gradient(90deg, var(--accent-color-light), var(--accent-color)) 1;
}

/* ============================ DROPDOWN MENU STYLING ============================= */
.nav-dropdown {
    position:relative;
}

.nav-dropdown__menu {
    position:absolute;
    top:100%;
    left:0;
    background:linear-gradient(135deg, rgba(255,255,255,0.95) 0%, rgba(248,249,250,0.98) 100%);
    backdrop-filter:blur(12px);
    min-width:200px;
    box-shadow:var(--shadow-lg);
    opacity:0;
    visibility:hidden;
    transform:translateY(-10px);
    transition:all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    border-radius:var(--border-radius);
    border:1px solid var(--border-color);
    z-index:100;
    list-style-type:none;
    padding:0;
    margin:0;
    overflow:hidden;
}

/* The last dropdown hugs the right edge once the search box collapses
   (~800-900px); its closed menu still occupies layout (visibility:hidden),
   so left-anchoring it widens document.scrollWidth past the viewport. */
.nav-list__item:last-child .nav-dropdown__menu {
    left:auto;
    right:0;
}

.nav-dropdown__item {
    width:100%;
    border-bottom:1px solid var(--border-color);
    margin:0;
    padding:0;
}

.nav-dropdown__item:last-child {
    border-bottom:none;
}

.nav-dropdown__link {
    padding:9px 20px;
    display:block;
    color:var(--text-color) !important;
    font-weight:normal;
    position:relative;
    text-shadow:none;
    transition:all 0.3s ease;
    border-radius:0;
    margin:0;
    border-left:3px solid transparent;
}

.nav-dropdown__link:hover {
    background:linear-gradient(90deg, rgba(78, 107, 132, 0.08), transparent);
    color:var(--primary-color) !important;
    border-left:3px solid var(--accent-color-light);
    transform:none;
    margin:0;
}

.nav-dropdown__link.is-active {
    background:linear-gradient(90deg, rgba(78, 107, 132, 0.12), transparent);
    font-weight:600;
    color:var(--primary-color) !important;
    border-left:3px solid transparent;
    border-image:linear-gradient(180deg, var(--accent-color), var(--accent-color-light)) 1;
}

@media screen and (min-width: 769px) {
    .nav-dropdown:hover .nav-dropdown__menu {
        opacity:1;
        visibility:visible;
        transform:translateY(0);
    }
}

/* ========================= DROPDOWN TOGGLE ARROWS =============================== */
.nav-dropdown__toggle {
    text-decoration:none !important;
}

.nav-dropdown__toggle:hover {
    text-decoration:none !important;
}

.nav-dropdown__toggle::after {
    content:" ▶";
    font-size:10px;
    margin-left:5px;
    transition:transform 0.3s;
    display:inline-block;
    vertical-align:middle;
    opacity:0.8;
    text-decoration:none;
}

.nav-dropdown__toggle:hover::after,
.nav-dropdown__toggle.is-active::after {
    transform:rotate(90deg);
    opacity:1;
    text-decoration:none;
}

/* =========================== MOBILE MENU STYLING ================================ */
.nav-mobile__toggle {
    display:none;
}

/* Mobile search reveal: checkbox always hidden, its magnifier label only
   shows in the shell's mobile header (see the .cmd media block). */
.nav-search__toggle,
.nav-search__icon {
    display:none;
}

.nav-mobile__icon {
    height:20px;
    flex-direction:column;
    justify-content:space-between;
    cursor:pointer;
    display:none;
    padding:10px;

}

.nav-mobile__title {
    display:none;
    color:var(--color-white);
    font-size:var(--font-size-xl);
    margin-left:15px;
    flex-grow:1;
}

.nav-mobile__title a {
    color:#fff !important;
    text-decoration:none;
}

.nav-mobile__bar {
    background-color:#e6e6e6;
    height:2px;
    width:25px;
    border-radius:2px;
    transition:all 0.3s ease;
}

@media screen and (max-width: 768px) {
    .nav {
        display:flex;
        align-items:center;
        padding:0 10px;
    }
    .nav-mobile__icon,
    .nav-mobile__toggle:checked ~ .nav-list {
        display:flex;
    }
    .nav-mobile__title,
    .nav-dropdown__menu.is-visible {
        display:block;
    }
    .nav-dropdown__toggle::after {
        font-size:10px;
    }

    .nav-list {
        display:none;
        width:100%;
        max-width:250px;
        text-align:left;
        position:absolute;
        top:100%;
        left:0;
        background:linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
        flex-direction:column;
        z-index:100;
        box-shadow:0 5px 10px rgba(0,0,0,0.2);
        border-radius:0 0 5px 0;
    }
    .nav-mobile__toggle:checked + .nav-mobile__icon .nav-mobile__bar:nth-child(1) {
        transform:rotate(45deg) translate(6px, 6px);
    }
    .nav-mobile__toggle:checked + .nav-mobile__icon .nav-mobile__bar:nth-child(2) {
        opacity:0;
    }
    .nav-mobile__toggle:checked + .nav-mobile__icon .nav-mobile__bar:nth-child(3) {
        transform:rotate(-45deg) translate(6px, -6px);
    }
    .nav-list__item {
        width:100%;
        border-bottom:1px solid rgba(255,255,255,0.1);
    }
    .nav-list__item:last-child {
        border-bottom:none;
    }
    .nav-dropdown__menu {
        position:static;
        display:none;
        width:100%;
        max-width:100%;
        opacity:1;
        visibility:visible;
        transform:none;
        box-shadow:none;
        background:rgba(255, 255, 255, 0.7);
        list-style-type:none;
        padding:0;
        margin:0;
    }
    .nav-dropdown__item {
        padding-left:0;
    }
    .nav-dropdown__link {
        padding:7px 20px 7px 25px;
        font-size:0.95em;
    }
    .nav-dropdown__link::after {
        width:3px;
        left:0;
        height:100%;
    }
    .nav-dropdown__menu .nav-dropdown__menu {
        background:rgba(0,0,0,0.2);
        border-radius:0;
    }
    .nav-dropdown__menu .nav-dropdown__link {
        padding-left:35px;
    }
}

/* ============================================================================
 * 08 — HEADER SEARCH BOX
 *      The search field inside the navbar. The /search/ results page itself
 *      is built from ops-room components (section 13).
 * ============================================================================ */

/* Custom Search Form Styling */
.search-box {
    float:right !important;
    margin-left:auto !important;
    display:flex !important;
    align-items:center !important;
    height:40px !important; /* Match navbar height */;
}

.search-box form {
    display:flex;
    align-items:center;
    background:transparent;
    border:none;
    margin:0px 15px 0 0;
    padding:0;
    height:100%;
    position:relative;
}

.search-box input[type="search"] {
    background:rgba(255, 255, 255, 0.1) !important;
    border:none !important;
    border-radius:4px !important;
    height:32px !important;
    min-height:32px !important;
    font-size:14px !important;
    padding:6px 35px 6px 8px !important;
    color:rgba(255, 255, 255, 0.9) !important;
    outline:none;
    width:150px;
    transition:all 0.2s ease;
}

.search-box input[type="search"]:hover,
.search-box input[type="search"]:focus {
    background:rgba(255, 255, 255, 0.1) !important;
    border-color:rgba(255, 255, 255, 0.5) !important;
}

.search-box input[type="search"]::placeholder {
    color:rgba(255, 255, 255, 0.6) !important;
}

.search-box button[type="submit"] {
    background:transparent !important;
    border:none !important;
    position:absolute;
    right:4px;
    top:50%;
    transform:translateY(-50%);
    padding:var(--spacing-xs) !important;
    height:24px !important;
    width:24px !important;
    cursor:pointer;
    color:rgba(255, 255, 255, 0.7);
    transition:all 0.2s ease;
    z-index:1;
}

.search-box button[type="submit"]:hover {
    color:rgba(255, 255, 255, 1);
}

.search-box button[type="submit"] svg {
    display:block;
    width:16px;
    height:16px;
}

@media (max-width: 992px) {
    .search-box {
        float:none !important;
        margin:0 auto !important;
        position:absolute;
        right:10px;
        top:0px;
        z-index:200;
        background:transparent;
    }
    .search-box form {
        background:transparent;
    }
    .search-box input[type="search"] {
        width:30vw;
        max-width:100px;
        font-size:1em;
        text-align:right;
    }
}

@media (max-width: 992px) and (min-width: 769px) {
    .search-box {
        display:none !important;
    }
}

/* Country typeahead dropdown (search-suggest.js). Anchored to the form,
   right-aligned so it grows leftward from the narrow input. Same panel
   language as the .cmd sub-menus (deep navy, cyan hairline); the shell is
   dark in both themes, so there is no dark variant to write. Suggestions are
   data, not nav labels, so they keep the body font and sentence case. */
.search-suggest {
    position:absolute;
    top:100%;
    left:auto;
    right:0;
    margin:4px 0 0;
    padding:0;
    list-style:none;
    width:max-content;
    min-width:220px;
    max-width:75vw;
    background:linear-gradient(180deg, #0a1826, #071019);
    border:1px solid rgba(0,190,255,.3);
    border-radius:0 0 2px 2px;
    box-shadow:0 18px 34px rgba(0,0,0,.45);
    overflow:hidden;
    z-index:200;
}
.search-suggest__item { border-bottom:1px solid rgba(255,255,255,.07); }
.search-suggest__item:last-child { border-bottom:none; }
.search-suggest__item a {
    display:flex;
    align-items:center;
    gap:8px;
    padding:8px 14px;
    color:#b9cddd;
    text-decoration:none;
    font-size:14px;
    white-space:nowrap;
    border-left:2px solid transparent;
}
.search-suggest__item.is-active a,
.search-suggest__item a:hover {
    background:rgba(84,195,234,.1);
    border-left-color:rgba(84,195,234,.6);
    color:#fff;
}
/* ============================================================================
 * 09 — FAQ ACCORDION
 *      Pure-CSS <details> accordion (no JS). Used on detail/comparison pages
 *      with FAQPage schema.
 * ============================================================================ */

/* FAQ Accordion - pure CSS, no JS */
.faq-accordion {
    padding:var(--spacing-sm) 16px 16px;
}
.faq-item {
    border:1px solid var(--card-border);
    border-radius:var(--border-radius-sm);
    margin-bottom:var(--spacing-sm);
    background:var(--surface-muted);
}
.faq-item:last-child {
    margin-bottom:0;
}
.faq-item summary {
    cursor:pointer;
    font-weight:600;
    padding:var(--spacing-md) 16px;
    list-style:none;
    display:flex;
    justify-content:space-between;
    align-items:center;
    transition:background-color 0.2s ease;
    border-radius:var(--border-radius-sm);
}
.faq-item summary::-webkit-details-marker {
    display:none;
}
.faq-item summary::after {
    content:"+";
    font-size:1.3em;
    font-weight:400;
    color:var(--text-muted);
    flex-shrink:0;
    margin-left:var(--spacing-md);
}
.faq-item[open] summary::after {
    content:"−";
}
.faq-item summary:hover {
    background-color:rgba(0, 0, 0, 0.03);
}
.faq-answer {
    padding:0 16px 14px;
    color:var(--text-muted);
    line-height:1.6;
}
body.dark .faq-item {
    background:var(--bg-hover);
}
body.dark .faq-item summary:hover {
    background-color:rgba(255, 255, 255, 0.05);
}
.ordnance-visual {
    display:flex;
    justify-content:center;
}
.ordnance-visual-svg {
    width:auto;
    max-width:100%;
    height:auto;
    display:block;
}
.ordnance-separator {
    height:1px;
    background:var(--surface-subtle);
    margin:var(--spacing-sm) 0 14px;
}
.ordnance-bars {
    display:grid;
    gap:var(--spacing-md);
}
.ordnance-bar-row {
    display:grid;
    grid-template-columns:110px minmax(0,1fr) 120px;
    align-items:center;
    gap:14px;
}
.ordnance-bar-label,.ordnance-bar-value,.dim-label {
    fill:var(--text-color);
    font-family:var(--font-primary);
}
.ordnance-bar-label,.ordnance-bar-value {
    color:var(--text-color);
    font-size:var(--font-size-base);
    font-weight:400;
    line-height:1.2;
}
.ordnance-bar-label {
    text-align:right;
}
.ordnance-bar-value {
    text-align:right;
    white-space:nowrap;
}
.ordnance-bar-track {
    width:100%;
    height:18px;
    background:var(--surface-subtle);
    border-radius:6px;
    overflow:hidden;
}
.ordnance-bar-fill {
    height:100%;
    border-radius:6px;
    width:var(--bar-pct, 0%);
    background:var(--bar-color, var(--primary-color));
}
.anno-line {
    stroke:#9CA3AF;
    stroke-width:0.8;
}
.human-fig {
    fill:#9CA3AF;
    stroke:#9CA3AF;
    stroke-linecap:round;
    stroke-linejoin:round;
}
.human-shadow {
    fill:#000;
    fill-opacity:0.09;
}
body.dark .ordnance-separator {
    background:#4b5563;
}
body.dark .ordnance-bar-track {
    background:#374151;
}
body.dark .ordnance-bar-label,body.dark .ordnance-bar-value,body.dark .dim-label {
    fill:#d1d5db;
}
body.dark .ordnance-bar-label,body.dark .ordnance-bar-value {
    color:#d1d5db;
}
body.dark .anno-line {
    stroke:#4b5563;
}
body.dark .human-fig {
    fill:#6b7280;
    stroke:#6b7280;
}
body.dark .human-shadow {
    fill:#000;
    fill-opacity:0.28;
}
@media (max-width:576px) {
    .ordnance-bar-row {
        grid-template-columns:90px minmax(0,1fr) 88px;
        gap:10px;
    }
}

/* ============================================================================
 * 10 — ADMIN UI
 *      Django admin: importjob change form (diff filter badges, diff tables,
 *      bulk inputs) + Wikipedia autofill section. Admin-only, low traffic.
 * ============================================================================ */

/* Admin: importjob change form */
.import-help { margin:0 0 var(--spacing-md) 0; }
.import-row-flex {
    display:flex;
    align-items:center;
    gap:var(--spacing-md);
}
.import-summary-row { margin-bottom:var(--spacing-md); }
.import-summary-row h3 { margin:0 0 10px 0; }
.import-summary-bar {
    display:flex;
    justify-content:space-between;
    align-items:center;
    flex-wrap:wrap;
    gap:10px;
}
.import-filters { display:flex; gap:10px; }

.import-bulk-actions {

    display:flex;

    gap:var(--spacing-sm);

    align-items:center;

}
.import-bulk-actions label { font-size:12px; white-space:nowrap; }
.import-bulk-input {
    padding:var(--spacing-xs) var(--spacing-sm);
    border:1px solid #ccc;
    border-radius:3px;
    width:150px;
}
.import-bulk-btn { padding:var(--spacing-xs) var(--spacing-md); font-size:12px; }
.import-bulk-btn--save { background:#417690; color:#fff; }
.import-bulk-divider { margin-left:10px; color:#ccc; }
.import-save-status { font-size:11px; }

.diff-filter-badge {
    display:inline-flex;
    align-items:center;
    font-size:12px;
    padding:var(--spacing-xs) 10px;
    border-radius:3px;
    cursor:pointer;
    user-select:none;
    border:1px solid;
}
.diff-filter-badge input[type="checkbox"] {
    width:14px;
    height:14px;
    margin-right:var(--spacing-xs);
}
.diff-filter-badge--added { background:var(--color-success-bg); border-color:var(--color-success); }
.diff-filter-badge--deleted { background:var(--color-danger-bg); border-color:var(--color-danger); }
.diff-filter-badge--modified { background:var(--color-warning-bg); border-color:var(--color-warning); }
.diff-filter-badge--unchanged { background:var(--light-gray); border-color:var(--text-muted); }

.import-table-wrapper {

    max-height:500px;

    overflow:auto;

    border:1px solid #ccc;

}
.import-table-wrapper--short { max-height:400px; }
.import-table {
    width:100%;
    border-collapse:collapse;
    font-size:11px;
}
.import-table--lg { font-size:12px; }
.import-table thead tr {
    background:#417690;
    color:#fff;
    position:sticky;
    top:0;
}
.import-table thead th { padding:6px; text-align:left; }
.import-table--lg thead th { padding:var(--spacing-sm); }
.import-table tbody td { padding:5px; }
.import-table--lg tbody td { padding:6px; }
.import-table tbody tr { border-bottom:1px solid #ddd; }
.import-table tr.diff-added { background:var(--color-success-bg); }
.import-table tr.diff-deleted { background:var(--color-danger-bg); }
.import-table tr.diff-modified { background:var(--color-warning-bg); }
.import-table tr.diff-unchanged { background:#f9f9f9; }
.import-table tbody tr.zebra:nth-child(even) { background:#f9f9f9; }

.import-cell--center { text-align:center; }
.import-cell--right { text-align:right; }
.import-cell--tight { padding:2px; }
.import-cell--meta { font-size:10px; color:#666; }
.import-cell--breakall { word-break:break-all; }
.import-cell--w60 { width:60px; }
.import-cell--w70 { width:70px; }
.import-cell--w100 { width:100px; }
.import-cell--w140 { width:140px; }
.import-cell--w160 { width:160px; }
.import-cell--w30 { width:30px; }

.import-status-text { font-weight:bold; }
.import-status-text--add { color:var(--color-success-bg-text); }
.import-status-text--del { color:var(--color-danger-bg-text); }
.import-status-text--mod { color:var(--color-warning-bg-text); }
.import-status-text--eq { color:var(--text-muted); font-weight:normal; }

.import-old-value { color:var(--color-danger-bg-text); font-size:9px; }
.import-old-value--right { text-align:right; }
.import-new-value { color:var(--color-success-bg-text); }

.import-input {

    width:100%;

    padding:2px var(--spacing-xs);

    border:1px solid #ddd;

    border-radius:2px;

    font-size:11px;

    box-sizing:border-box;

}
.import-input--right { text-align:right; }

.import-confidence-inherited { color:#6f42c1; }
.import-confidence-exact { color:var(--color-success-bg-text); }
.import-confidence-alt { color:var(--color-info); }
.import-confidence-fuzzy { color:#fd7e14; }
.import-confidence-link { text-decoration:none; }
.import-no-suggestion { color:#aaa; }

.btn-delete-af-row {
    padding:0 var(--spacing-xs);
    font-size:11px;
    cursor:pointer;
    background:var(--color-danger-bg);
    border:1px solid var(--color-danger);
    color:var(--color-danger-bg-text);
    border-radius:3px;
}
.btn-restore-ship,
.btn-reject-ship {
    margin-left:5px;
    padding:0 var(--spacing-xs);
    font-size:9px;
    cursor:pointer;
    border-radius:3px;
}
.btn-restore-ship { background:var(--light-gray); border:1px solid var(--text-muted); }
.btn-reject-ship {
    background:var(--color-danger-bg);
    border:1px solid var(--color-danger);
    color:var(--color-danger-bg-text);
}
.ship-rejected { color:var(--text-muted); font-style:italic; }
.import-action-button--approve { background-color:#417690; color:#fff; }
.import-action-button--reject { background-color:#ba2121; color:#fff; }

#import-actions-section button,
#final-actions-section button {
    padding:10px 20px;
    cursor:pointer;
    font-size:14px;
}
#import-actions-section button:disabled,
#final-actions-section button:disabled { opacity:0.5; cursor:not-allowed; }
#fetch-status, #action-status { font-weight:bold; }

.import-error-fieldset { background-color:#ffdddd; }
.import-error-message { white-space:pre-wrap; color:#a00; }

/* Admin: Wikipedia autofill section (shared across aircraft/ship/vehicle/missile/firearm/airbase change forms) */
.autofill-url-input { width:500px; padding:6px; }
.autofill-btn-inline { margin-left:10px; }
.autofill-row-mt { margin-top:var(--spacing-md); }
.autofill-row-mt-lg { margin-top:15px; }
.autofill-btn-spaced { margin-right:10px; }
.autofill-status { font-weight:bold; }
.autofill-preview { display:none; margin-top:15px; }
.autofill-preview-title { margin-bottom:5px; }
.autofill-preview-pre {
    max-height:200px;
    overflow:auto;
    background:#f5f5f5;
    padding:10px;
    border:1px solid #ccc;
    white-space:pre-wrap;
    font-size:12px;
}
#wikipedia-autofill-section button,
#description-generator-section button { padding:var(--spacing-sm) var(--spacing-lg); cursor:pointer; }
#wikipedia-autofill-section button:disabled,
#description-generator-section button:disabled { opacity:0.5; cursor:not-allowed; }
#wikipedia-autofill-section button.loading,
#description-generator-section button.loading { opacity:0.7; }
.field-highlighted { background-color:#ffffcc !important; }
.generator-actions {
    display:flex;
    flex-wrap:wrap;
    gap:10px;
    align-items:center;
}
/* ============================================================================
 * 11 — LEAFLET MAPS
 *      Map containers, markers and popups: the conflict events map
 *      (list_conflict.html) and the airbases maps (includes/airbases_map.html).
 * ============================================================================ */

/* Conflict listing page (list_conflict.html) */
.conflict-events-map { height:460px; z-index:0; }
/* Dark mode: dim the (always-light) OSM tiles a notch so the map stops being
   the one glowing rectangle on the page; a full invert mangles OSM colors. */
body.dark .conflict-events-map .leaflet-tile { filter:brightness(0.82) saturate(0.85); }
.timeline-show-more { text-align:center; margin-bottom:var(--spacing-xl); }

.conflict-marker-icon {
    font-size:15px;
    /* fixed ink: the roundel sits on light map tiles in both themes */
    color:#22303f;
    background:rgba(255,255,255,0.85);
    border:1px solid rgba(0,0,0,0.2);
    border-radius:50%;
    width:26px;
    height:26px;
    display:flex;
    align-items:center;
    justify-content:center;
}
/* Imprecise geolocation (region / sea precision): dashed halo around the roundel */
.conflict-marker-icon.imprecise { box-shadow:0 0 0 4px rgba(34,48,63,0.12); border-style:dashed; }
.conflict-popup { line-height:1.35; }
.conflict-popup-title { font-weight:600; }
.conflict-popup-date { font-family:var(--font-mono); font-size:10px; color:#5c6a78; margin-top:2px; }
.conflict-popup-location { margin-top:var(--spacing-xs); }
.conflict-popup-link { margin-top:6px; }

/* Map controls under the conflict events map: domain chips, replay button,
 * per-period activity histogram and time slider. Chips share the .console
 * chip primitive (selector extended there). */
.mapctl {
    padding:10px 12px 8px;
    border-top:1px solid var(--hairline);
}
.mapctl-row {
    display:flex;
    align-items:center;
    flex-wrap:wrap;
    gap:10px;
    margin-bottom:8px;
}
.mapctl .chips { display:flex; gap:6px; }
.mapctl .mapctl-date { margin-left:auto; }
.mapctl input[type="range"] {
    display:block;
    width:100%;
    margin:2px 0 0;
    accent-color:var(--signal);
}
/* Activity histogram: one <i> per time bucket, height set by JS from the
 * bucket's event count; .off = past the slider cutoff. */
.mapbars {
    display:flex;
    align-items:flex-end;
    gap:2px;
    height:34px;
}
.mapbars i {
    flex:1;
    min-height:2px;
    background:var(--signal);
    border-radius:1px 1px 0 0;
    opacity:.85;
}
.mapbars i.off { opacity:.22; }
.mapctl-scale {
    display:flex;
    justify-content:space-between;
    font-family:var(--font-mono);
    font-size:10px;
    color:var(--text-muted);
    margin-top:2px;
}
.mapctl-play {
    font-family:var(--font-mono);
    font-size:11px;
    font-weight:500;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text-muted);
    border:1px solid var(--hairline-strong);
    border-radius:6px;
    background:transparent;
    padding:5px 11px;
    cursor:pointer;
    white-space:nowrap;
}
.mapctl-play:hover { border-color:var(--signal); color:var(--text-color); }
.mapctl-date {
    font-family:var(--font-mono);
    font-size:10px;
    color:var(--text-muted);
    white-space:nowrap;
}

/* Airbases world map */
.airbases-map { height:500px; margin-top:2em; }
.airbases-map--compact { height:450px; }
.airbase-marker-flag { font-size:18px; text-shadow:1px 1px 2px rgba(0,0,0,0.5); }
.airbase-popup { line-height:1.4; }
.airbase-popup-title { font-weight:bold; }

.airbase-popup-link { margin-top:var(--spacing-xs); }


/* ============================================================================
 * 12 — SITE SHELL
 *      Ops-room header (.cmd) and footer (.foot), shared by BOTH themes:
 *      they stay dark in light and dark mode (identity choice). The navbar
 *      keeps its markup (navigation.html) and is restyled to sit inside .cmd.
 *      Reference: docs/design/README.md.
 * ============================================================================ */

/* Inline SVG icon sprite (includes/icons.svg) */
.icon-sprite { position:absolute; }
svg.ic {
    width:1.05em;
    height:1.05em;
    vertical-align:-0.16em;
    stroke:currentColor;
    fill:none;
    stroke-width:1.7;
    stroke-linecap:round;
    stroke-linejoin:round;
    flex:none;
}

/* ------------------------------ Header ------------------------------ */
/* Pinned at every width so the menu stays one click away. Under 768px the
 * header is already a single 58px row and sticks whole; on desktop it is 118px,
 * too much to keep on screen, so it scrolls up by the height of the wordmark
 * row and only the 45px menu strip stays (see the min-width:769px block). The
 * scroll-padding on <html> keeps in-page anchors (#by-country, #cat-*) from
 * landing underneath whatever is pinned. */
.cmd {
    position:sticky;
    top:0;
    z-index:50;
    background:
        /* Diagonal scanlines */
        repeating-linear-gradient(135deg, transparent, transparent 3px, rgba(0,180,255,.05) 3px, rgba(0,180,255,.05) 5px),
        /* Radar rings + blip, right side */
        radial-gradient(circle at 88% 40%, transparent 34px, rgba(0,200,255,.14) 35px, transparent 36.5px),
        radial-gradient(circle at 88% 40%, transparent 62px, rgba(0,200,255,.10) 63px, transparent 64.5px),
        radial-gradient(circle at 88% 40%, transparent 92px, rgba(0,200,255,.07) 93px, transparent 94.5px),
        radial-gradient(circle 3px at 88% 40%, rgba(0,255,210,.85), rgba(0,255,210,.25) 60%, transparent),
        /* Deep navy base */
        linear-gradient(135deg, #060d16 0%, #0a1826 45%, #0c2033 75%, #060d16 100%);
    border-bottom:1px solid rgba(0,190,255,.35);
    color:#e8f1f8;
}
html { scroll-padding-top:64px; }
.cmd-inner {
    max-width:1200px;
    margin:0 auto;
    padding:18px 16px 0;
}
.cmd-top {
    display:flex;
    align-items:center;
    gap:18px;
    flex-wrap:wrap;
}
.wordmark {
    font-family:var(--font-display);
    font-weight:600;
    font-size:27px;
    letter-spacing:.045em;
    text-transform:uppercase;
    color:#fff;
    border:2px solid rgba(255,255,255,.85);
    border-radius:2px;
    padding:1px 12px 3px;
    white-space:nowrap;
}
.wordmark a { color:#fff !important; }
.wordmark a:hover { text-decoration:none; }
.wordmark .net { color:#54c3ea; }
.cmd-tag {
    font-family:var(--font-mono);
    font-size:10.5px;
    letter-spacing:.22em;
    color:#6f8ca3;
    text-transform:uppercase;
}
.cmd-tags { display:inline-flex; flex-direction:column; gap:4px; }
.cmd-sub { display:inline-flex; align-items:center; gap:7px; }
.cmd-sub .dot {
    width:6px;
    height:6px;
    border-radius:50%;
    background:#2ec27e;
    animation:pulse 2.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .cmd-sub .dot { animation:none !important; } }

/* Theme toggle — icon button at the right end of .cmd-top, before the mobile
 * search magnifier. Moon in light mode, sun in dark mode; the shell stays
 * dark in both themes so the colors are fixed, only the glyph swaps. */
.cmd .theme-toggle {
    display:flex;
    align-items:center;
    margin-left:auto;
    padding:8px;
    color:#b9cddd;
    background:none;
    border:0;
    cursor:pointer;
}
.cmd .theme-toggle:hover { color:#fff; }
.cmd .theme-toggle .ic-sun { display:none; }
body.dark .cmd .theme-toggle .ic-sun { display:block; }
body.dark .cmd .theme-toggle .ic-moon { display:none; }

/* Navbar restyled to sit inside the dark shell */
.cmd .nav {
    background:transparent;
    box-shadow:none;
    backdrop-filter:none;
    border-top:1px solid rgba(255,255,255,.08);
    margin-top:12px;
}
.cmd .nav-mobile__title { display:none; }
.cmd .nav-list__link {
    font-family:var(--font-display);
    font-weight:500;
    font-size:16.5px;
    letter-spacing:.05em;
    text-transform:uppercase;
    color:#b9cddd !important;
    text-shadow:none;
    border-top:none;
    border-radius:0;
    margin:0;
    padding:9px 14px 10px;
    border-bottom:2px solid transparent;
}
.cmd .nav-list__link:hover {
    background:none;
    border-top:none;
    color:#fff !important;
    border-bottom-color:rgba(84,195,234,.5);
}
.cmd .nav-list__link.is-active {
    background:none;
    border-top:none;
    border-image:none;
    font-weight:600;
    color:#fff !important;
    border-bottom-color:#54c3ea;
}
/* Sub-menus. The legacy dropdown is a white blurred card with a green rail —
 * a light-mode artefact hanging off the dark shell. Same panel language as
 * .cmd instead: deep navy, cyan hairline, square corners, and the top-level
 * link's display type one notch down. The shell stays dark in both themes, so
 * there is no dark variant to write — a body.dark rule here would carry a type
 * selector, outrank these, and render the sub-menus grey on dark pages. */
.cmd .nav-dropdown__menu {
    background:linear-gradient(180deg, #0a1826, #071019);
    backdrop-filter:none;
    border:1px solid rgba(0,190,255,.3);
    border-top:none;
    border-radius:0 0 2px 2px;
    box-shadow:0 18px 34px rgba(0,0,0,.45);
    min-width:212px;
}
.cmd .nav-dropdown__item { border-bottom:1px solid rgba(255,255,255,.07); }
.cmd .nav-dropdown__item:last-child { border-bottom:none; }
.cmd .nav-dropdown__link {
    font-family:var(--font-display);
    font-weight:500;
    font-size:14px;
    letter-spacing:.05em;
    text-transform:uppercase;
    color:#b9cddd !important;
    padding:10px 16px;
    border-left:2px solid transparent;
    border-image:none;
}
.cmd .nav-dropdown__link:hover {
    background:rgba(84,195,234,.1);
    border-left-color:rgba(84,195,234,.6);
    color:#fff !important;
}
.cmd .nav-dropdown__link.is-active {
    background:rgba(84,195,234,.14);
    border-image:none;
    border-left-color:#54c3ea;
    font-weight:600;
    color:#fff !important;
}
/* Icon-less top menu: even rhythm from a flex gap + slim link padding; first
 * link aligns with the wordmark's left edge (desktop only — mobile keeps the
 * full-width burger panel). The gap widens on large viewports; the tablet range
 * keeps a tighter one so the six items never overflow the single nowrap row. */
@media screen and (min-width: 769px) {
    .cmd .nav-list { gap:18px; }
    .cmd .nav-list__link { padding:9px 7px 10px; }
    .cmd .nav-list > li:first-child .nav-list__link { padding-left:0; }
    /* Negative sticky offset: the header rides up until the wordmark row is
     * off-screen and pins on its menu strip alone — 45px instead of 118px, no
     * JS and no second markup path. 73px is where .cmd .nav starts inside the
     * header, measured identical from 769px to 1600px; it only moves if the
     * wordmark's size or .cmd-inner's padding changes. */
    .cmd { top:-73px; }
    html { scroll-padding-top:54px; }
}
@media screen and (min-width: 992px) {
    .cmd .nav-list { gap:34px; }
}

/* ------------------------------ Footer ------------------------------ */
.foot {
    margin-top:40px;
    border-top:1px solid rgba(0,190,255,.3);
    background:linear-gradient(180deg, #0a1826, #060d16);
    color:#8ba1b3;
}
.foot-inner {
    max-width:1200px;
    margin:0 auto;
    padding:30px 16px 26px;
}
.foot .footer-links {
    justify-content:flex-start;
    text-align:left;
    margin-bottom:26px;
}
.foot .footer-col-title {
    font-family:var(--font-mono);
    font-size:10px;
    font-weight:500;
    letter-spacing:.18em;
    color:#6f8ca3;
}
.foot a, .foot a:visited { color:#b9cddd; }
.foot a:hover { color:#fff; }
.foot .footer-line {
    display:flex;
    align-items:baseline;
    gap:10px;
    flex-wrap:wrap;
    margin:0;
    padding:0;
    text-align:left;
    font-size:inherit;
    color:inherit;
}
.foot .fm {
    font-family:var(--font-display);
    font-weight:600;
    font-size:17px;
    letter-spacing:.06em;
    color:#e4edf4;
    text-transform:uppercase;
}
.foot .fm .net { color:#54c3ea; }


@media (max-width: 768px) {
    .cmd-tag { display:none; }
    /* One header row: burger left, wordmark right. The nav is a sibling of
     * .cmd-top in the markup, so the two are placed explicitly in a 2-cell grid
     * rather than reordered — on mobile the nav cell only carries the burger,
     * the search box is hidden and the panel is out of flow. */
    .cmd-inner {
        display:grid;
        grid-template-columns:auto minmax(0, 1fr);
        align-items:center;
        column-gap:6px;
        padding:10px 12px;
    }
    /* Tight gap and icon padding so wordmark + theme toggle + magnifier fit
     * on one row down to small phones. */
    .cmd-top { grid-area:1 / 2; gap:8px; }
    .cmd .theme-toggle,
    .cmd .nav-search__icon { padding:6px; }
    /* Below 400px the 27px wordmark plus both icons overflows the header
     * cell — scale the wordmark, not the controls. */
    @media (max-width: 400px) {
        .wordmark { font-size:23px; padding:1px 8px 3px; }
    }
    .cmd .nav {
        grid-area:1 / 1;
        margin-top:0;
        padding:0;
        border-top:none;
    }
    .cmd .search-box { display:none !important; }
    /* The 48px offset keeps the burger panel clear of the open search bar
     * (its height in the search-reveal block below). */
    .cmd .nav-search__toggle:checked ~ .nav-list { top:calc(100% + 48px); }
    .cmd .nav-mobile__icon { padding:8px 6px; }
    /* Mobile dropdown panel: dark navy instead of the legacy slate gradient.
     * Fixed width because its containing block is now the burger-sized cell. */
    .cmd .nav-list {
        width:min(250px, calc(100vw - 24px));
        background:linear-gradient(160deg, #0a1826, #0c2033);
        border:1px solid rgba(0,190,255,.25);
        border-top:none;
    }
    /* Inline sub-menus keep the legacy translucent-white fill, which reads as a
     * pale block inside the navy panel — sink them instead. */
    .cmd .nav-dropdown__menu {
        background:rgba(0,0,0,.28);
        border:none;
        border-radius:0;
        box-shadow:none;
        min-width:0;
    }
    .cmd .nav-dropdown__link {
        font-size:12.5px;
        padding:8px 16px 8px 24px;
    }
}

/* Search reveal — phones AND tablets: below 993px there is no room for the
 * inline search field (nav links crowd the bar), so a magnifier icon at the
 * right end of .cmd-top (label driving the #search-toggle checkbox in the
 * nav) reveals the field as a bar docked under the header. The 16px input
 * font stops iOS from zooming the page on focus. */
@media (max-width: 992px) {
    /* The auto left margin pushing the icon cluster right lives on the theme
     * toggle, which precedes the magnifier and shows at every width. */
    .nav-search__icon {
        display:flex;
        align-items:center;
        padding:8px;
        color:#b9cddd;
        cursor:pointer;
    }
    .cmd .nav-search__toggle:checked ~ .search-box {
        display:flex !important;
        position:absolute;
        top:100%;
        left:0;
        z-index:101;
        box-sizing:border-box;
        width:calc(100vw - 24px);
        height:48px;
        padding:8px;
        background:#0a1826;
        border:1px solid rgba(0,190,255,.25);
        border-top:none;
    }
    .cmd .nav-search__toggle:checked ~ .search-box form {
        width:100%;
        margin:0;
    }
    .cmd .nav-search__toggle:checked ~ .search-box input[type="search"] {
        width:100%;
        max-width:none;
        text-align:left;
        font-size:16px !important;
    }
}

@media (max-width: 576px) {
    .wordmark { font-size:22px; }
}


/* ============================================================================
 * 13 — COMPONENTS
 *      The ops-room design system: every page family (home, listings,
 *      rankings, detail pages, comparisons, events, news, flags, airbases)
 *      is assembled from these, per the component contract in
 *      docs/design/README.md. Tokens carry their own dark values, so component rules
 *      rarely need a body.dark override.
 * ============================================================================ */

/* --- Action pill: the one primary call-to-action of the design system,
 * replacing the v1 .btn / .btn-primary gradient. Filled --signal, mono caps.
 * Two sizes share this skin: .actbtn standalone (add .block to stretch it to
 * the container width) and the compact .ledger-foot .go card-foot variant,
 * whose metrics live with .ledger-foot. --- */
.actbtn,
.ledger-foot .go {
    display:inline-flex;
    align-items:center;
    justify-content:center;
    gap:6px;
    font-family:var(--font-mono);
    text-transform:uppercase;
    color:var(--color-white);
    background:var(--signal);
    border:0;
    border-radius:6px;
    cursor:pointer;
    text-decoration:none;
    /* A pill is one line: a wrapped CTA reads as a paragraph, not a button */
    white-space:nowrap;
}
.actbtn {
    font-size:12px;
    font-weight:600;
    letter-spacing:.14em;
    padding:10px 18px;
}
.actbtn:hover, .ledger-foot .go:hover { filter:brightness(1.1); text-decoration:none; }
.actbtn[disabled] { opacity:.45; pointer-events:none; }
.actbtn.block { width:100%; }
/* --signal is a light cyan in dark mode; white on it is unreadable */
body.dark .actbtn, body.dark .ledger-foot .go { color:var(--ground); }

/* Flat page: migrated templates opt out of the legacy #page card via
 * {% block page_attrs %} class="page-flat" {% endblock %} */
#page.page-flat {
    background:transparent;
    box-shadow:none;
    border-radius:0;
    padding:0 16px 56px;
}
.page-flat .breadcrumb-container { padding:14px 0 0; }
.page-flat .breadcrumb {
    background:none;
    border:none;
    border-radius:0;
    box-shadow:none;
    padding:0;
    margin:0;
}
.page-flat .breadcrumb::before { content:none; }
.page-flat .breadcrumb,
.page-flat .breadcrumb-item,
.page-flat .breadcrumb-item a {
    font-family:var(--font-mono);
    font-size:10.5px;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.page-flat .breadcrumb-item.active { color:var(--text-color); }
.page-flat .breadcrumb-item+.breadcrumb-item::before {
    content:"/";
    color:var(--hairline-strong);
    background:none;
}
/* breadcrumb link colors live with the interaction-language rules below */

/* Eyebrow kicker above the h1 */
.eyebrow {
    font-family:var(--font-mono);
    font-size:11px;
    font-weight:500;
    letter-spacing:.2em;
    text-transform:uppercase;
    color:var(--signal);
    display:flex;
    align-items:center;
    gap:10px;
    flex-wrap:wrap;
}
.eyebrow::after { content:""; height:1px; flex:1; background:var(--hairline); min-width:40px; }
.eyebrow a { color:inherit; }

/* Section headings with rule */
.section { margin-top:48px; }
.section-head { display:flex; align-items:baseline; gap:14px; margin-bottom:18px; }
.section-head h2 {
    font-size:26px;
    font-weight:600;
    letter-spacing:.04em;
    text-transform:uppercase;
    margin:0;
}
.section-head .rule { flex:1; height:1px; background:var(--hairline); }
.section-head .all {
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.12em;
    text-transform:uppercase;
    white-space:nowrap;
}
/* The nowrap .all would otherwise squeeze the heading into one word per line */
@media (max-width: 768px) {
    .section-head { flex-wrap:wrap; row-gap:6px; }
    .section-head .all { flex-basis:100%; white-space:normal; }
}

/* Equipment hero: title left, photo right */
.achero {
    display:grid;
    grid-template-columns:minmax(0, 1.1fr) minmax(0, 1fr);
    gap:36px;
    align-items:center;
    padding:26px 0 8px;
}
/* Shared display treatment of the three hero variants' h1 + lede
 * (.achero equipment / .afhero forces / .hero generic); size and rhythm
 * stay per-variant, next to each hero's own block. */
.achero h1, .afhero h1, .hero h1 {
    font-weight:600;
    letter-spacing:.015em;
    text-transform:uppercase;
    text-wrap:balance;
    padding-bottom:0;
}
.achero .lede, .afhero .lede, .hero .lede { color:var(--text-muted); font-size:15px; margin:0; }
.achero h1 {
    font-size:clamp(44px, 6.5vw, 76px);
    line-height:.95;
    margin:12px 0 14px;
}
.achero h1.long { font-size:clamp(32px, 4.2vw, 48px); line-height:1.02; }
.achero .lede { max-width:58ch; }
.acphoto {
    border-radius:6px;
    overflow:hidden;
    background:var(--photo-ground);
    border:1px solid var(--hairline);
    box-shadow:var(--shadow-panel);
    position:relative;
    margin:0;
}
.acphoto img { display:block; width:100%; height:auto; }
/* Hero intel column — photo + .herostat status panel stacked in the hero's
 * right slot; replaces the .statband on equipment detail pages
 * (herostat harmonization 2026-08) */
.achero .acintel {
    display:flex;
    flex-direction:column;
    gap:16px;
    min-width:0;
}
/* With an intel column the hero top-aligns like .herogrid — centering the
 * short text block against photo+panel leaves a void above the title */
.achero:has(.acintel) { align-items:start; }

/* Summary stat band */
.statband {
    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(150px, 1fr));
    border-top:1px solid var(--hairline-strong);
    border-bottom:1px solid var(--hairline);
    margin-top:26px;
}
.statband > div { padding:16px 18px 14px; border-left:1px solid var(--hairline); }
.statband > div:first-child { border-left:none; padding-left:0; }
.statband .k {
    font-family:var(--font-mono);
    font-size:9.5px;
    font-weight:500;
    letter-spacing:.16em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.statband .n {
    font-family:var(--font-display);
    font-weight:600;
    font-size:30px;
    line-height:1.1;
    font-variant-numeric:tabular-nums;
    margin-top:2px;
}
.statband .n small {
    font-size:15px;
    font-weight:500;
    color:var(--text-muted);
    letter-spacing:.03em;
    margin-left:3px;
}
.statband .n.sm { font-size:23px; padding-top:5px; }
.statband .n .oc { display:block; white-space:nowrap; }

/* Technical profile band (blueprint grid) */
.profileband {
    margin-top:42px;
    border:1px solid var(--hairline);
    border-radius:6px;
    overflow:hidden;
    box-shadow:var(--shadow-panel);
    background:
        linear-gradient(var(--hairline) 1px, transparent 1px) 0 0/44px 44px,
        linear-gradient(90deg, var(--hairline) 1px, transparent 1px) 0 0/44px 44px,
        var(--panel-2);
    text-align:center;
    padding:26px 20px 8px;
}
.profileband img { max-width:640px; width:100%; height:auto; }
/* Inside the hero's text column (photo + herostat fill the right slot) the
 * band balances the columns instead of leaving a void under the lede */
.achero .profileband { margin-top:28px; }
/* Inside a tablecard the band loses its standalone frame and gap */
.tablecard .profileband {
    margin-top:0;
    border:none;
    border-radius:0;
    box-shadow:none;
}
/* Inside a tablecard the Leaflet map sits flush under the ledger-head */
.tablecard .airbases-map { margin-top:0; }
.profileband .cap {
    font-family:var(--font-mono);
    font-size:9.5px;
    letter-spacing:.18em;
    text-transform:uppercase;
    color:var(--text-muted);
    padding:12px 0 10px;
}
img.profile-inv { mix-blend-mode:multiply; }
body.dark img.profile-inv { mix-blend-mode:screen; filter:invert(1) hue-rotate(180deg); }

/* Comparison pages: two profile panels side by side, images vertically centered
 * so different drawing heights stay aligned */
.vsband { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:22px; }
.vsband .profileband { display:flex; flex-direction:column; margin-top:20px; }
.vsband .profileband a { margin:auto; width:100%; }
/* minmax(0, …), not 1fr: a bare 1fr track floors at the min-content width of
 * its contents, so a 640px profile drawing would widen the page instead of
 * scaling down */
@media (max-width: 768px) { .vsband { grid-template-columns:minmax(0, 1fr); } }

/* Versus teaser (comparison hub pages): a category's headline matchup —
 * two sides facing a VS roundel; a side carries a profile drawing or a
 * flag image when one exists, otherwise the name alone */
.vscard .vsface {
    display:grid;
    grid-template-columns:minmax(0, 1fr) 34px minmax(0, 1fr);
    align-items:center;
    gap:12px;
    padding:18px 18px 16px;
    text-decoration:none;
    color:var(--text-color);
    border-bottom:1px solid var(--hairline);
}
.vscard .vsface .side {
    display:flex;
    flex-direction:column;
    align-items:center;
    gap:8px;
    min-width:0;
}
.vscard .vsface .side img { max-width:100%; max-height:56px; width:auto; height:auto; object-fit:contain; }
/* Text-only sides (families without profile art — ordnance): a large muted
 * category glyph stands in for the silhouette */
.vscard .vsface .side .ph { color:var(--hairline-strong); }
.vscard .vsface .side .ph .ic { width:30px; height:30px; }
.vscard .vsface .side img.vsflag { height:34px; max-height:34px; border-radius:2px; box-shadow:var(--shadow-panel); }
.vscard .vsface .side img.vsflag.lg { height:auto; max-height:64px; }
.vscard .vsface .name {
    font-family:var(--font-display);
    font-size:15px;
    font-weight:700;
    letter-spacing:.02em;
    line-height:1.15;
    text-align:center;
}
.vscard .vsface:hover .name { color:var(--signal); }
.vscard .vsface .sub {
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text-muted);
    text-align:center;
}
.vscard .vsmark {
    width:34px;
    height:34px;
    display:flex;
    align-items:center;
    justify-content:center;
    border:1px solid var(--hairline);
    border-radius:50%;
    color:var(--signal);
    background:var(--signal-soft);
}
.vscard .vsmark .ic { width:14px; height:14px; }
/* Pair rows under the teaser: facing sides over a force-ratio split bar */
.vscard .duels { list-style:none; margin:0; padding:4px 0 8px; }
.vscard .duels a {
    display:grid;
    grid-template-columns:1fr 24px 1fr;
    align-items:center;
    column-gap:4px;
    padding:8px 18px 10px;
    text-decoration:none;
    color:var(--text-color);
    font-size:13px;
    line-height:1.3;
}
.vscard .duels a:hover { color:var(--signal); }
.vscard .duels .d1,
.vscard .duels .d2 {
    min-width:0;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
}
.vscard .duels .d1 { text-align:right; }
.vscard .duels .d2 { text-align:left; }
.vscard .duels .num { font-family:var(--font-mono); font-size:10px; color:var(--text-muted); }
.vscard .duels .dvs { display:flex; align-items:center; justify-content:center; color:var(--text-muted); }
.vscard .duels .dvs .ic { width:11px; height:11px; }
.vscard .duels .split {
    grid-column:1 / -1;
    height:3px;
    border-radius:2px;
    margin-top:6px;
    background:linear-gradient(90deg, var(--bar-a), var(--bar-b) var(--pct, 50%), var(--hairline) var(--pct, 50%));
}

/* Discreet pair-switcher on comparison pages — secondary control, no card */
.cmpswitch {
    display:flex;
    align-items:center;
    justify-content:flex-end;
    flex-wrap:wrap;
    gap:8px;
    margin:12px 0 0;
}
/* Hosted in a picker card (comparison hubs) the switcher is the main control,
 * not a discreet corner tool */
.tablecard .cmpswitch {
    justify-content:flex-start;
    margin:0;
    font-family:var(--font-mono);
    font-size:10.5px;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.cmpswitch select {
    font-family:var(--font-mono);
    font-size:12px;
    letter-spacing:normal;
    text-transform:none;
    color:var(--text-color);
    background:var(--panel);
    border:1px solid var(--hairline);
    border-radius:6px;
    padding:5px 8px;
    max-width:210px;
}
.cmpswitch select:focus { outline:2px solid var(--signal); outline-offset:1px; }

/* Rank equivalence picker (/compare/ranks/): unlike .cmpswitch it carries four
 * controls — a branch select tied to each country — plus a real submit, because
 * the tool posts over GET and must stay usable with JS off */
.rankpick {
    display:flex;
    flex-direction:column;
    align-items:flex-start;
    gap:8px;
}
.rankpick__side {
    display:flex;
    align-items:center;
    flex-wrap:wrap;
    gap:6px;
}
/* Sits on its own line between the two sides so both select rows stay aligned */
.rankpick__vs { width:13px; height:13px; color:var(--text-muted); margin-left:4px; }
.rankpick select {
    font-family:var(--font-mono);
    font-size:12px;
    color:var(--text-color);
    background:var(--panel);
    border:1px solid var(--hairline);
    border-radius:6px;
    padding:5px 8px;
    max-width:210px;
}
.rankpick select:focus { outline:2px solid var(--signal); outline-offset:1px; }
.rankpick button {
    font-family:var(--font-mono);
    font-size:11px;
    font-weight:500;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--color-white);
    background:var(--signal);
    border:0;
    border-radius:6px;
    padding:7px 14px;
    cursor:pointer;
}
.rankpick button:hover { filter:brightness(1.1); }
.rankpick button { margin-top:2px; }
/* --signal is a light cyan in dark mode; white on it is unreadable */
body.dark .rankpick button { color:var(--ground); }
.rankpick__note { margin:10px 0 0; font-size:12px; line-height:1.45; }

/* The rank tool has one flat matchup list rather than a .masonry of per-category
 * .vscards, so the duels spread across the card instead of leaving it half empty */
.vscard .duels.duelgrid {
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(270px, 1fr));
    padding:8px;
}
.vscard .duels.duelgrid a { padding:8px 12px 9px; border-radius:6px; }
.vscard .duels.duelgrid a:hover { background:var(--signal-soft); }

/* Rank ladder: two mirrored rank columns bracketing the NATO tier they share.
 * Fixed layout keeps the centre tier column from drifting as rank names vary in
 * length; below 576px the table scrolls inside .tscroll rather than squash. */
table.data.ranklad { table-layout:fixed; }
table.data.ranklad .rkside { width:38%; }
table.data.ranklad .rktier { width:24%; text-align:center; }
table.data.ranklad thead th:nth-child(2) { text-align:center; }
table.data.ranklad thead th:last-child { text-align:right; }
.ranklad .rkitem {
    display:flex;
    align-items:center;
    gap:10px;
}
.ranklad .rkitem + .rkitem { margin-top:6px; }
.ranklad .rkside--end .rkitem { justify-content:flex-end; text-align:right; }
.ranklad .rkins {
    flex:none;
    max-height:22px;
    max-width:64px;
    width:auto;
    height:auto;
    object-fit:contain;
}
.ranklad .rkname { min-width:0; }
.ranklad .rknone { color:var(--text-muted); font-style:italic; }
.ranklad .rkcode {
    display:block;
    font-family:var(--font-mono);
    font-size:12px;
    font-weight:500;
    letter-spacing:.08em;
    color:var(--signal);
}
/* A tier only one of the two forces uses — the asymmetry is the finding */
.ranklad tr.rkgap .rkcode { color:var(--amber); }
.ranklad .rkfn {
    display:block;
    margin-top:2px;
    font-size:11px;
    line-height:1.3;
    color:var(--text-muted);
}
/* Branch label under a matchup in the .duels list */
.vscard .duels .rkbranch {
    grid-column:1 / -1;
    margin-top:4px;
    font-family:var(--font-mono);
    font-size:9.5px;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
    text-align:center;
}

@media (max-width:576px) {
        /* Three columns of prose plus insignia never fit; let .tscroll scroll it */
        table.data.ranklad { min-width:520px; }
        .rankpick select { max-width:100%; flex:1 1 140px; }
}

/* Column headers on side-by-side spec tables (comparison pages) */
table.spec thead th {
    font-family:var(--font-display);
    font-size:16.5px;
    font-weight:600;
    letter-spacing:.03em;
    text-align:left;
    padding:13px 16px 11px;
    border-bottom:2px solid var(--hairline-strong);
}
/* Comparison variant (.cmp): the detail-page 45% label column squeezes the two
 * value columns — fix the layout so values get equal, stable widths */
table.spec.cmp { table-layout:fixed; }
table.spec.cmp .l, table.spec.cmp thead th:first-child { width:30%; }
table.spec.cmp .oline { display:block; }
/* Full-width variant for long text fields (armament, propulsion) that would
 * wrap badly in the compact half-page spec card */
table.spec.cmp.wide .l, table.spec.cmp.wide thead th:first-child { width:16%; }
table.spec.cmp.wide .v ul { margin:0; padding-left:1.2em; }
table.spec.cmp.wide .v li { margin-bottom:.3em; }
/* Advantage pills on the winning/losing value — same visual language as the
 * event-ledger chips; replaces the legacy full-cell tints + dot emojis. The
 * negative margins make the pill a halo that bleeds into the cell padding,
 * keeping value text aligned with unmarked rows */
table.spec.cmp .cmpv { display:inline-block; }
table.spec.cmp .cmpv.compare-higher,
table.spec.cmp .cmpv.compare-lower {
    padding:2px 9px;
    margin:-2px -9px;
    border-radius:6px;
}
table.spec.cmp .cmpv.compare-higher { background:var(--good-soft); color:var(--good); }
table.spec.cmp .cmpv.compare-lower { background:var(--bad-soft); color:var(--bad); }

/* Head-to-head pages on phones. Everything above was drawn for the two-column
 * desktop grid: three table columns with 16px cell padding lose ~100px of a
 * 358px row to gutters alone, and the switcher's max-width never applies
 * because a <select> flex item floors at the width of its longest option. */
@media (max-width: 576px) {
    .page-flat .spec td { padding:9px 10px; }
    .page-flat table.spec thead th { padding:12px 10px 10px; font-size:15px; }
    /* The .wide variant exists for full-width desktop cards; its 16% label
     * column is 57px here, so it reverts to the regular 30% */
    table.spec.cmp.wide .l,
    table.spec.cmp.wide thead th:first-child { width:30%; }
    table.spec.cmp .v { overflow-wrap:anywhere; }
    table.spec.cmp .cmpv.compare-higher,
    table.spec.cmp .cmpv.compare-lower { padding:2px 6px; margin:-2px -6px; }
    /* Switcher: label on its own line, the two pickers sharing the next one
     * (they stack when hosted in a card on the hub pages). min-width:0 is what
     * lets them shrink past their longest option. */
    .cmpswitch { justify-content:flex-start; gap:6px; }
    .cmpswitch > span:first-child { flex:1 0 100%; }
    .cmpswitch select {
        flex:1 1 140px;
        min-width:0;
        max-width:none;
    }
    /* Scale diagram and radar chart get the card's full width back */
    .tablecard .card-pad.ordnance-visual,
    .tablecard .card-pad.flex-center { padding:14px 8px; }
}
/* Chart.js writes an explicit pixel width on the canvas; without a cap it
 * keeps the widest size it was ever laid out at and never shrinks back */
.tablecard .card-pad.flex-center > canvas { max-width:100%; }

/* Panel-card primitive — the shared shell of every card component of the
 * redesign (.herostat overrides the radius, variants add their own layout) */
.ledger, .tablecard, .herostat, .accard, .newscard, .bookcard {
    background:var(--panel);
    border:1px solid var(--hairline);
    border-radius:6px;
    box-shadow:var(--shadow-panel);
}
.ledger, .tablecard { overflow:hidden; }
.ledger-head {
    display:flex;
    align-items:center;
    gap:10px;
    padding:12px 18px;
    border-bottom:1px solid var(--hairline);
    background:var(--panel-2);
    font-family:var(--font-display);
    font-weight:600;
    font-size:18px;
    letter-spacing:.06em;
    text-transform:uppercase;
}
.ledger-head svg { color:var(--signal); }
.ledger-head .ver {
    margin-left:auto;
    font-family:var(--font-mono);
    font-size:10.5px;
    font-weight:500;
    letter-spacing:.08em;
    text-transform:none;
    color:var(--text-muted);
}
.tablecard .card-pad { padding:14px 18px; }
.tablecard > img,
.tablecard > a > img { display:block; width:100%; height:auto; }

/* Infographic figure card (ranking pages): image + mono caption */
figure.tablecard { margin:0; }
figure.tablecard figcaption {
    padding:9px 16px;
    border-top:1px solid var(--hairline);
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text-muted);
}

/* Spec table */
table.spec { width:100%; border-collapse:collapse; font-size:13.5px; }
.spec td { padding:9px 16px; border-top:1px solid var(--hairline); }
.spec tr:first-child td { border-top:none; }
.spec .l {
    font-family:var(--font-mono);
    font-size:10.5px;
    letter-spacing:.1em;
    text-transform:uppercase;
    color:var(--text-muted);
}
/* The label column takes the width of its longest label and not a pixel more:
 * width:1% asks for the minimum, nowrap sets that minimum to the text itself.
 * The old 45% split handed "Subtype" a quarter of the card while Propulsion
 * wrapped to four lines beside it. This self-tunes per table — an equipment
 * sheet lands near 120px, the country sheet near 240px — so no per-context
 * modifier is needed. Comparison tables are excluded: they are table-layout:
 * fixed with their own column widths, where nowrap would overflow instead. */
.spec:not(.cmp) .l { width:1%; white-space:nowrap; }
.spec .v { font-variant-numeric:tabular-nums; font-weight:500; }
.spec .v small { color:var(--text-muted); font-weight:400; }

/* Horizontal bar with hatched on-order segment (--pct / --opct) */
.bar {
    position:relative;
    display:block;
    height:8px;
    min-width:80px;
    background:var(--hairline);
    border-radius:99px;
    overflow:hidden;
}
.bar i {
    position:absolute;
    inset:0 auto 0 0;
    width:var(--pct, 0%);
    background:linear-gradient(90deg, var(--bar-a), var(--bar-b));
    border-radius:99px;
}
.bar i.ordered {
    left:var(--pct, 0%);
    width:var(--opct, 0%);
    border-radius:0 99px 99px 0;
    background:repeating-linear-gradient(115deg, var(--bar-b), var(--bar-b) 3px, transparent 3px, transparent 6px);
    opacity:.75;
}
.legend {
    display:flex;
    gap:18px;
    padding:10px 18px 12px;
    border-top:1px solid var(--hairline);
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--text-muted);
    align-items:center;
}
.legend .sw { width:18px; height:8px; border-radius:99px; display:inline-block; margin-right:6px; vertical-align:1px; }
.legend .sw.solid { background:linear-gradient(90deg, var(--bar-a), var(--bar-b)); }
.legend .sw.hatch { background:repeating-linear-gradient(115deg, var(--bar-b), var(--bar-b) 3px, transparent 3px, transparent 6px); }
.legend .sw.line { height:2px; background:var(--amber); border-radius:0; vertical-align:4px; }

/* Chip lists (armament, compare links). Also styles markdownified <ul><li>. */
.arm { padding:8px 18px 16px; }
/* Nested in a padded card body the chip row must not double the inset */
.card-pad .arm { padding:12px 0 0; }
.arm, .arm ul {
    display:flex;
    flex-wrap:wrap;
    gap:8px;
}
.arm ul { list-style:none; margin:0; padding:0; }
.arm p { margin:0; display:contents; }
/* Two chip states: data tag (transparent + muted) vs interactive (panel + signal) */
.arm a, .arm span, .arm li {
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.06em;
    color:var(--text-muted);
    border:1px solid var(--hairline);
    border-radius:3px;
    background:transparent;
    padding:5px 10px;
}
.arm > a, .arm li:has(a) {
    background:var(--panel-2);
    color:var(--signal);
}
.arm li a, .arm li span { border:none; background:none; padding:0; color:inherit; }
/* Stretched link: the whole chip is clickable even when only part of the
 * label is wrapped in the anchor (link_armament links the weapon name only) */
.arm li { position:relative; }
.arm li a::after { content:""; position:absolute; inset:0; }
.arm > a:hover, .arm li:has(a):hover { border-color:var(--signal); text-decoration:none; }
.arm li a:hover { text-decoration:none; }
.arm a .ic { width:12px; height:12px; vertical-align:-2px; margin-right:3px; color:var(--signal); }
.arm-g {
    font-family:var(--font-mono);
    font-size:9.5px;
    letter-spacing:.16em;
    text-transform:uppercase;
    color:var(--text-muted);
    padding:14px 18px 6px;
}

/* Events ledger rows + semantic chips */
.ledger ol { list-style:none; margin:0; padding:0; }
.ledger li { border-top:1px solid var(--hairline); }
.ledger li:first-child { border-top:none; }
.ledger .evlink {
    display:grid;
    grid-template-columns:58px 96px 1fr;
    gap:12px;
    padding:13px 18px;
    align-items:start;
    color:inherit;
}
a.evlink:hover { background:var(--panel-2); text-decoration:none; }
/* Standoff incident log: its type chips run longer than the event-type ones
 * (INFRASTRUCTURE, INTERCEPTION overflow the 96px column into the gap). */
.ledger.wide-type .evlink { grid-template-columns:58px 114px 1fr; }
/* Update-journal feed (/updates/): rows are grouped under per-day section
 * heads, so the date column is dropped — chip + text only. */
.ledger.journal .evlink { grid-template-columns:96px 1fr; }
/* Nearby-bases card (airbase detail): a distance replaces the date and there is
 * no type chip, so the middle column goes rather than sitting empty. */
.ledger.geo .evlink { grid-template-columns:58px 1fr; }
/* The status chip rides inside .txt here rather than in a column of its own:
 * barely 4% of bases are anything but Active, so a reserved column would sit
 * empty on every other row. Inline-block because .chip is laid out as a grid
 * item everywhere else, where its vertical padding and margin-top apply. */
.ledger.geo .txt .chip {
    display:inline-block;
    vertical-align:1px;
    margin-top:0;
}
.ledger .date {
    font-family:var(--font-mono);
    font-size:11px;
    font-weight:500;
    color:var(--text-muted);
    padding-top:3px;
    white-space:nowrap;
}
/* Year on its own line so the date column stays narrow; a span rather than a
 * <br> so mobile can pull it back inline (see the 576px block). */
.ledger .date .yr { display:block; }
.ledger .txt { font-size:13.5px; line-height:1.5; }
.ledger .txt .who { font-weight:600; }
/* Compact ledger (home sitrep): tighter rows, text clamped to two lines,
 * and the profile stack (image + model name) shrunk to match — it is what
 * actually drives the row height on the air column */
.ledger.compact .evlink { padding:10px 18px; }
.ledger.compact .txt {
    display:-webkit-box;
    -webkit-line-clamp:2;
    -webkit-box-orient:vertical;
    overflow:hidden;
}
.ledger.compact .evis { gap:2px; }
.ledger.compact .evis img { max-height:30px; }
.ledger.compact .evis .evname {
    max-width:96px;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}
.chip {
    font-family:var(--font-mono);
    font-size:9.5px;
    font-weight:500;
    letter-spacing:.1em;
    text-transform:uppercase;
    padding:3px 8px;
    border-radius:3px;
    white-space:nowrap;
    justify-self:start;
    margin-top:2px;
}
.chip.bad { color:var(--bad); background:var(--bad-soft); }
.chip.good { color:var(--good); background:var(--good-soft); }
.chip.info { color:var(--signal); background:var(--signal-soft); }
.chip.warn { color:var(--amber); background:var(--amber-soft); }

/* Balanced two-column card flow.
 * Children are inline-block, not block: WebKit balances block children by
 * growing the first column to swallow the whole break-inside:avoid card
 * (columns end up 3–1 with the card's margin/shadow fragment painted at the
 * top of column 2 — Safari-only). Atomic inline boxes take the correct
 * Chrome-like balance; the one residue is a ~26px WebKit inset at the top of
 * later columns. float:left is no better: WebKit splits floated cards. */
.masonry { columns:2; column-gap:24px; }
.masonry > * {
    display:inline-block;
    width:100%;
    vertical-align:top;
    break-inside:avoid;
    margin-bottom:24px;
}

/* Compact inline operator list */
.oplist { padding:14px 18px; font-size:13.5px; line-height:2; }
.oplist a { font-weight:500; }
.oplist .fl { margin-right:4px; }
.oplist .sep { color:var(--hairline-strong); margin:0 8px; }

/* Full-width prose (markdownified description), newspaper two-column flow */
.prose { font-size:15px; line-height:1.68; columns:2; column-gap:48px; }
/* Single-column variant for short programmatic texts (comparison intros):
 * two newspaper columns split 3-sentence blurbs mid-phrase */
.prose.single { columns:1; max-width:78ch; }
@media (max-width: 992px) { .prose { columns:1; } }
.prose p { margin:0 0 1em; }
/* Links inside running text must not rely on color alone (WCAG 1.4.1) */
.prose a {
    text-decoration:underline;
    text-decoration-color:color-mix(in srgb, var(--signal) 45%, transparent);
    text-underline-offset:2px;
}
.prose a:hover { text-decoration-color:var(--signal); }
.prose h2 {
    font-size:23px;
    font-weight:600;
    letter-spacing:.04em;
    text-transform:uppercase;
    margin:1.6em 0 .5em;
    padding-bottom:0;
    display:flex;
    align-items:center;
    gap:12px;
    break-after:avoid;
}
.prose h2:first-child { margin-top:0; }
.prose h2::after { content:""; height:1px; flex:1; background:var(--hairline); }
.prose h3 {
    font-size:18px;
    font-weight:600;
    letter-spacing:.04em;
    text-transform:uppercase;
    margin:1.4em 0 .4em;
    color:var(--text-muted);
    break-after:avoid;
}
.prose ul { margin:0 0 1em; padding-left:1.3em; }
.prose li { margin-bottom:.35em; }

/* News detail: readable article copy with a compact editorial resources rail. */
.news-article-layout {
    display:grid;
    grid-template-columns:minmax(0, 78ch) minmax(280px, 1fr);
    gap:48px;
    align-items:start;
}
.news-article-main .artfig + .prose { margin-top:48px; }
.news-article-aside > .section { margin-top:32px; }
.news-article-aside > .section:first-child { margin-top:0; }
.news-article-aside .section-head h2 { font-size:18px; }
.news-article-aside .bookrow { grid-template-columns:minmax(0, 1fr); gap:12px; }
@media (max-width: 992px) {
    .news-article-layout { grid-template-columns:minmax(0, 1fr); gap:0; }
    .news-article-aside { margin-top:48px; }
}
/* Markdown tables inside prose (NATO prefix tables, snippet copy) had no rule
 * of their own and fell through to the legacy bare-table styling — a shadowed
 * legacy card carried no margin at all, so the next paragraph sat flush against
 * its bottom edge. Re-skinned on the same hairline language as table.data. */
.page-flat .prose table {
    width:100%;
    margin:0 0 1.4em;
    border-collapse:collapse;
    box-shadow:none;
    break-inside:avoid;
    font-size:14px;
}
.page-flat .prose th,
.page-flat .prose td {
    padding:9px 14px;
    text-align:left;
    vertical-align:top;
    background:none;
    border-bottom:1px solid var(--hairline);
}
.page-flat .prose thead th {
    font-family:var(--font-mono);
    font-size:10px;
    font-weight:500;
    letter-spacing:.16em;
    text-transform:uppercase;
    color:var(--text-muted);
    background:var(--panel-2);
    border-bottom:1px solid var(--hairline-strong);
}
.page-flat .prose tbody tr:last-child td { border-bottom:none; }
.page-flat .prose tbody tr:hover td { background:var(--signal-soft); }
/* width:100% is only a preferred width: a table whose columns' min-content adds
 * up to more than the reading column overflows anyway (the Gemini comparison
 * tables do, by ~20px on a 390px screen). Auto layout keeps the good column
 * proportions where there is room; below the tablet breakpoint, fitting wins. */
@media (max-width: 768px) {
    .page-flat .prose table { table-layout:fixed; }
    .page-flat .prose th,
    .page-flat .prose td { overflow-wrap:anywhere; }
}

/* Legacy include cards (FAQ, In the News) re-skinned inside migrated pages */
.page-flat .card {
    background:var(--panel);
    border:1px solid var(--hairline);
    border-radius:6px;
    box-shadow:var(--shadow-panel);
    margin-top:24px;
}
.page-flat .card-header {
    background:var(--panel-2);
    border-bottom:1px solid var(--hairline);
    padding:12px 18px;
}
.page-flat .card-header h2 {
    font-size:18px;
    font-weight:600;
    letter-spacing:.06em;
    text-transform:uppercase;
    color:var(--text-color);
    margin:0;
    padding:0;
}
.page-flat .faq-item {
    background:var(--panel-2);
    border-color:var(--hairline);
}
.page-flat .sources {
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.04em;
    color:var(--text-muted);
    border-top:1px solid var(--hairline);
    margin-top:44px;
    padding-top:14px;
}

@media (max-width: 992px) {
    .achero { grid-template-columns:1fr; gap:24px; }
    .masonry { columns:1; }
}
@media (max-width: 576px) {
    /* Two-column matrix: auto-fit would also land on 2 columns here, but the
     * hairlines have to be driven by position, so the count is pinned. */
    .statband { grid-template-columns:repeat(2, 1fr); }
    .statband > div {
        padding:12px 14px 10px;
        border-left:1px solid var(--hairline);
        border-top:1px solid var(--hairline);
    }
    .statband > div:nth-child(odd) { border-left:none; padding-left:0; }
    .statband > div:nth-child(-n+2) { border-top:none; }
    .statband .n { font-size:24px; }
    .statband .n.sm { font-size:19px; }
    .section-head h2 { font-size:21px; }
    table.data .cty .nm2 {
        display:block;
        white-space:normal;
        font-weight:400;
    }
    table.data .cty .nm2::before { content:none; }
    /* Too narrow to let the longest label set the split — a 240px label on the
     * country sheet would leave the value under 90px. Cap it and let it wrap. */
    .spec:not(.cmp) .l { width:41%; white-space:normal; }
}

/* Interaction language (redesign contract): clickable text is always
 * signal-tinted inside migrated pages; quiet zones re-asserted below. */
.page-flat a:link, .page-flat a:visited { color:var(--signal); }
.page-flat a:hover { color:var(--signal); }
.page-flat .breadcrumb-item a:link, .page-flat .breadcrumb-item a:visited { color:var(--text-muted); }
.page-flat .breadcrumb-item a:hover { color:var(--signal); }
.page-flat a.evlink:link, .page-flat a.evlink:visited { color:inherit; }
.page-flat a.evlink:hover { text-decoration:none; }
.page-flat .section-head .all:link, .page-flat .section-head .all:visited { color:var(--signal); }

/* Headings inside migrated pages: neutralize the legacy green/blue bar
 * treatment. H2 = dark condensed + hairline rule (via .section-head/.prose),
 * H3 = muted condensed, hierarchy carried by size and color only. */
.page-flat h2 {
    color:var(--text-color);
    border-left:none;
    background:none;
    padding:0;
}
.page-flat h3 {
    color:var(--text-muted);
    border-left:none;
    border-radius:0;
    background:none;
    padding:0;
}

/* Hero without photo: let the text column span the full width — unless an
 * intel column remains, which then narrows to the herogrid panel width */
.achero:not(:has(.acphoto)) { grid-template-columns:1fr; }
.achero:not(:has(.acphoto)):has(.herostat) { grid-template-columns:minmax(0, 1fr) 290px; }
@media (max-width: 992px) {
    .achero:not(:has(.acphoto)):has(.herostat) { grid-template-columns:1fr; }
}

/* Country entries in inline operator lists never break mid-name */
.oplist > span { white-space:nowrap; }

/* Compact multi-column roster for long enumerations (ship hulls, etc.) —
 * use instead of .arm chips when the list is a plain enumeration */
.roster { padding:12px 18px 16px; columns:220px 3; column-gap:32px; }
/* Embedded in a spec fact-sheet cell (airbase Units/Runways): no own padding,
 * single column, so entries align with the other value cells */
table.spec .roster { padding:0; columns:1; }
/* Single-column variant: long technical lines (ship armament, airbase units)
 * keep their full text and wrap instead of truncating */
.roster.single { columns:1; }
/* `.wrap` keeps the columns but lets an entry that carries a trailing detail run
 * onto a second line — the aircraft page lists a base plus its operating unit,
 * which the ellipsis was cutting mid-word */
.roster.single > span,
.roster.single li,
.roster.wrap > span,
table.spec .roster > span {
    white-space:normal;
    overflow:visible;
    text-overflow:clip;
}
.roster ul { list-style:none; margin:0; padding:0; }
.roster > span, .roster li {
    display:block;
    break-inside:avoid;
    font-family:var(--font-mono);
    font-size:11.5px;
    letter-spacing:.03em;
    padding:5px 0;
    border-bottom:1px dotted var(--hairline);
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}
/* 24px touch target without changing the row height */
.roster li a {
    display:inline-block;
    padding-block:5px;
    margin-block:-5px;
}
/* Unit emblem wall (airbase page): a grid of cut-out patches with a mono caption,
 * each tile linking to its Commons file page. The images are cut out, so no
 * background or radius — the badge sits on the panel in both themes. Tiles are
 * fixed-height so a two-line caption never staggers the row. */
.embwall {
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(96px, 1fr));
    gap:2px;
    padding:12px 12px 8px;
}
.embwall a {
    display:flex;
    flex-direction:column;
    align-items:center;
    gap:8px;
    padding:10px 6px 8px;
    border-radius:var(--border-radius-sm);
    color:var(--text-muted);
    text-decoration:none;
}
.embwall a:hover { background:var(--signal-soft); color:var(--text-color); text-decoration:none; }
.embwall img { width:64px; height:64px; object-fit:contain; }
.embwall .cap {
    font-family:var(--font-mono);
    font-size:9.5px;
    line-height:1.3;
    letter-spacing:.06em;
    text-transform:uppercase;
    text-align:center;
    display:-webkit-box;
    -webkit-line-clamp:3;
    -webkit-box-orient:vertical;
    overflow:hidden;
}
/* Licence attribution for the few emblems that require it (CC BY, OGL) */
.embcredit {
    margin:0;
    padding:0 18px 12px;
    font-size:10.5px;
    line-height:1.5;
    color:var(--text-muted);
}
.page-flat .ordnance-separator { background:var(--hairline); margin:14px 0 16px; }
.page-flat .ordnance-bar-label {
    font-family:var(--font-mono);
    font-size:10.5px;
    letter-spacing:.1em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.page-flat .ordnance-bar-value {
    font-variant-numeric:tabular-nums;
    font-size:13.5px;
    font-weight:500;
}
.page-flat .ordnance-bar-track {
    height:8px;
    border-radius:99px;
    background:var(--hairline);
}
.page-flat .ordnance-bar-fill {
    background:linear-gradient(90deg, var(--bar-a), var(--bar-b));
    border-radius:99px;
}
.page-flat .dim-label { font-family:var(--font-mono); fill:var(--text-muted); }

/* Canonical data table (redesign). Legacy tables dropped inside a migrated
 * tablecard (e.g. NATO designations) inherit the same treatment without
 * markup changes via the :not(.spec) selector branch. */
.tscroll { overflow-x:auto; }
table.data,
.page-flat .tablecard table:not(.spec) {
    width:100%;
    border-collapse:collapse;
    font-size:14px;
}
table.data th,
.page-flat .tablecard table:not(.spec) th {
    font-family:var(--font-mono);
    font-size:10px;
    font-weight:500;
    letter-spacing:.16em;
    text-transform:uppercase;
    color:var(--text-muted);
    text-align:left;
    padding:12px 18px;
    border-bottom:1px solid var(--hairline-strong);
    background:var(--panel-2);
    white-space:nowrap;
    position:sticky;
    top:0;
    z-index:2;
}
table.data td,
.page-flat .tablecard table:not(.spec) td {
    padding:11px 18px;
    border-top:1px solid var(--hairline);
    font-variant-numeric:tabular-nums;
    background:none;
}
table.data tr:first-child td,
.page-flat .tablecard table:not(.spec) tr:first-child td { border-top:none; }
table.data tbody tr:hover,
.page-flat .tablecard table:not(.spec) tbody tr:hover td { background:var(--signal-soft); }
table.data .num,
.page-flat .tablecard table:not(.spec) .num { text-align:right; }
table.data td.num,
.page-flat .tablecard table:not(.spec) td.num { font-family:var(--font-mono); font-size:13px; }
table.data .rank { font-family:var(--font-mono); font-size:11px; color:var(--text-muted); width:30px; }
table.data .cty { font-weight:600; white-space:nowrap; }
table.data .cty .fl { margin-right:8px; }
/* Secondary name trailing the main one. The interpunct comes from CSS so the
 * narrow layout can drop it and break the line instead of widening a cell that
 * is deliberately nowrap. */
table.data .cty .nm2::before { content:" · "; }
table.data .dim { color:var(--text-muted); }
table.data .plus { color:var(--signal); }
/* Inverse of .actv: small numeral beside a trailing share bar */
table.data .numbar {
    display:inline-flex;
    align-items:center;
    gap:10px;
}
table.data .numbar .bar { width:90px; min-width:90px; height:5px; }
/* Sub-line under a cell's main entry (belligerent loss-type breakdowns) */
table.data .td-sub {
    display:block;
    font-size:11px;
    font-weight:400;
    color:var(--text-muted);
    margin-top:4px;
    white-space:normal;
}

/* ---------------- Force pages (air force / navy / army) ---------------- */
.afhero { display:flex; gap:26px; align-items:flex-start; padding:26px 0 8px; }
.afhero .roundel {
    flex:none;
    width:84px;
    height:84px;
    border-radius:50%;
    background:var(--panel);
    border:1px solid var(--hairline);
    box-shadow:var(--shadow-panel);
    display:flex;
    align-items:center;
    justify-content:center;
    margin-top:8px;
}
.afhero .roundel img { width:60px; height:60px; object-fit:contain; }
.afhero h1 {
    font-size:clamp(38px, 6vw, 64px);
    line-height:1;
    margin:10px 0 12px;
}
.afhero .lede { max-width:66ch; }
/* Force-page status panel: rank/types/events + Updated, right of the title
 * (harmonization 2026-08); the mass numbers stay in the statband below */
.afhero > div { flex:1 1 auto; min-width:0; }
.afhero .herostat { flex:0 0 290px; margin-left:auto; margin-top:8px; }
@media (max-width: 992px) {
    .afhero .herostat { flex-basis:auto; margin-left:0; align-self:stretch; }
}

/* Country hero — .achero variant: terrain map + flag medallion, rank badges */
.ctyhero h1 { font-size:clamp(38px, 6vw, 64px); line-height:1; margin:10px 0 12px; }
.ctyhero .herobadges { display:flex; flex-wrap:wrap; gap:10px; margin-top:20px; }
.ctyhero .hb {
    font-family:var(--font-mono);
    font-size:10px;
    font-weight:500;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
    border:1px solid var(--hairline-strong);
    border-radius:4px;
    padding:8px 12px;
    display:inline-flex;
    align-items:baseline;
    gap:7px;
}
.ctyhero .hb strong {
    font-family:var(--font-display);
    font-size:18px;
    font-weight:600;
    line-height:1;
    color:var(--text-color);
    font-variant-numeric:tabular-nums;
}
.ctyhero a.hb:hover { border-color:var(--signal); text-decoration:none; }
.ctyhero .hb.rk { border-color:var(--signal); background:var(--signal-soft); }
.ctyhero .hb.rk, .ctyhero .hb.rk strong { color:var(--signal); }
/* Branch quick-nav — second badge row under the stats badges; every pill is a
   link, so labels are signal-tinted per the interaction language. The sprite
   icon wants center alignment, not the baseline the numeral badges use. */
.ctyhero .ctynav { margin-top:12px; }
.ctyhero .ctynav .hb {
    align-items:center;
    color:var(--signal);
}
.ctyhero .ctynav .hb .ic { width:15px; height:15px; }
/* Medallion sits on light map tiles in both themes: fixed dark shadow */
.ctymap .ctyflag {
    position:absolute;
    right:12px;
    bottom:12px;
    width:78px;
    height:auto;
    border-radius:3px;
    border:1px solid var(--hairline-strong);
    box-shadow:0 3px 10px rgba(0,0,0,.3);
}

/* Global index dial (conic gauge, score via --score 0-100) */
.indexcard { display:flex; gap:26px; padding:20px 22px; align-items:center; flex-wrap:wrap; }
.indexbadge {
    flex:none;
    width:110px;
    height:110px;
    border-radius:50%;
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    background:conic-gradient(var(--signal) calc(var(--score) * 1%), var(--hairline) 0);
    position:relative;
}
.indexbadge::before {
    content:"";
    position:absolute;
    inset:7px;
    border-radius:50%;
    background:var(--panel);
}
.indexbadge .s {
    position:relative;
    font-family:var(--font-display);
    font-weight:600;
    font-size:34px;
    line-height:1;
    font-variant-numeric:tabular-nums;
}
.indexbadge .l {
    position:relative;
    font-family:var(--font-mono);
    font-size:8px;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
    margin-top:3px;
}
.indexcopy { flex:1; min-width:220px; font-size:13.5px; color:var(--text-muted); line-height:1.6; }
.indexcopy .rk { font-family:var(--font-mono); font-size:12px; color:var(--text-color); }
.indexcopy .rk strong { color:var(--signal); }
/* Methodology chip sits inside the copy block, not a card body */
.indexcopy .arm { padding:10px 0 0; }

/* Category bars (fleet composition, aircraft origin) */
.fleetbars { list-style:none; margin:0; padding:6px 0; }
.fleetbars li {
    display:grid;
    /* label column wide enough for long vehicle categories; they wrap to two
     * lines instead of sliding under the count */
    grid-template-columns:minmax(100px, 170px) 76px 1fr;
    align-items:center;
    gap:14px;
    padding:9px 18px;
}
.fleetbars .cat {
    font-family:var(--font-mono);
    font-size:10.5px;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--text-muted);
    display:flex;
    align-items:center;
    gap:8px;
    line-height:1.4;
    min-width:0;
}
.fleetbars .cat svg { color:var(--signal); }
/* Wide variant for vehicle-category lists: labels like "Multiple launch rocket
 * system" stay on one line; reverts to wrapping on small screens where 250px
 * of label would crush the bars */
.fleetbars.wide li { grid-template-columns:minmax(100px, 250px) 76px 1fr; }
@media (max-width: 576px) {
    .fleetbars.wide li { grid-template-columns:minmax(100px, 170px) 76px 1fr; }
}
.fleetbars .n {
    font-family:var(--font-mono);
    font-size:12px;
    text-align:right;
    font-variant-numeric:tabular-nums;
    white-space:nowrap;
}
.fleetbars .n .plus { color:var(--signal); }
/* Operators variant (aircraft pages): the label cell is a linked country name
 * in the body face with a roundel/flag, instead of a mono category label */
.fleetbars .cty { font-size:13.5px; font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.fleetbars .cty .fl { margin-right:7px; }
.fleetbars .rnd {
    width:auto;
    height:auto;
    max-width:26px;
    max-height:19px;
    object-fit:contain;
    margin-right:8px;
    vertical-align:-4px;
}

/* Fleet evolution SVG bar chart */
.evochart { padding:18px 18px 8px; }
.evochart svg { width:100%; height:auto; display:block; }
.evochart .axis { font-family:var(--font-mono); font-size:10px; fill:var(--text-muted); }
.evochart .val { font-family:var(--font-mono); font-size:10.5px; font-weight:500; fill:var(--text-color); }
.evochart .gridline { stroke:var(--hairline); stroke-width:1; }
.evochart .barrect { fill:var(--bar-a); }
.evochart .barrect.last { fill:var(--bar-b); }
/* Chart.js canvases (multi-series, stacked and radar charts; single-series bar
 * histories are the server-rendered .evochart above). Height is the only
 * per-instance value, injected as --chart-h. */
.chartbox { position:relative; }
.chartbox canvas { width:100%; height:var(--chart-h, 300px); }
.chart-nodata {
    display:flex;
    align-items:center;
    justify-content:center;
    height:var(--chart-h, 300px);
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--text-muted);
}

/* Secondary series overlaid on the bars (e.g. GDP share on the budget chart).
 * The card shows no y-axis: the line is zero-based on a rounded ceiling that
 * the legend spells out (see svg_charts._build_overlay). */
.evochart .evoline {
    fill:none;
    stroke:var(--amber);
    stroke-width:2;
    stroke-linecap:round;
    stroke-linejoin:round;
}

/* Most-used equipment grid */
.topgrid { display:grid; grid-template-columns:repeat(3, 1fr); gap:0; }
.topgrid a {
    display:flex;
    flex-direction:column;
    color:inherit;
    border-left:1px solid var(--hairline);
    border-top:1px solid var(--hairline);
    padding:14px 16px 12px;
}
.topgrid a:nth-child(3n/**/+1) { border-left:none; }
.topgrid a:nth-child(-n/**/+3) { border-top:none; }
.topgrid a:hover { text-decoration:none; background:var(--signal-soft); }
.topgrid .tvis { height:66px; display:flex; align-items:center; justify-content:center; }
.topgrid .tvis img { max-height:60px; max-width:100%; }
.topgrid .tname {
    font-family:var(--font-display);
    font-weight:600;
    font-size:17px;
    letter-spacing:.02em;
    text-transform:uppercase;
    margin-top:6px;
    color:var(--text-color);
}
.topgrid .tmeta {
    font-family:var(--font-mono);
    font-size:9.5px;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--text-muted);
}

/* Ledger rows with equipment profile thumbnails: profile (or placeholder icon)
 * stacked above the model name caption */
.ledger.with-vis .evlink { grid-template-columns:58px 92px 96px 1fr; }
.ledger .evis {
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    gap:4px;
    align-self:start;
}
.ledger .evis img { max-width:92px; max-height:38px; }
.ledger .evis.ph svg { width:22px; height:22px; color:var(--hairline-strong); }
.ledger .evis .evname {
    font-family:var(--font-display);
    font-weight:600;
    font-size:13px;
    line-height:1.1;
    letter-spacing:.02em;
    text-transform:uppercase;
    color:var(--text-color);
    max-width:92px;
    text-align:center;
    text-wrap:balance;
}
/* Primary action inside a ledger foot (rankings hub): the compact size of the
 * .actbtn pill, so the "full ranking" CTA reads as THE click target of the card */
.ledger-foot .go {
    font-size:11px;
    font-weight:500;
    letter-spacing:.08em;
    padding:7px 14px;
}

/* Editable fields inside a spec table (suggestion form) + honeypot */
table.spec .v input[type="text"],
table.spec .v input[type="url"],
table.spec .v select,
table.spec .v textarea {
    width:100%;
    box-sizing:border-box;
    font:inherit;
    font-size:13px;
    padding:7px 10px;
    border:1px solid var(--hairline-strong);
    border-radius:6px;
    background:var(--panel);
    color:var(--text-color);
}
table.spec .v textarea { min-height:110px; resize:vertical; }
table.spec .v input:focus, table.spec .v select:focus, table.spec .v textarea:focus {
    outline:2px solid var(--signal);
    outline-offset:1px;
}
.formbad { color:var(--bad); }
.honeypot-field {
    position:absolute;
    left:-9999px;
}
/* outgun the .page-flat a:link signal tint — white text on the filled pill */
.page-flat .ledger-foot a.go:link, .page-flat .ledger-foot a.go:visited { color:var(--color-white); }
/* --signal is a light cyan in dark mode; white on it is unreadable (as .actbtn) */
body.dark .page-flat .ledger-foot a.go:link,
body.dark .page-flat .ledger-foot a.go:visited { color:var(--ground); }

.ledger-foot {
    padding:10px 18px;
    border-top:1px solid var(--hairline);
    background:var(--panel-2);
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.1em;
    text-transform:uppercase;
}
/* Two-slot foot: a summary figure on the left, the action pill on the right.
 * The pill never shrinks (its label is nowrap); the summary takes what is left
 * and drops to its own line when the two no longer fit side by side. */
.ledger-foot.duo {
    display:flex;
    flex-wrap:wrap;
    justify-content:space-between;
    align-items:center;
    gap:12px;
}
.ledger-foot.duo > span { flex:1 1 240px; }
.ledger-foot.duo .go { flex:0 0 auto; }
.ledger-foot.duo .ic { margin-right:7px; color:var(--signal); }
/* A card reduced to a single bar — one-line cross-links (the active-conflict
 * tracker on country pages) reuse the foot rather than a bespoke banner, so
 * its divider must not double the card border */
.tablecard > .ledger-foot:only-child { border-top:0; }
.ledger-head .live {
    margin-left:auto;
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.16em;
    color:var(--text-muted);
    display:flex;
    align-items:center;
    gap:7px;
    text-transform:none;
}
/* Pulsing status dot — one primitive: green on live feeds, amber (.hotdot,
 * below with .explore) on the explore rail's hot link */
.live .dot, .explore .hotdot { width:7px; height:7px; border-radius:50%; background:var(--good); animation:pulse 2.4s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:.25; } }
@media (prefers-reduced-motion: reduce) { .live .dot, .cmd-sub .dot, .hotdot { animation:none !important; } }

@media (max-width: 992px) {
    .topgrid { grid-template-columns:repeat(2, 1fr); }
    .topgrid a:nth-child(3n/**/+1) { border-left:1px solid var(--hairline); }
    .topgrid a:nth-child(2n/**/+1) { border-left:none; }
    .afhero { flex-direction:column; gap:14px; }
}
@media (max-width: 576px) {
    .ledger.with-vis .evlink { grid-template-columns:52px 1fr; }
    .ledger .evis { display:none; }
}

/* Two-column card layout for force pages */
.acgrid { display:grid; grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); gap:28px; align-items:start; }
.stack { display:flex; flex-direction:column; gap:28px; }

/* Thumbnail cell in inventory tables */
td.thumb { width:104px; }
td.thumb .tvis {
    width:88px;
    height:40px;
    display:flex;
    align-items:center;
    justify-content:center;
    overflow:hidden;
}
td.thumb img { max-width:84px; max-height:38px; }

/* Flag-emoji fallback inside the hero roundel circle */
.afhero .roundel .fl { font-size:36px; line-height:1; }

/* Same minmax(0, …) as the two-column form above: with a bare 1fr the single
 * track cannot shrink below the min-content width of the cards it holds, and
 * an intrinsically wide child (ordnance scale SVG, chart canvas, profile
 * drawing) pushes the whole page past the viewport. The resulting horizontal
 * scroll also slides the sticky header out of reach on phones. */
@media (max-width: 992px) {
    .acgrid { grid-template-columns:minmax(0, 1fr); }
}

/* Comparison hubs: the cross-hub link card (.hubtools) shares the picker's
 * two-column grid, so once that grid collapses it wedges nine links between the
 * picker and the matchups the visitor actually came for. Rather than hide it —
 * it is the only place those hubs link to each other — dissolve the section and
 * grid wrappers so the card becomes a direct flex child of #content and can be
 * ordered to the end of the page. If :has() is missing the whole rule drops and
 * the layout falls back to the collapsed grid. */
@media (max-width: 768px) {
    #content:has(.hubtools) {
        display:flex;
        flex-direction:column;
    }
    .section:has(> .hubgrid),
    .hubgrid { display:contents; }
    /* .section's own margin goes with it, so the two stacks carry it instead */
    .hubgrid > .stack { margin-top:48px; }
    .hubtools { order:99; }
}


/* Light category subdivisions inside data tables */
table.data tr.subhead td,
.page-flat .tablecard table:not(.spec) tr.subhead td {
    font-family:var(--font-mono);
    font-size:9.5px;
    font-weight:500;
    letter-spacing:.18em;
    text-transform:uppercase;
    color:var(--text-muted);
    background:var(--panel-2);
    padding:6px 18px;
    border-top:1px solid var(--hairline-strong);
}
table.data tbody tr.subhead:hover td,
.page-flat .tablecard table:not(.spec) tbody tr.subhead:hover td { background:var(--panel-2); }

/* Emphasized Active column: display numeral with a fleet-share mini bar below */
table.data td.actv { min-width:120px; }
table.data .actv .actn {
    display:block;
    font-family:var(--font-display);
    font-weight:600;
    font-size:18px;
    line-height:1;
}
table.data .actv .bar { display:block; height:5px; min-width:80px; margin-top:6px; }

/* ---------------- Equipment listings (grid of cards) ---------------- */
.hero { padding:30px 0 8px; }
.hero h1 {
    font-size:clamp(34px, 5vw, 54px);
    line-height:1.02;
    letter-spacing:.01em;
    margin:14px 0 10px;
}
.hero .lede { max-width:62ch; font-size:16px; }
.hero .lede + .lede { margin-top:10px; }
/* Real flag images inside a hero h1 (country comparisons) — emoji flags look
 * off at display sizes */
.hero h1 .h1flag {
    height:.58em;
    width:auto;
    border:1px solid var(--hairline-strong);
    border-radius:3px;
    vertical-align:-.02em;
}

/* Listing hero with a database-status side panel: mono K/V readout + related
 * tool links (replaces the floating text links under the lede) */
.hero.herogrid {
    display:grid;
    grid-template-columns:minmax(0, 1fr) 290px;
    gap:48px;
    /* top-aligned: center would shift H1/panel with the per-page lede and
     * panel heights, breaking cross-listing alignment */
    align-items:start;
}
/* 8px = half the 11px-mono eyebrow row, so the card's top edge sits on the
 * eyebrow's hairline rule */
.herogrid .herostat { margin-top:8px; }
.herostat {
    border-radius:10px;
    padding:6px 18px 10px;
}
.herostat .hs {
    display:flex;
    justify-content:space-between;
    align-items:baseline;
    gap:12px;
    padding:8px 0;
    border-bottom:1px dotted var(--hairline);
    font-family:var(--font-mono);
    font-size:12px;
    letter-spacing:.03em;
}
.herostat .hs .k {
    font-size:10.5px;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.herostat .hs .v { font-variant-numeric:tabular-nums; white-space:nowrap; }
.herostat .hs .v.wrap { white-space:normal; text-align:right; }
.herostat .hs-links { display:flex; flex-direction:column; gap:9px; padding:12px 0 4px; }
.herostat .hs-links a {
    display:flex;
    align-items:center;
    gap:9px;
    font-size:13.5px;
    text-decoration:none;
}
.herostat .hs-links a:hover { text-decoration:underline; }
.herostat .hs-links .ic { width:15px; height:15px; flex:0 0 auto; }
@media (max-width: 992px) {
    .hero.herogrid { grid-template-columns:1fr; gap:24px; }
}

/* Grid ⇄ table view toggle on card listings; preference kept in localStorage */
.console .vtoggle { display:flex; gap:4px; margin-left:14px; }
.console .vtoggle button {
    display:flex;
    align-items:center;
    justify-content:center;
    width:32px;
    height:28px;
    background:transparent;
    border:1px solid var(--hairline-strong);
    border-radius:6px;
    color:var(--text-muted);
    cursor:pointer;
    padding:0;
}
.console .vtoggle button:hover { border-color:var(--signal); color:var(--text-color); }
.console .vtoggle button[aria-pressed="true"] { background:var(--signal); border-color:var(--signal); color:var(--color-white); }
.console .vtoggle .ic { width:15px; height:15px; }
.listwrap .regtable { display:none; margin-top:22px; }
.listwrap.view-table .fleetgrid { display:none; }
.listwrap.view-table .regtable { display:block; }


/* Filter console — single panel replacing stacked chip rows on listing pages:
 * row 1 = category chips (crawlable links) + result count, row 2 = era/origin
 * selects (data-nav → navigate on change) + name search. Long crawlable
 * enumerations (countries, decades) move to the .roster "Browse" section at
 * the bottom of the page. */
.console {
    background:var(--panel);
    border:1px solid var(--hairline);
    border-radius:10px;
    box-shadow:var(--shadow-panel);
    margin:26px 0 0;
}
/* Hosted inside a section (airbases DB filters): section-head provides the
 * gap above, the console provides the gap down to the table */
.section > .console { margin:0 0 20px; }
/* Inside a section (rankings hub geo filter) the next block has no top margin
 * of its own — give the console breathing room below */
.section .console { margin-bottom:22px; }
.console .crow {
    display:flex;
    align-items:center;
    gap:10px;
    flex-wrap:wrap;
    padding:12px 16px;
}
.console .crow + .crow { border-top:1px solid var(--hairline); }
.console .clab {
    font-family:var(--font-mono);
    font-size:10.5px;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
    flex:0 0 auto;
}
.console .crow > .clab { min-width:48px; }
.console .chips { display:flex; flex-wrap:wrap; gap:6px; flex:1; }
.console .chips a,
.mapctl .chips a {
    font-family:var(--font-mono);
    font-size:11px;
    font-weight:500;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text-muted);
    border:1px solid var(--hairline-strong);
    border-radius:6px;
    background:transparent;
    padding:5px 11px;
    white-space:nowrap;
}
.console .chips a:hover,
.mapctl .chips a:hover { border-color:var(--signal); color:var(--text-color); text-decoration:none; }
.console .chips a[aria-current],
.mapctl .chips a[aria-current] { color:var(--color-white); background:var(--signal); border-color:var(--signal); }
.console .csel { display:flex; align-items:center; gap:8px; }
.console .csel + .csel { margin-left:18px; }
.console select,
.console input[type="search"] {
    font-family:var(--font-mono);
    font-size:12px;
    color:var(--text-color);
    background:var(--panel-2);
    border:1px solid var(--hairline-strong);
    border-radius:6px;
    padding:7px 10px;
    max-width:220px;
}
.console select:focus, .console input[type="search"]:focus { outline:2px solid var(--signal); outline-offset:1px; }
.console .csearch { display:flex; flex:1; min-width:200px; justify-content:flex-end; }
.console .csearch input { flex:0 1 240px; border-radius:6px 0 0 6px; border-right:none; max-width:none; }
.console .csearch button {
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text-color);
    background:var(--panel-2);
    border:1px solid var(--hairline-strong);
    border-radius:0 6px 6px 0;
    padding:7px 14px;
    cursor:pointer;
}
.console .csearch button:hover { border-color:var(--signal); color:var(--signal); }
.console .count {
    margin-left:auto;
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.08em;
    color:var(--text-muted);
    font-variant-numeric:tabular-nums;
    white-space:nowrap;
}
/* Facet row (equipment listings): chips on wide screens, a data-nav select once
 * they would stack into a wall. Both sit in the DOM, only one ever displays. */
.console .cnarrow { display:none; }
/* Quick-filter shortcut chips (e.g. airbases' most-requested countries): the
 * wrapper is transparent to the crow-facet flex layout on wide screens, and
 * hides as one unit on narrow screens (see media query) instead of leaving a
 * dangling .clab once its .chips disappear. */
.console .qfilter { display:contents; }

/* Narrow console: the label + count keep the first line, the chips wrap onto a
 * full-width line of their own (sharing it with the label left them a ~200px
 * column, i.e. one chip per line), and every control below goes full width. */
@media (max-width: 768px) {
    .console .crow { padding:10px 12px; row-gap:8px; }
    .console .count { order:1; }
    .console .vtoggle { order:1; margin-left:10px; }
    .console .chips { flex:1 1 100%; order:2; }
    .console .chips a {
        font-size:10.5px;
        letter-spacing:.06em;
        padding:5px 9px;
    }
    /* Only the facet row swaps; the other consoles keep their wrapped chips */
    .console .crow-facet .chips { display:none; }
    .console .crow-facet .qfilter { display:none; }
    .console .crow-facet .cnarrow {
        display:block;
        flex:1 1 100%;
        order:2;
        max-width:none;
    }
    .console .csel { flex:1 1 100%; }
    .console .csel + .csel { margin-left:0; }
    .console .csel select { flex:1; max-width:none; }
    .console .csearch { min-width:100%; }
    .console .csearch input { flex:1; }
}

/* Large flag display inside a tablecard (country page) — centered, capped
 * height so square flags (che, vat) don't become giant blocks */
.flagpanel { display:flex; justify-content:center; padding:26px 20px; }
.flagpanel img {
    max-height:240px;
    max-width:100%;
    width:auto;
    border:1px solid var(--hairline);
    box-shadow:var(--shadow-panel);
}

/* Flag wall — dense tile grid for the flags family listings and "Similar
 * Flags" (includes/flag_wall.html); .wide widens the tiles */
.flagwall {
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(130px, 1fr));
    gap:16px;
}
.flagwall.wide { grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); }
.flagtile {
    display:flex;
    flex-direction:column;
    align-items:center;
    gap:8px;
    text-align:center;
}
.flagtile img {
    height:50px;
    width:auto;
    max-width:100%;
    border-radius:2px;
    box-shadow:0 0 0 1px var(--hairline);
}
.flagtile .name {
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.04em;
    line-height:1.3;
}
.flagtile:hover { text-decoration:none; }
.flagtile:hover img { box-shadow:0 0 0 1px var(--signal); }

/* Flag color pills — the .color-dot / --dot-color primitive of the flags
 * family, also used on country pages */
.color-pills-inline {
    display:inline-flex;
    align-items:center;
    gap:.4rem;
    line-height:1;
}
.color-dot {
    display:inline-block;
    width:20px;
    height:20px;
    border-radius:50%;
    background-color:var(--dot-color);
}
.color-dot--small {
    width:18px;
    height:18px;
}
.color-dot--bordered {
    border:1px solid var(--card-border);
    box-sizing:border-box;
}

/* Order-of-battle composition cells: interpuncts between optional items
 * without leading-separator glitches when the first item is absent */
.oob .citem + .citem::before { content:"· "; color:var(--text-muted); }

/* "Browse" rosters at the bottom of listing pages — crawlable country/decade
 * links with readable labels (flags alone are not enough) */
.roster a { color:var(--text-color); text-decoration:none; }
.roster a:hover { color:var(--signal); }
.roster .sub { color:var(--text-muted); }
.roster .sub a { color:var(--text-muted); }
.roster .sub a:hover { color:var(--signal); }

.fleetgrid {
    display:grid;
    grid-template-columns:repeat(4, 1fr);
    gap:22px;
    margin-top:22px;
}
.accard {
    overflow:hidden;
    display:flex;
    flex-direction:column;
    color:inherit;
    transition:border-color .15s ease;
}
.accard:hover { text-decoration:none; border-color:var(--signal); }
.accard .vis {
    background:
        linear-gradient(var(--hairline) 1px, transparent 1px) 0 0/28px 28px,
        linear-gradient(90deg, var(--hairline) 1px, transparent 1px) 0 0/28px 28px,
        var(--panel-2);
    padding:16px;
    display:flex;
    align-items:center;
    justify-content:center;
    height:124px;
    border-bottom:1px solid var(--hairline);
}
.accard .vis img { max-width:100%; height:auto; max-height:96px; }
.accard .vis .ph { color:var(--hairline-strong); }
.accard .vis .ph svg { width:56px; height:56px; stroke-width:1.1; }
.accard .body { padding:13px 16px 10px; }
.accard .meta {
    font-family:var(--font-mono);
    font-size:9.5px;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}
.accard h3 {
    font-size:21px;
    font-weight:600;
    line-height:1.05;
    letter-spacing:.02em;
    margin:3px 0 0;
    padding:0;
    text-transform:uppercase;
    color:var(--text-color);
}
.accard:hover h3 { color:var(--signal); }
.accard .stats { display:flex; margin-top:auto; border-top:1px solid var(--hairline); }
.accard .stats > span { flex:1; padding:8px 12px 9px; border-left:1px solid var(--hairline); min-width:0; }
.accard .stats > span:first-child { border-left:none; }
.accard .stats .k {
    display:block;
    font-family:var(--font-mono);
    font-size:8.5px;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.accard .stats .v {
    font-family:var(--font-display);
    font-weight:600;
    font-size:16px;
    font-variant-numeric:tabular-nums;
    white-space:nowrap;
    color:var(--text-color);
}
.accard .stats .v small { font-size:11px; color:var(--text-muted); font-weight:500; }
/* Status pill standing in for the numeric value (country aircraft listicles):
 * .chip is inline by default, so its vertical padding needs a block box */
.accard .stats .chip { display:inline-block; margin-top:0; }

@media (max-width: 992px) { .fleetgrid { grid-template-columns:repeat(2, 1fr); } }
@media (max-width: 576px) { .fleetgrid { grid-template-columns:1fr; }  }

/* News card illustration: full-bleed image on top of the card */
.newsgrid { display:grid; grid-template-columns:repeat(3, 1fr); gap:24px; }
/* Article hero illustration: capped to the reading column and flush with it */
figure.tablecard.artfig { max-width:78ch; }
.newscard {
    padding:20px 22px 18px;
    display:flex;
    flex-direction:column;
    gap:10px;
    position:relative;
    overflow:hidden;
}
.newscard::before {
    content:"";
    position:absolute;
    top:0; left:0; right:0;
    height:2px;
    background:linear-gradient(90deg, var(--bar-a), var(--bar-b) 60%, transparent);
}
.newscard .thumb { margin:-20px -22px 0; display:block; }
.newscard .thumb img { width:100%; height:150px; object-fit:cover; display:block; }
.newscard .meta {
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
    display:flex;
    gap:10px;
}
.newscard h3 { font-size:19px; line-height:1.15; margin:0; padding:0; }
.newscard h3 a { color:var(--text-color); }
.newscard h3 a:hover { color:var(--signal); text-decoration:none; }
.newscard p { margin:0; font-size:13px; line-height:1.55; color:var(--text-muted); }
.newscard .flags { margin-top:auto; font-size:15px; }
@media (max-width: 992px) { .newsgrid { grid-template-columns:1fr; } }

/* Further reading: affiliate book module on conflict trackers and news articles
 * (world/affiliate.py). Shared by the titled-section wrapper and the conflict
 * rail, hence no .page-flat scoping. .nocover is set by the module's own script
 * when Amazon serves no real
 * cover, so the card drops the image column instead of showing an empty box. */
/* auto-fit rather than a viewport breakpoint: the conflict tracker puts this
 * module in a ~440px side rail at full desktop width, where a fixed 3-column grid
 * squeezes the blurbs to one word per line. Track count follows the container. */
.bookrow { display:grid; grid-template-columns:repeat(auto-fit, minmax(260px, 1fr)); gap:24px; }
.bookcard {
    display:grid;
    grid-template-columns:72px minmax(0, 1fr);
    gap:16px;
    padding:18px 20px;
}
.bookcard:hover { border-color:var(--signal); }
.bookcard .cover {
    display:block;
    width:72px;
    aspect-ratio:2 / 3;
    background:var(--panel-2);
    border:1px solid var(--hairline);
    border-radius:2px;
    overflow:hidden;
}
.bookcard .cover img {
    display:block;
    width:100%;
    height:100%;
    object-fit:cover;
}
.bookcard.nocover { grid-template-columns:minmax(0, 1fr); }
.bookcard.nocover .cover { display:none; }
.bookmeta { display:flex; flex-direction:column; gap:6px; }
.bookcard h3 { font-size:16px; line-height:1.2; margin:0; padding:0; }
.bookcard h3 a { color:var(--text-color); }
.bookcard h3 a:hover { color:var(--signal); text-decoration:none; }
.bookcard .byline {
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.bookcard p { margin:0; font-size:13px; line-height:1.55; color:var(--text-muted); }
.affnote {
    margin:14px 0 0;
    font-size:12px;
    line-height:1.5;
    color:var(--text-muted);
}

/* Conflict tracker: hero arrangement and event feed with a compact reading rail. */
.hero.conflict-hero {
    grid-template-areas:
        "heading status"
        "overview overview";
}
.conflict-heading { grid-area:heading; }
.conflict-overview { grid-area:overview; margin-top:0; }
.conflict-hero > .herostat { grid-area:status; }
.conflict-event-layout.with-reading {
    display:grid;
    grid-template-columns:minmax(0, 1fr) minmax(280px, 340px);
    column-gap:24px;
    align-items:start;
}
.conflict-event-layout.with-reading > .console,
.conflict-event-layout.with-reading > .ledger { grid-column:1; }
.conflict-event-reading { grid-column:2; grid-row:1 / span 2; margin-top:26px; }
.conflict-event-reading .bookrow { grid-template-columns:minmax(0, 1fr); gap:12px; }
@media (min-width: 577px) {
    .conflict-event-layout .ledger.with-vis.txtvis .evlink {
        grid-template-columns:58px minmax(120px, 150px) 96px 1fr;
    }
}
@media (max-width: 1200px) {
    .conflict-event-layout.with-reading { grid-template-columns:minmax(0, 1fr); }
    .conflict-event-reading { grid-column:1; grid-row:auto; margin-top:48px; }
}
@media (max-width: 992px) {
    .hero.conflict-hero {
        grid-template-areas:
            "heading"
            "overview"
            "status";
    }
}

/* Force Balance: two-side face-off card on the conflict tracker. Side colors
 * arrive as --fb-a / --fb-b (CSS variable injection from ConflictParty.chart_color);
 * the mirrored left column reuses the .bar primitive flipped with scaleX(-1). */
.forcebal .fb-head {
    display:grid;
    grid-template-columns:1fr auto 1fr;
    align-items:center;
    gap:12px;
    padding:14px 16px 10px;
    border-bottom:1px solid var(--hairline);
}
.forcebal .fb-side {
    display:flex;
    flex-direction:column;
    align-items:flex-end;
    gap:2px;
    min-width:0;
}
.forcebal .fb-side + .fb-vs + .fb-side { align-items:flex-start; }
.forcebal .fb-side strong { font-family:var(--font-display); font-size:15px; }
.forcebal .fb-side:first-child strong { color:var(--fb-a); }
.forcebal .fb-side:last-child strong { color:var(--fb-b); }
.forcebal .fb-flags { font-size:14px; letter-spacing:2px; }
.forcebal .fb-count {
    font-family:var(--font-mono);
    font-size:10px;
    color:var(--text-muted);
    text-transform:uppercase;
}
.forcebal .fb-vs {
    font-family:var(--font-mono);
    font-size:11px;
    color:var(--text-muted);
    text-transform:uppercase;
}
.forcebal .fb-rows {
    list-style:none;
    margin:0;
    padding:6px 16px 10px;
}
.forcebal .fb-rows li {
    display:grid;
    grid-template-columns:minmax(52px, auto) minmax(0, 1fr) minmax(96px, auto) minmax(0, 1fr) minmax(52px, auto);
    align-items:center;
    gap:10px;
    padding:7px 0;
}
.forcebal .fb-rows li + li { border-top:1px solid var(--hairline); }
.forcebal .fb-rows .bar { min-width:0; height:6px; }
.forcebal .fb-left { transform:scaleX(-1); --bar-a:var(--fb-a); --bar-b:var(--fb-a); }
.forcebal .fb-right { --bar-a:var(--fb-b); --bar-b:var(--fb-b); }
.forcebal .fb-val {
    font-family:var(--font-mono);
    font-size:12px;
    white-space:nowrap;
}
.forcebal .fb-val:first-child { text-align:right; }
.forcebal .fb-val:last-child { text-align:left; }
.forcebal .fb-lab {
    display:flex;
    flex-direction:column;
    align-items:center;
    text-align:center;
    font-size:11px;
    text-transform:uppercase;
    letter-spacing:.04em;
    color:var(--text-muted);
}
.forcebal .fb-lab small {
    font-size:9px;
    text-transform:none;
    letter-spacing:0;
    color:var(--text-muted);
    opacity:.75;
}
.forcebal .ledger-foot .go { margin-left:8px; }

/* Key-event highlight in the conflict ledgers: the heaviest single losses
 * (view sets is_key) get an amber inset rule and a crosshair mark. */
.ledger li.key { box-shadow:inset 3px 0 0 var(--amber); background:var(--amber-soft); }
.ledger li.key .evlink { position:relative; padding-right:40px; }
.ledger li.key .keymark {
    position:absolute;
    top:50%;
    right:14px;
    transform:translateY(-50%);
    color:var(--amber);
    line-height:1;
}

/* Situation report grid: give the belligerent table the room its numeric
 * columns need instead of spilling into the .tscroll. */
.sitgrid { grid-template-columns:minmax(0, 1.12fr) minmax(0, 1fr); }
.sitgrid table.data td,
.sitgrid table.data th { padding-left:12px; padding-right:12px; }
.sitgrid table.data td.actv { min-width:96px; }
.sitgrid table.data .actv .bar { min-width:56px; }
@media (max-width: 992px) {
    .sitgrid { grid-template-columns:minmax(0, 1fr); }
}
@media (max-width: 576px) {
    .forcebal .fb-rows li { grid-template-columns:minmax(44px, auto) minmax(0, 1fr) minmax(72px, auto) minmax(0, 1fr) minmax(44px, auto); gap:6px; }
    .forcebal .fb-val { font-size:11px; }
    .forcebal .fb-lab { font-size:10px; }
}

.flagimg {
    width:26px;
    height:18px;
    object-fit:cover;
    border-radius:2px;
    box-shadow:0 0 0 1px var(--hairline);
    flex:none;
}


/* ---------------- Homepage ---------------- */
.board {
    display:grid;
    grid-template-columns:repeat(6, 1fr);
    margin-top:34px;
    border-top:1px solid var(--hairline-strong);
    border-bottom:1px solid var(--hairline);
}
.board a {
    display:flex;
    flex-direction:column;
    gap:2px;
    padding:20px 20px 18px 20px;
    color:inherit;
    border-left:1px solid var(--hairline);
}
.board a:first-child { border-left:none; padding-left:0; }
.board a:hover { text-decoration:none; }
.board .k {
    font-family:var(--font-mono);
    font-size:10.5px;
    font-weight:500;
    letter-spacing:.18em;
    text-transform:uppercase;
    color:var(--text-muted);
    display:flex;
    align-items:center;
    gap:8px;
}
.board .k svg { color:var(--signal); }
.board .n {
    font-family:var(--font-display);
    font-weight:600;
    font-size:clamp(30px, 3.2vw, 44px);
    line-height:1.05;
    font-variant-numeric:tabular-nums;
    color:var(--text-color);
}
.board a:hover .n { color:var(--signal); }
.board .d { font-size:12.5px; color:var(--text-muted); }

.sitrep { display:grid; grid-template-columns:1fr 1fr; gap:28px; }

.explore { display:flex; flex-wrap:wrap; gap:10px; }
.explore a {
    display:inline-flex;
    align-items:center;
    gap:9px;
    font-family:var(--font-display);
    font-weight:500;
    font-size:16px;
    letter-spacing:.04em;
    color:var(--text-color);
    background:var(--panel);
    border:1px solid var(--hairline);
    border-radius:4px;
    padding:9px 16px 10px;
    text-transform:uppercase;
}
.explore a svg { color:var(--signal); }
.explore a:hover { text-decoration:none; border-color:var(--signal); color:var(--signal); }
.explore a.hot { border-color:color-mix(in srgb, var(--amber) 45%, var(--hairline)); }
.explore .hotdot { background:var(--amber); animation-duration:2s; }


@media (max-width: 992px) {
    .sitrep { grid-template-columns:1fr; }
}
/* Three-column board, tablet band only: the 3n+1 hairline rule outranks the
 * plain .board a below it, so left unbounded it would survive into the
 * two-column layout and strip the 4th tile's separator. */
@media (min-width: 577px) and (max-width: 992px) {
    .board { grid-template-columns:repeat(3, 1fr); }
    .board a { border-left:1px solid var(--hairline); border-top:1px solid var(--hairline); }
    .board a:nth-child(3n + 1) { border-left:none; padding-left:0; }
    .board a:nth-child(-n+3) { border-top:none; }
}
@media (max-width: 576px) {
    /* Row hairlines too, otherwise the six tiles read as a loose pile rather
     * than a grid once they wrap onto three rows */
    .board { grid-template-columns:repeat(2, 1fr); }
    .board a {
        padding:14px 14px 12px;
        border-left:1px solid var(--hairline);
        border-top:1px solid var(--hairline);
    }
    .board a:nth-child(odd) { border-left:none; padding-left:0; }
    .board a:nth-child(-n+2) { border-top:none; }
    .board .n { font-size:28px; }
    .board .d { font-size:11.5px; }
}


/* Navy events: air-style with-vis rows without ship renders — the vessel
 * label takes the profile column, widened for class names */
.ledger.with-vis.txtvis .evlink { grid-template-columns:58px minmax(150px, 200px) 96px 1fr; }
.ledger.with-vis.txtvis .evis .evname { max-width:none; }

/* Full-width event rows: date | flag | country+qty | description | status */
.ledger.evrows .evlink {
    grid-template-columns:58px 30px minmax(120px, 160px) 1fr auto;
    gap:14px;
    align-items:center;
}
.ledger.evrows .evwho { display:flex; flex-direction:column; gap:1px; min-width:0; }
.ledger.evrows .cty {
    font-weight:600;
    font-size:13.5px;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}
.ledger.evrows .qty {
    font-family:var(--font-mono);
    font-size:10.5px;
    color:var(--signal);
    font-variant-numeric:tabular-nums;
}
.ledger.evrows .chip { justify-self:end; margin-top:0; }
.ledger.evrows .date { padding-top:0; }
/* Narrow evrows: date + status on line 1, then the conflict-page reading — flag
 * emoji, bold country, interpunct, description — on a full-width line below.
 * The country cannot simply move: it is a sibling grid child, so it is dropped
 * here and re-emitted from data-who as generated content. Its own column was
 * also what broke the previous layout — nowrap, it sized the 1fr track and
 * boxed the description into it, costing the text the date column's width. */
@media (max-width: 768px) {
    .ledger.evrows .evlink { grid-template-columns:auto minmax(0, 1fr); row-gap:4px; }
    .ledger.evrows .flagimg,
    .ledger.evrows .fl,
    .ledger.evrows .evwho { display:none; }
    .ledger.evrows .date { grid-area:1 / 1; }
    .ledger.evrows .date .yr { display:inline; margin-left:4px; }
    .ledger.evrows .chip { grid-area:1 / 2; justify-self:end; }
    .ledger.evrows .txt { grid-column:1 / -1; grid-row:2; }
    .ledger.evrows .txt[data-who]::before { content:attr(data-who) " · "; font-weight:600; }
}

/* Homepage hero: title and lede forced on a single line at desktop widths */
.hero-tight h1 { font-size:clamp(24px, 3.7vw, 46px); white-space:nowrap; }
.hero-tight .lede { max-width:none; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
@media (max-width: 768px) {
    .hero-tight h1, .hero-tight .lede { white-space:normal; }
    .hero-tight .lede { overflow:visible; }
}

/* Homepage sitrep: fixed row height so the two ledgers stay row-aligned */
.sitrep .ledger .evlink { min-height:95px; }
.sitrep .ledger li { height:96px; overflow:hidden; }
.sitrep .ledger .txt {
    display:-webkit-box;
    -webkit-line-clamp:4;
    -webkit-box-orient:vertical;
    overflow:hidden;
}
/* Below 992px the two sitrep ledgers stack, so there is no row to align to and
 * the locked height just truncates the country name mid-word. */
@media (max-width: 992px) {
    .sitrep .ledger li { height:auto; overflow:visible; }
    .sitrep .ledger .evlink { min-height:0; }
    .sitrep .ledger .txt { -webkit-line-clamp:3; }
}
/* Narrow ledgers: date and status on the first line, the profile stack and the
 * description each on a full-width line of their own. */
@media (max-width: 576px) {
    /* Date on one line: the stacked layout below gives it an auto column shared
     * with the status chip. .evrows is excluded here only because it stacks from
     * 768px — it sets the same rule at its own breakpoint. */
    .ledger:not(.evrows) .date .yr { display:inline; margin-left:4px; }
    /* Applies to every ledger except .evrows, which owns its own layout from
     * 768px down. The txtvis selector is spelled out because its four-class
     * desktop rule would otherwise outrank this one and keep a 4-column grid
     * on a 400px screen — that is what squeezed the text to one word per line. */
    .ledger:not(.evrows) .evlink,
    .ledger.with-vis.txtvis .evlink { grid-template-columns:auto minmax(0, 1fr); row-gap:6px; }
    .ledger:not(.evrows) .date { grid-area:1 / 1; }
    .ledger:not(.evrows) .chip {
        grid-area:1 / 2;
        justify-self:end;
        margin-top:0;
    }
    .ledger:not(.evrows) .evis {
        grid-column:1 / -1;
        justify-content:flex-start;
        gap:10px;
        height:auto;
    }
    .ledger:not(.evrows) .evis .evname { max-width:none; }
    .ledger:not(.evrows) .txt { grid-column:1 / -1; }
    /* .geo carries no status chip, so the second column of the stacked layout
     * is free — the base name stays beside its distance instead of dropping to
     * a line of its own and doubling the card's height. Same specificity as the
     * rule above, so it has to sit after it. */
    .ledger.geo .txt { grid-column:2; }
}

/* --- Coalition Builder (hub picker + comparison page) --- */
.coalbuild {
    display:grid;
    grid-template-columns:minmax(0, 1fr) auto minmax(0, 1fr);
    gap:14px;
    align-items:stretch;
}
.coalbuild .vsmid {
    display:flex;
    align-items:center;
    color:var(--text-muted);
}
.coalbuild .vsmid .ic { width:22px; height:22px; color:var(--signal); }
@media (max-width: 768px) {
    .coalbuild { grid-template-columns:minmax(0, 1fr); }
    .coalbuild .vsmid { justify-content:center; }
}
.coalpanel {
    border:1px solid var(--hairline);
    border-radius:8px;
    padding:12px 14px;
    display:flex;
    flex-direction:column;
    gap:10px;
}
.coalpanel .plabel {
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.18em;
    text-transform:uppercase;
    color:var(--text-muted);
    display:flex;
    justify-content:space-between;
    align-items:baseline;
}
.coalpanel .plabel button {
    background:none;
    border:none;
    padding:0;
    font:inherit;
    color:var(--signal);
    cursor:pointer;
    letter-spacing:normal;
    text-transform:none;
}
.coalpresets { display:flex; flex-wrap:wrap; gap:6px; }
.coalpresets button {
    font-family:var(--font-mono);
    font-size:11px;
    padding:3px 9px;
    border:1px solid var(--hairline);
    border-radius:999px;
    background:var(--panel);
    color:var(--text);
    cursor:pointer;
}
.coalpresets button:hover { border-color:var(--signal); }
.coalpresets button.on {
    background:var(--signal-soft);
    border-color:var(--signal);
    color:var(--signal);
}
.coaltags { display:flex; flex-wrap:wrap; gap:6px; min-height:28px; }
.coaltags .coaltag {
    display:inline-flex;
    align-items:center;
    gap:5px;
    font-size:12.5px;
    padding:3px 8px;
    border:1px solid var(--hairline);
    border-radius:6px;
    background:var(--panel-2);
}
.coaltags .coaltag.ally { border-color:var(--signal); color:var(--signal); }
.coaltags .coaltag b { font-weight:600; }
.coaltags .coaltag button {
    background:none;
    border:none;
    padding:0 0 0 2px;
    color:var(--text-muted);
    cursor:pointer;
    font-size:13px;
    line-height:1;
}
.coaltags .coaltag button:hover { color:var(--bad); }
.coalsearch { position:relative; }
.coalsearch input {
    box-sizing:border-box;
    width:100%;
    padding:7px 10px;
    font-size:13.5px;
    border:1px solid var(--hairline);
    border-radius:6px;
    background:var(--panel);
    color:var(--text);
}
.coalsearch input:focus { outline:2px solid var(--signal); outline-offset:1px; }
.coalsearch .results {
    position:absolute;
    top:calc(100% + 4px);
    left:0;
    right:0;
    z-index:30;
    background:var(--panel);
    border:1px solid var(--hairline);
    border-radius:6px;
    box-shadow:var(--shadow-panel);
    max-height:240px;
    overflow-y:auto;
}
.coalsearch .results:empty { display:none; }
.coalsearch .results button {
    display:flex;
    width:100%;
    align-items:center;
    gap:8px;
    padding:7px 10px;
    background:none;
    border:none;
    font-size:13.5px;
    color:var(--text);
    cursor:pointer;
    text-align:left;
}
.coalsearch .results button:hover,
.coalsearch .results button.sel { background:var(--signal-soft); }
.coalsearch .results .dim { margin-left:auto; font-size:11.5px; }
.coalstats {
    display:grid;
    grid-template-columns:repeat(3, minmax(0, 1fr));
    gap:6px 12px;
    border-top:1px dashed var(--hairline);
    padding-top:10px;
    margin-top:auto;
}
.coalstats .cs { display:flex; flex-direction:column; }
.coalstats .k {
    font-family:var(--font-mono);
    font-size:9.5px;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.coalstats .v { font-family:var(--font-display); font-size:17px; }
.coalgo { text-align:center; margin-top:14px; }

/* Member roster: six columns must fit the half-width card without spilling
 * into the .tscroll — narrow the budget-share column and tighten cell
 * padding, same recipe as the .sitgrid belligerent table. */
/* The .page-flat prefix matches the specificity of the tablecard cell
 * padding rules (`.page-flat .tablecard table:not(.spec) td`) — without it
 * the 18px padding wins and the six columns spill into the .tscroll. */
.page-flat .tablecard table.mroster td,
.page-flat .tablecard table.mroster th { padding-left:8px; padding-right:8px; }
table.data.mroster td.actv { min-width:76px; }
table.data.mroster .actv .bar { min-width:40px; }

/* Nuclear-power marker in the roster: the ☢ glyph needs body-size type to
 * read as a symbol rather than a smudge inside the 9.5px chip. */
.chip.nuke {
    font-size:13px;
    line-height:1.2;
    padding:1px 6px;
}

/* Comparison page hero: one aligned row per side (flag strip | name + count),
 * plus the shared-member notice below. */
.coalsides {
    display:grid;
    grid-template-columns:auto minmax(0, 1fr);
    gap:10px 14px;
    align-items:center;
    justify-content:start;
    margin:14px 0 4px;
}
.coalsides .cname { font-size:15px; color:var(--text-muted); }
.coalsides .cname b { color:var(--text); font-weight:600; }
@media (max-width: 576px) {
    .coalsides { grid-template-columns:minmax(0, 1fr); gap:4px; }
    .coalsides .cname { margin-bottom:8px; }
}
.sharednote { font-size:14.5px; color:var(--text-muted); }
.sharednote .ic {
    width:15px;
    height:15px;
    vertical-align:-2px;
    margin-right:4px;
    color:var(--amber);
}
.flagstrip { display:inline-flex; align-items:center; gap:4px; vertical-align:-4px; }
.flagstrip img {
    height:22px;
    width:auto;
    border-radius:2px;
    box-shadow:0 0 0 1px var(--hairline);
}
.flagstrip .more {
    font-family:var(--font-mono);
    font-size:11px;
    color:var(--text-muted);
    margin-left:2px;
}

/* --- Nuclear Blast Simulator (/nuclear/simulator/) --- */
.nukesim {
    display:grid;
    grid-template-columns:320px minmax(0, 1fr);
    gap:16px;
    padding:14px 18px 16px;
}
@media (max-width: 992px) {
        .nukesim { grid-template-columns:minmax(0, 1fr); }
}
.nukesim-side { display:flex; flex-direction:column; gap:8px; }
.nukesim-side .nklabel {
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.18em;
    text-transform:uppercase;
    color:var(--text-muted);
    margin-top:4px;
}
.nukesim-side input[type="number"],
.nukesim-side select {
    box-sizing:border-box;
    width:100%;
    padding:7px 10px;
    font-size:13.5px;
    border:1px solid var(--hairline);
    border-radius:6px;
    background:var(--panel);
    color:var(--text);
}
.nukesim-side input:focus,
.nukesim-side select:focus { outline:2px solid var(--signal); outline-offset:1px; }
.nkyield { display:flex; gap:6px; }
.nkyield input { flex:1; min-width:0; }
.nkyield select { width:auto; }
.nkmeta { font-size:12.5px; color:var(--text-muted); }
.nkmeta:empty { display:none; }

/* Quick-pick chips (iconic weapons, smallest to largest) */
.nkquick { display:flex; flex-wrap:wrap; gap:6px; }
.nkquick button {
    display:inline-flex;
    align-items:baseline;
    gap:5px;
    font-size:12px;
    padding:4px 10px;
    border:1px solid var(--hairline);
    border-radius:999px;
    background:var(--panel);
    color:var(--text);
    cursor:pointer;
}
.nkquick button small { font-family:var(--font-mono); font-size:10px; color:var(--text-muted); }
.nkquick button:hover { border-color:var(--signal); }
.nkquick button.on { background:var(--signal-soft); border-color:var(--signal); color:var(--signal); }
.nkquick button.on small { color:var(--signal); }

/* Searchable weapon combobox */
.nkpicker { position:relative; }
.nkpicker-trigger {
    display:flex;
    align-items:center;
    gap:8px;
    width:100%;
    padding:8px 12px;
    font-size:14px;
    text-align:left;
    border:1px solid var(--hairline);
    border-radius:6px;
    background:var(--panel);
    color:var(--text);
    cursor:pointer;
}
.nkpicker-trigger:hover { border-color:var(--signal); }
.nkpicker-trigger[aria-expanded="true"] { border-color:var(--signal); outline:2px solid var(--signal); outline-offset:1px; }
.nkpicker-trigger .cur { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.nkpicker-trigger::after {
    content:"";
    flex:0 0 auto;
    width:0;
    height:0;
    border-left:4px solid transparent;
    border-right:4px solid transparent;
    border-top:5px solid currentColor;
    opacity:.55;
}
.nkpicker-pop {
    position:absolute;
    top:calc(100% + 4px);
    left:0;
    right:0;
    z-index:40;
    background:var(--panel);
    border:1px solid var(--hairline);
    border-radius:8px;
    box-shadow:var(--shadow-panel);
    overflow:hidden;
}
.nkpicker-search {
    box-sizing:border-box;
    width:100%;
    padding:9px 12px;
    font-size:13.5px;
    border:0;
    border-bottom:1px solid var(--hairline);
    background:var(--panel);
    color:var(--text);
}
.nkpicker-search:focus { outline:none; }
.nkpicker-list { max-height:288px; overflow-y:auto; }
.nkopt-group {
    position:sticky;
    top:0;
    font-family:var(--font-mono);
    font-size:9.5px;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--text-muted);
    background:var(--panel);
    padding:8px 12px 3px;
}
.nkopt {
    display:flex;
    align-items:baseline;
    justify-content:space-between;
    gap:10px;
    padding:6px 12px;
    font-size:13.5px;
    color:var(--text);
    cursor:pointer;
}
.nkopt .y { flex:0 0 auto; font-family:var(--font-mono); font-size:11px; color:var(--text-muted); }
.nkopt:hover,
.nkopt.hl { background:var(--signal-soft); }
.nkopt.sel .nm { color:var(--signal); font-weight:600; }
.nkopt[hidden],
.nkopt-group[hidden] { display:none; }
.nkpicker-empty { padding:12px; font-size:13px; color:var(--text-muted); }
.nklink {
    align-self:flex-start;
    padding:0;
    font:inherit;
    font-size:12.5px;
    background:none;
    border:none;
    color:var(--signal);
    cursor:pointer;
    text-decoration:underline;
}
.nkburst { display:flex; gap:6px; }
.nkburst button,
.nkjumps button {
    font-family:var(--font-mono);
    font-size:11px;
    padding:3px 9px;
    border:1px solid var(--hairline);
    border-radius:999px;
    background:var(--panel);
    color:var(--text);
    cursor:pointer;
}
.nkburst button:hover,
.nkjumps button:hover { border-color:var(--signal); }
.nkburst button.on {
    background:var(--signal-soft);
    border-color:var(--signal);
    color:var(--signal);
}
.nkjumps { display:flex; flex-wrap:wrap; gap:6px; margin-bottom:8px; }
.nkmapwrap { position:relative; }
.nukesim-map { height:520px; border-radius:8px; z-index:0; }
@media (max-width: 768px) {
        .nukesim-map { height:380px; }
}
/* The map is a target picker before it is a map: a crosshair says "click to
 * place a point", where Leaflet's default grab hand promised panning and made
 * the click feel like a misfire. Dragging still pans. */
.nukesim-map.leaflet-grab { cursor:crosshair; }
/* Instruction badge over the map, retired once ground zero is set. Sits above
 * the tile panes (z 400) but below the zoom controls (z 800). */
.nkmaphint {
    position:absolute;
    top:12px;
    left:50%;
    transform:translateX(-50%);
    z-index:500;
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text);
    background:var(--panel);
    border:1px solid var(--hairline-strong);
    border-radius:999px;
    padding:6px 14px;
    box-shadow:var(--shadow-panel);
    pointer-events:none;
    white-space:nowrap;
}
/* Narrow maps: the badge would sit on top of the zoom control, so it moves
 * below the map body, clearing the Leaflet attribution strip. */
@media (max-width: 576px) {
        .nkmaphint {
            top:auto;
            bottom:26px;
            font-size:10px;
            padding:5px 10px;
        }
}
.nknote { font-size:12px; color:var(--text-muted); margin:10px 0 0; }
.nkhint { font-size:13px; color:var(--text-muted); margin:0; }
.nukerings { display:flex; flex-direction:column; gap:9px; }
.nkring {
    display:grid;
    grid-template-columns:12px minmax(0, 1fr);
    gap:8px;
    font-size:13px;
    line-height:1.35;
}
.nkring i {
    width:11px;
    height:11px;
    border-radius:50%;
    background:var(--dot-color, var(--text-muted));
    margin-top:3px;
}
.nkring .r { font-family:var(--font-mono); font-size:11.5px; color:var(--text-muted); }
.nkring small { display:block; color:var(--text-muted); font-size:11.5px; }
/* Staggered fade-in replayed on every detonation (the .in class is toggled
 * by nuclear-simulator.js after it rebuilds the ring rows). */
@keyframes nkfade { from { opacity:0; transform:translateY(5px); } to { opacity:1; transform:none; } }
.nukerings.in .nkring { animation:nkfade .3s ease both; }
.nukerings.in .nkring:nth-child(2) { animation-delay:.05s; }
.nukerings.in .nkring:nth-child(3) { animation-delay:.10s; }
.nukerings.in .nkring:nth-child(4) { animation-delay:.15s; }
.nukerings.in .nkring:nth-child(5) { animation-delay:.20s; }
.nukerings.in .nkring:nth-child(6) { animation-delay:.25s; }
@media (prefers-reduced-motion: reduce) {
        .nukerings.in .nkring { animation:none; }
}
/* "Simulate this weapon" card on nuclear missile / bomb detail pages: prose
 * line + the shared .arm chip link, so it reads like the sibling cards. */
.simcta p { margin:0; font-size:14px; line-height:1.5; }

/* Year x month intensity grid (standoff metric stats pages). Cell shading is
 * driven per instance through --heat (0..1); color-mix against the bar token
 * keeps both themes right, and the 62% cap keeps the numerals readable on the
 * hottest cells. The peak cell is outlined, the current partial month italic.
 * Selector spelled out to tie the `.page-flat .tablecard table:not(.spec) td`
 * background reset (03) on specificity — this rule sits later, so it wins. */
table.data.heatmap td.hm {
    text-align:right;
    font-family:var(--font-mono);
    font-size:12px;
    background:color-mix(in srgb, var(--bar-a) calc(var(--heat, 0) * 62%), transparent);
}
table.data.heatmap td.hm.peak { font-weight:700; }
table.data.heatmap td.hm.cur {
    outline:2px solid var(--signal);
    outline-offset:-2px;
    font-style:italic;
}

/* Nuclear world map — includes/nuclear_map.html, generated by
   scripts/gen_nuclear_map.py. Status fills read the theme tokens, so dark
   mode needs no override; tiny countries carry a clickable centroid dot. */
.nucmap { padding:12px 16px 4px; }
.nucmap svg { display:block; width:100%; height:auto; }
.nucmap .land { fill:var(--panel-2); }
.nucmap .cc {
    stroke:var(--panel);
    stroke-width:.4;
    stroke-linejoin:round;
}
.nucmap .active { fill:var(--bar-a); }
.nucmap .host { fill:var(--amber); }
.nucmap .acquiring { fill:var(--bad); }
.nucmap .former { fill:var(--good); }
.nucmap .dot { stroke:var(--panel); stroke-width:1; }
.nucmap a:hover .cc, .nucmap a:hover .dot { filter:brightness(1.18); }

/* Delivery-leg pictograms (nuclear hub table + country statband) */
.legs { display:inline-flex; gap:8px; align-items:center; }

/* Host-base static map atop the nuclear base card */
.basemap {
    display:block;
    width:100%;
    height:auto;
    border-bottom:1px solid var(--hairline);
}

/* --- Guide pages (/guides/) — three components, geometry from
 * world/views/guide_views.py builders (the svg_charts.py contract: Python
 * computes positions as percentages / viewBox units, CSS only styles).
 * Positions arrive via CSS-variable injection (--x, --w). --- */

/* .famtimeline: one lane per equipment family, one dot per service entry,
 * era bands above and a decade axis below. */
.famtimeline { padding:18px 18px 6px; }
.ftl-eras { position:relative; height:26px; margin-left:110px; }
.ftl-eras span {
    position:absolute;
    left:var(--x);
    width:var(--w);
    top:0;
    bottom:0;
    display:flex;
    align-items:center;
    justify-content:center;
    font-family:var(--font-mono);
    font-size:9.5px;
    letter-spacing:.1em;
    text-transform:uppercase;
    color:var(--text-muted);
    border-left:1px dashed var(--hairline-strong);
    overflow:hidden;
    white-space:nowrap;
    padding:0 4px;
}
.ftl-lane {
    display:grid;
    grid-template-columns:110px 1fr;
    align-items:center;
    min-height:36px;
    border-top:1px solid var(--hairline);
}
.ftl-lane .fam { font-family:var(--font-mono); font-size:11px; font-weight:600; letter-spacing:.06em; }
.ftl-lane .fam small {
    display:block;
    font-weight:400;
    color:var(--text-muted);
    font-size:9.5px;
    letter-spacing:.03em;
}
.ftl-track { position:relative; height:36px; }
.ftl-track::before { content:""; position:absolute; left:0; right:0; top:50%; height:1px; background:var(--hairline); }
.ftl-dot {
    position:absolute;
    top:50%;
    left:var(--x);
    transform:translate(-50%,-50%);
    width:9px;
    height:9px;
    border-radius:50%;
    background:var(--signal);
    border:2px solid var(--panel);
    box-shadow:0 0 0 1px var(--signal);
}
.ftl-dot.hollow { background:var(--panel); box-shadow:0 0 0 1px var(--text-muted); }
/* Dots are links; the ::before pad grows the hit area beyond the 9px visual */
a.ftl-dot::before { content:""; position:absolute; inset:-8px; border-radius:50%; }
a.ftl-dot:hover { width:13px; height:13px; }
.ftl-lbl {
    position:absolute;
    left:var(--x);
    top:1px;
    transform:translateX(-50%);
    font-family:var(--font-mono);
    font-size:9px;
    color:var(--text-muted);
    white-space:nowrap;
}
.ftl-lbl.below { top:auto; bottom:1px; }
.ftl-axis { position:relative; height:22px; margin-left:110px; }
.ftl-axis span {
    position:absolute;
    left:var(--x);
    transform:translateX(-50%);
    top:4px;
    font-family:var(--font-mono);
    font-size:10px;
    color:var(--text-muted);
}
.ftl-legend {
    display:flex;
    gap:18px;
    padding:10px 18px 14px;
    font-family:var(--font-mono);
    font-size:10.5px;
    color:var(--text-muted);
    flex-wrap:wrap;
}
.ftl-legend i { display:inline-block; width:9px; height:9px; border-radius:50%; margin-right:6px; vertical-align:-1px; }
.ftl-legend .full i { background:var(--signal); }
.ftl-legend .empty i { background:var(--panel); box-shadow:inset 0 0 0 1px var(--text-muted); }
@media (max-width:768px) {
    .ftl-lane { grid-template-columns:72px 1fr; }
    .ftl-eras, .ftl-axis { margin-left:72px; }
    .ftl-lbl { display:none; }
}

/* .lineage: generation tree, server-computed SVG (nodes link to detail
 * pages; dashed nodes are documented systems without a page yet).
 * --lw is the viewBox width, injected per instance: capping the rendered
 * width at 1.25px per viewBox unit keeps the text size consistent across
 * guides — otherwise a narrow tree stretches to the card and blows up. */
.lineage { padding:10px 8px 4px; overflow-x:auto; }
.lineage svg {
    display:block;
    width:100%;
    height:auto;
    min-width:560px;
    max-width:calc(var(--lw, 900) * 1.25px);
    margin:0 auto;
}
.lineage .node rect { fill:var(--panel-2); stroke:var(--hairline-strong); }
.lineage a:hover .node rect { stroke:var(--signal); }
.lineage .node text { font-family:var(--font-mono); font-size:11px; font-weight:600; fill:var(--text-color); }
.lineage .node .yr { font-size:8.5px; font-weight:400; fill:var(--text-muted); letter-spacing:.05em; }
.lineage .node.tofill rect { stroke-dasharray:3 3; fill:transparent; }
.lineage .node.tofill text { fill:var(--text-muted); }
.lineage .edge { stroke:var(--hairline-strong); stroke-width:1.2; fill:none; }
.lineage .edge.tech { stroke-dasharray:4 4; }
.lineage .rowlbl {
    font-family:var(--font-mono);
    font-size:9.5px;
    letter-spacing:.12em;
    fill:var(--text-muted);
}

/* .rangespec: log-scale reach chart — bar per system, class guides above,
 * landmark distances below. */
.rangespec { padding:16px 18px 8px; position:relative; }
.rs-head { display:flex; gap:16px; padding:0 0 14px; margin-top:4px; }
.rs-head .cls {
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.1em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.rs-row { display:grid; grid-template-columns:88px 1fr; align-items:center; min-height:26px; }
.rs-row .lbl { font-family:var(--font-mono); font-size:11px; font-weight:500; }
.rs-row .lbl a { color:inherit; }
.rs-track { position:relative; height:26px; }
.rs-bar {
    position:absolute;
    left:0;
    top:50%;
    transform:translateY(-50%);
    width:var(--w);
    height:7px;
    border-radius:0 4px 4px 0;
    background:var(--bar-a);
}
.rs-bar.hgv { background:var(--amber); }
.rs-val {
    position:absolute;
    /* Clamped so the longest bar's value never clips at the card edge */
    left:min(calc(var(--w) + 8px), calc(100% - 48px));
    top:50%;
    transform:translateY(-50%);
    font-family:var(--font-mono);
    font-size:10px;
    color:var(--text-muted);
    white-space:nowrap;
}
.rs-guides { position:absolute; top:16px; bottom:36px; left:calc(88px + 18px); right:18px; pointer-events:none; }
.rs-guides i {
    position:absolute;
    left:var(--x);
    top:0;
    bottom:0;
    width:0;
    border-left:1px dashed var(--hairline-strong);
}
.rs-guides i::after {
    content:attr(data-l);
    position:absolute;
    top:-14px;
    transform:translateX(-50%);
    font-family:var(--font-mono);
    font-size:9px;
    letter-spacing:.08em;
    color:var(--text-muted);
    white-space:nowrap;
}
.rs-land { position:relative; height:30px; margin-left:88px; border-top:1px solid var(--hairline); margin-top:8px; }
.rs-land span {
    position:absolute;
    left:var(--x);
    transform:translateX(-50%);
    top:6px;
    font-family:var(--font-mono);
    font-size:9.5px;
    color:var(--amber);
    white-space:nowrap;
}
.rs-land span::before { content:"▲"; display:block; text-align:center; font-size:7px; }
@media (max-width:768px) {
    .rs-row { grid-template-columns:64px 1fr; }
    .rs-land { margin-left:64px; }
    .rs-guides { left:calc(64px + 18px); }
    .rs-val { display:none; }
}

/* Guide decoder table: native-script cell (Chinese characters read better a
 * notch larger than the mono/latin table body). */
table.data td.zh { font-size:15px; white-space:nowrap; }

/* Ranking podium — top-3 band above the leaderboard (ranking pages).
 * Fully clickable tiles; medal identity via --pd-medal (drawn CSS medal:
 * ribbon + glossy disc — deliberately NOT the medal emojis, which render
 * differently on every OS) plus a soft tint wash fading into the panel. */
.podium { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:14px; margin-bottom:14px; }
.podium .pd {
    display:flex;
    flex-direction:column;
    gap:5px;
    background:linear-gradient(180deg, var(--pd-tint), var(--panel) 58%);
    border:1px solid var(--hairline);
    border-top:3px solid var(--pd-medal, var(--hairline-strong));
    border-radius:6px;
    box-shadow:var(--shadow-panel);
    padding:14px 16px 13px;
    text-decoration:none;
    color:var(--text-color);
}
.podium .pd:hover { border-color:var(--hairline-strong); border-top-color:var(--pd-medal); }
.podium .pd.g { --pd-medal:#c9a227; --pd-tint:rgba(201, 162, 39, .12); }
.podium .pd.s { --pd-medal:#9aa7b1; --pd-tint:rgba(154, 167, 177, .14); }
.podium .pd.b { --pd-medal:#b0763d; --pd-tint:rgba(176, 118, 61, .12); }
.podium .rkline { display:flex; align-items:center; gap:9px; min-width:0; }
.podium .rk {
    position:relative;
    flex:none;
    width:26px;
    height:26px;
    border-radius:50%;
    background:
        /* glossy highlight over the medal disc */
        radial-gradient(circle at 35% 28%, rgba(255,255,255,.55), rgba(255,255,255,0) 48%),
        var(--pd-medal);
    box-shadow:inset 0 0 0 2px rgba(255,255,255,.28), 0 1px 2px rgba(0,0,0,.28);
    display:inline-flex;
    align-items:center;
    justify-content:center;
    font-family:var(--font-mono);
    font-size:12px;
    font-weight:700;
    color:#fff;
    text-shadow:0 1px 1px rgba(0,0,0,.35);
}
.podium .rk::before {
    /* ribbon the medal hangs from, tucked under the tile's top border */
    content:"";
    position:absolute;
    top:-11px;
    left:50%;
    width:12px;
    height:12px;
    transform:translateX(-50%);
    background:var(--pd-medal);
    clip-path:polygon(0 0, 100% 0, 50% 100%);
    opacity:.85;
}
.podium .cty { font-weight:600; font-size:14.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.podium .n {
    font-family:var(--font-display);
    font-weight:600;
    font-size:30px;
    line-height:1.15;
    font-variant-numeric:tabular-nums;
}
/* Unit riding the numeral's line (equipment tops: "411 km/h") */
.podium .n small {
    font-family:var(--font-mono);
    font-size:12px;
    font-weight:500;
    color:var(--text-muted);
    margin-left:2px;
}
.podium .share {
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text-muted);
}
.podium .bar { margin-top:6px; }
@media (max-width:768px) {
    .podium { grid-template-columns:1fr; gap:10px; }
    .podium .n { font-size:24px; }
}

/* Concentration split bar — 100% stacked shares, top operators then rest.
 * Segment identity by opacity step on --bar-a (order matches the .splitkey
 * flags below the bar), the rest of the field in hairline grey. */
.splitbar { display:flex; height:16px; border-radius:3px; overflow:hidden; }
.splitbar i { width:var(--pct, 0%); background:var(--bar-a); }
.splitbar i:nth-child(2) { opacity:.8; }
.splitbar i:nth-child(3) { opacity:.62; }
.splitbar i:nth-child(4) { opacity:.46; }
.splitbar i:nth-child(5) { opacity:.32; }
.splitbar i.rest { flex:1; opacity:1; background:var(--hairline); }
.splitkey {
    display:flex;
    flex-wrap:wrap;
    gap:4px 14px;
    margin-top:9px;
    font-family:var(--font-mono);
    font-size:10.5px;
    color:var(--text-color);
}
.splitkey .rest { color:var(--text-muted); }

/* Ranking leaderboard table (.leadb, base_ranking.html) on phones: the
 * optional Share column is dropped, the value bar narrows (the .sitgrid
 * ratio) and country names may wrap, so the Total column stays inside the
 * .tscroll viewport instead of forcing a sideways scroll. */
@media (max-width:576px) {
    table.data.leadb .shr { display:none; }
    table.data.leadb td.actv { min-width:96px; }
    table.data.leadb .actv .bar { min-width:56px; }
    table.data.leadb .cty { white-space:normal; }
}

/* ============================================================================
 * 14 — QUIZ PAGES
 *      Shared game shell + per-game variants, extracted from six embedded
 *      <style> blocks (one per quiz template) and retokenized on the redesign
 *      tokens — the games get dark mode from the token swap. Scoping: shared
 *      rules are unscoped, per-game rules hang off the .quiz-<slug> modifier
 *      set on .quiz-container in each template.
 * ============================================================================ */

/* Shared across the six games */
.quiz-header {
    display:flex;
    align-items:center;
    gap:.75rem;
    margin-bottom:1rem;
    padding:.75rem 1rem;
    background:var(--panel-2);
    border-radius:6px;
}
.quiz-score-badge {
    display:flex;
    align-items:center;
    gap:.4rem;
    padding:.3rem .7rem;
    border-radius:20px;
    font-size:.9em;
    font-weight:600;
    white-space:nowrap;
}
.quiz-score-correct { background:var(--good-soft); color:var(--good); }
.quiz-score-wrong { background:var(--bad-soft); color:var(--bad); }
.quiz-progress-bar {
    flex:1;
    height:8px;
    background:var(--hairline-strong);
    border-radius:4px;
    overflow:hidden;
}
.quiz-progress-fill {
    height:100%;
    width:0;
    background:var(--signal);
    border-radius:4px;
    transition:width .3s ease;
}
.quiz-progress-text {
    font-size:.85em;
    color:var(--text-muted);
    white-space:nowrap;
}
.quiz-options {
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:.75rem;
}
.quiz-option:hover:not(.answered) { border-color:var(--signal); transform:scale(1.02); }
.quiz-option.answered { cursor:default; }
.quiz-feedback {
    display:none;
    margin-top:1.5rem;
    padding:1rem;
    background:var(--panel-2);
    border:1px solid var(--hairline-strong);
    border-radius:8px;
}
.quiz-feedback.visible {
    display:flex;
    justify-content:center;
    align-items:center;
    gap:1.25rem;
}
.quiz-result {
    font-size:1.2em;
    font-weight:bold;
    padding:.5rem 1rem;
    border-radius:6px;
}
.quiz-result.is-correct { background:var(--good); color:var(--color-white); }
.quiz-result.is-wrong { background:var(--bad); color:var(--color-white); }
#btn-next {
    padding:.75rem 2rem;
    background:var(--text-color);
    color:var(--color-white);
    border:none;
    border-radius:6px;
    font-size:1em;
    font-weight:600;
    cursor:pointer;
    transition:background .15s ease;
}
#btn-next:hover { background:var(--signal); }
.quiz-nav {
    text-align:center;
    margin-top:1.5rem;
    padding-top:1rem;
    border-top:1px solid var(--hairline);
}
.quiz-nav a { color:var(--text-muted); font-size:.9em; }
.quiz-complete {
    display:none;
    text-align:center;
    padding:2rem 1rem;
}
.quiz-complete-title {
    font-size:1.8em;
    font-weight:bold;
    margin-bottom:1rem;
    color:var(--signal);
}
.quiz-complete-score {
    font-size:1.4em;
    font-weight:bold;
    margin-bottom:1rem;
}
.quiz-complete-message {
    font-size:1.1em;
    margin-bottom:1.5rem;
    color:var(--text-muted);
}
#btn-play-again { padding:13px 28px; }
.quiz-complete-image {
    width:180px;
    height:180px;
    object-fit:cover;
    border-radius:12px;
    margin-bottom:1rem;
}
/* --- aircraft_showdown --- */
.quiz-container.quiz-showdown { max-width:700px; margin:0 auto; }
.quiz-showdown .quiz-question {
    text-align:center;
    font-size:1.2em;
    padding:1rem;
    margin-bottom:.75rem;
    font-weight:bold;
    background:var(--panel-2);
    border-radius:6px;
}
.quiz-showdown .quiz-option {
    border:3px solid var(--hairline-strong);
    border-radius:12px;
    padding:1.25rem 1rem;
    text-align:center;
    cursor:pointer;
    transition:all .15s ease;
    background:var(--panel);
}
.quiz-showdown .quiz-option.correct { border-color:var(--good) !important; background:var(--good-soft); }
.quiz-showdown .quiz-option.wrong { border-color:var(--bad) !important; background:var(--bad-soft); }
.quiz-showdown .quiz-option-flag {
    font-size:1.5rem;
    line-height:1;
    margin-bottom:.3rem;
}
.quiz-showdown .quiz-option-name { font-size:1.1em; font-weight:bold; }
.quiz-showdown .quiz-option-country {
    font-size:.85em;
    color:var(--text-muted);
    margin-top:.2rem;
}
.quiz-showdown .quiz-option-value {
    font-size:1.2em;
    font-weight:bold;
    margin-top:.5rem;
    background:var(--panel-2);
    border-radius:4px;
    display:none;
}
.quiz-showdown .quiz-option-value.visible { display:inline-block; padding:.3rem .6rem; }
@media (max-width: 576px) {
    .quiz-showdown .quiz-options { grid-template-columns:1fr; }
    .quiz-showdown .quiz-option { padding:1rem; }
}

/* --- guess_the_flag --- */
.quiz-container.quiz-flag { max-width:600px; margin:0 auto; }
.quiz-flag .quiz-question {
    text-align:center;
    font-size:1.4em;
    padding:1.5rem;
    margin-bottom:1rem;
    font-weight:bold;
    background:var(--panel-2);
    border-radius:6px;
}
.quiz-flag .quiz-question-label {
    font-size:.7em;
    font-weight:normal;
    color:var(--text-muted);
    margin-bottom:.5rem;
}
.quiz-flag .quiz-option {
    border:3px solid var(--hairline-strong);
    border-radius:12px;
    padding:1.5rem 1rem;
    text-align:center;
    cursor:pointer;
    transition:all .15s ease;
    background:var(--panel);
    font-size:3rem;
}
.quiz-flag .quiz-option.correct { border-color:var(--good) !important; background:var(--good-soft); }
.quiz-flag .quiz-option.wrong { border-color:var(--bad) !important; background:var(--bad-soft); }
@media (max-width: 480px) {
    .quiz-flag .quiz-option { padding:1rem; font-size:2.5rem; }
}

/* --- identify_the_rank --- */
.quiz-container.quiz-rank { max-width:650px; margin:0 auto; }
.quiz-rank .quiz-image-container {
    text-align:center;
    padding:2rem;
    margin-bottom:1rem;
    background:var(--panel-2);
    border-radius:8px;
}
.quiz-rank .quiz-rank-image {
    max-width:150px;
    max-height:150px;
    object-fit:contain;
}
.quiz-rank .quiz-hint {
    margin-top:1rem;
    font-size:.9em;
    color:var(--text-muted);
}
.quiz-rank .quiz-hint-badge {
    display:inline-block;
    padding:.25rem .6rem;
    background:var(--hairline-strong);
    border-radius:4px;
    font-size:.85em;
    font-family:var(--font-mono);
}
.quiz-rank .quiz-question-label {
    text-align:center;
    font-size:1.1em;
    margin-bottom:.75rem;
    color:var(--text-muted);
}
.quiz-rank .quiz-option {
    border:3px solid var(--hairline-strong);
    border-radius:12px;
    padding:1rem;
    text-align:center;
    cursor:pointer;
    transition:all .15s ease;
    background:var(--panel);
}
.quiz-rank .quiz-option.correct {
    border-color:var(--good) !important;
    border-width:4px;
    background:var(--good-soft) !important;
}
.quiz-rank .quiz-option.wrong {
    border-color:var(--bad) !important;
    border-width:4px;
    background:var(--bad-soft) !important;
}
.quiz-rank .quiz-option-country { font-size:1em; margin-bottom:.25rem; }
.quiz-rank .quiz-option-flag { font-size:1.4em; margin-right:.35rem; }
.quiz-rank .quiz-option-branch {
    font-size:.85em;
    color:var(--text-muted);
    margin-bottom:.35rem;
}
.quiz-rank .quiz-option-rank {
    font-size:1.05em;
    font-weight:bold;
    padding-top:.35rem;
    border-top:1px solid var(--hairline);
}
@media (max-width: 576px) {
    .quiz-rank .quiz-options { grid-template-columns:1fr; }
    .quiz-rank .quiz-option { padding:.85rem; }
    .quiz-rank .quiz-rank-image { max-width:120px; max-height:120px; }
}

/* --- name_that_aircraft --- */
.quiz-container.quiz-name { max-width:650px; margin:0 auto; }
.quiz-name .quiz-image-container {
    text-align:center;
    padding:1.5rem;
    margin-bottom:1rem;
    background:var(--panel);
    border:1px solid var(--hairline-strong);
    border-radius:8px;
}
.quiz-name .quiz-aircraft-image {
    max-width:100%;
    max-height:200px;
    object-fit:contain;
}
.quiz-name .quiz-question-label {
    text-align:center;
    font-size:1.1em;
    margin-bottom:.75rem;
    color:var(--text-muted);
}
.quiz-name .quiz-option {
    border:3px solid var(--hairline-strong);
    border-radius:12px;
    padding:1rem;
    text-align:center;
    cursor:pointer;
    transition:all .15s ease;
    background:var(--panel);
}
.quiz-name .quiz-option.correct {
    border-color:var(--good) !important;
    border-width:4px;
    background:var(--good-soft) !important;
}
.quiz-name .quiz-option.wrong {
    border-color:var(--bad) !important;
    border-width:4px;
    background:var(--bad-soft) !important;
}
.quiz-name .quiz-option-name {
    font-size:1.05em;
    font-weight:bold;
    margin-bottom:.25rem;
}
.quiz-name .quiz-option-origin { font-size:.9em; color:var(--text-muted); }
.quiz-name .quiz-option-flag { margin-right:.25rem; }
@media (max-width: 576px) {
    .quiz-name .quiz-options { grid-template-columns:1fr; }
    .quiz-name .quiz-option { padding:.85rem; }
}

/* --- which_is_stronger --- */
.quiz-container.quiz-stronger { max-width:700px; margin:0 auto; }
.quiz-stronger .quiz-question {
    text-align:center;
    font-size:1.2em;
    padding:1rem;
    margin-bottom:.75rem;
    font-weight:bold;
    background:var(--panel-2);
    border-radius:6px;
}
.quiz-stronger .quiz-option {
    border:3px solid var(--hairline-strong);
    border-radius:12px;
    padding:1.25rem 1rem;
    text-align:center;
    cursor:pointer;
    transition:all .15s ease;
    background:var(--panel);
}
.quiz-stronger .quiz-option.correct {
    border-color:var(--good) !important;
    border-width:4px;
    background:var(--good-soft) !important;
    box-shadow:0 0 0 4px var(--good-soft);
}
.quiz-stronger .quiz-option.wrong {
    border-color:var(--bad) !important;
    border-width:4px;
    background:var(--bad-soft) !important;
    box-shadow:0 0 0 4px var(--bad-soft);
}
.quiz-stronger .quiz-option-flag {
    font-size:2.75rem;
    line-height:1;
    margin-bottom:.4rem;
}
.quiz-stronger .quiz-option-name { font-size:1.1em; font-weight:bold; }
.quiz-stronger .quiz-option-value {
    font-size:1.2em;
    font-weight:bold;
    margin-top:.5rem;
    padding:.4rem .6rem;
    background:var(--panel-2);
    border-radius:4px;
    display:none;
}
.quiz-stronger .quiz-option-value.visible { display:inline-block; }
@media (max-width: 576px) {
    .quiz-stronger .quiz-options { grid-template-columns:1fr; }
    .quiz-stronger .quiz-option { padding:1rem; }
    .quiz-stronger .quiz-option-flag { font-size:2.25rem; }
}

/* --- who_operates_it --- */
.quiz-container.quiz-operates { max-width:600px; margin:0 auto; }
.quiz-operates .quiz-question {
    text-align:center;
    padding:1.5rem;
    margin-bottom:1rem;
    background:var(--panel-2);
    border-radius:6px;
}
.quiz-operates .quiz-question-label {
    font-size:1em;
    color:var(--text-muted);
    margin-bottom:.5rem;
}
.quiz-operates .quiz-question-aircraft { font-size:1.4em; font-weight:bold; }
.quiz-operates .quiz-question-origin {
    font-size:.9em;
    color:var(--text-muted);
    margin-top:.3rem;
}
.quiz-operates .quiz-option {
    border:3px solid var(--hairline-strong);
    border-radius:12px;
    padding:1rem;
    text-align:center;
    cursor:pointer;
    transition:all .15s ease;
    background:var(--panel);
}
.quiz-operates .quiz-option.correct { border-color:var(--good) !important; background:var(--good-soft); }
.quiz-operates .quiz-option.wrong { border-color:var(--bad) !important; background:var(--bad-soft); }
.quiz-operates .quiz-option-flag { font-size:2rem; margin-bottom:.3rem; }
.quiz-operates .quiz-option-name { font-size:.95em; font-weight:bold; }
@media (max-width: 480px) {
    .quiz-operates .quiz-option { padding:.75rem; }
    .quiz-operates .quiz-option-flag { font-size:1.5rem; }
    .quiz-operates .quiz-option-name { font-size:.85em; }
}
