/* The Google Fonts @import that used to sit here has moved into every page's
   <head> as a <link>, with preconnect. It is the same three families on the
   same URL — what changed is WHEN the browser finds out about them.

   An @import inside this file cannot be discovered until this file has been
   downloaded and parsed, so the font request was a second serialized round
   trip that started only after the CSS finished. The fonts then arrived after
   first paint and `display=swap` swapped them in underneath the reader, which
   reflowed every line of text on the page. That was CLS 0.192 on /en/map/ —
   measured, by deleting this line and watching it go to 0.000, then restored
   and re-measured as a <link> in the head: 0.020.

   A <link> in the head is discovered in the initial HTML parse and fetched in
   parallel with this stylesheet, so the font is there before the first paint
   and there is nothing to swap. See PERFORMANCE.md §1 defect 1. */
/* fonts:start — generated by tools/fonts.js; do not edit between these markers */
/* Self-hosted. Google serves 6 subsets; these are the ones this site's
   characters actually need — greek is mono-only, for the Σ in the
   composite-score formula on /en/methodology/. See tools/fonts.js. */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-400-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-400-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-500-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-500-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-600-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-600-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Source Serif 4';font-style:italic;font-weight:400;font-display:swap;src:url(/assets/fonts/source-serif-4-400-italic-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Source Serif 4';font-style:italic;font-weight:400;font-display:swap;src:url(/assets/fonts/source-serif-4-400-italic-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Source Serif 4';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/source-serif-4-400-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Source Serif 4';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/source-serif-4-400-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Source Serif 4';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/source-serif-4-600-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Source Serif 4';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/source-serif-4-600-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/space-grotesk-400-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/space-grotesk-400-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/space-grotesk-500-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/space-grotesk-500-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/space-grotesk-600-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/space-grotesk-600-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/space-grotesk-700-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/space-grotesk-700-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
/* fonts:end */
:root{--bg:#0F1626;--panel:#1A2338;--amber:#E8A33D;--teal:#4FD1C5;--text:#EDEFF4;--muted:#949CB0;--border:rgba(139,148,168,.16);--ok:#4ADE80;--warn:#FACC15;--crisis:#FB923C;--danger:#F87171;--cream:#F5EFE3;--cream-text:#2C2418;--cream-muted:#6F6450;--sans:'Space Grotesk',sans-serif;--serif:'Source Serif 4',serif;--mono:'IBM Plex Mono',monospace}
*{box-sizing:border-box}html,body{margin:0;padding:0;background:var(--bg);color:var(--text);font-family:var(--sans)}
a{color:var(--teal);text-decoration:none}a:hover{color:var(--amber)}button{font-family:var(--sans)}
@keyframes nmPulse{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.35)}}
@keyframes nmFlow{to{stroke-dashoffset:-24}}
@keyframes nmGlow{0%,100%{opacity:.25}50%{opacity:.8}}
@media (prefers-reduced-motion:reduce){svg *{animation:none!important}}
.container{max-width:1100px;margin:0 auto;padding:0 28px}
.panel{background:var(--panel);border:1px solid var(--border);border-radius:16px}
.mono{font-family:var(--mono)}
.badge-impact{font-family:var(--mono);font-size:11px;font-weight:600;color:var(--bg);background:var(--amber);padding:3px 8px;border-radius:6px;white-space:nowrap}
.btn-outline{background:none;border:1px solid var(--amber);color:var(--amber);font-size:13px;font-weight:600;padding:8px 18px;border-radius:8px;cursor:pointer;white-space:nowrap;display:inline-block}
.btn-outline:hover{background:rgba(232,163,61,.12)}
.lens-badge{font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.16em;background:var(--cream-text);color:var(--cream);padding:4px 10px;border-radius:6px;white-space:nowrap}
header.site{position:sticky;top:0;z-index:50;display:flex;align-items:center;justify-content:space-between;padding:14px 28px;background:rgba(15,22,38,.92);backdrop-filter:blur(8px);border-bottom:1px solid var(--border)}
header.site nav{display:flex;align-items:center;gap:18px}
header.site nav a{font-size:13.5px;font-weight:500;color:var(--muted)}
header.site nav a.active{color:var(--amber)}
footer.site{border-top:1px solid var(--border);padding:26px 28px;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:12px;max-width:1100px;margin:0 auto}
.h-flex{display:flex;align-items:center}
.grid-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px}
.grid-conn{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:14px}
.card{background:var(--panel);border:1px solid var(--border);border-radius:14px;padding:16px 18px;display:flex;flex-direction:column;gap:8px;height:100%}
a .card:hover{border-color:rgba(232,163,61,.5)}
.chip{font-size:13px;font-weight:500;padding:7px 16px;border-radius:999px;border:1px solid rgba(139,148,168,.3);cursor:pointer}
.chip:hover{border-color:var(--amber);color:var(--amber)}
.seg{border:none;cursor:pointer;font-size:13px;font-weight:600;padding:8px 16px;border-radius:8px;white-space:nowrap;background:transparent;color:var(--muted)}
.seg.on{background:var(--amber);color:var(--bg)}
.tl-row{display:flex;gap:15px}
.tl-rail{display:flex;flex-direction:column;align-items:center;flex:none;width:16px}
.tl-dot{width:12px;height:12px;border-radius:50%;background:var(--amber);flex:none;margin-top:4px;box-shadow:0 0 8px rgba(232,163,61,.5)}
.tl-line{width:2px;flex:1;background:rgba(232,163,61,.35)}
.paper-mode .read-surface{background:#F7F2E9!important;color:#2C2418!important;border-color:rgba(44,36,24,.15)!important}
.paper-mode .read-surface .rmut{color:#8a7d63!important}
.paper-mode .read-surface .rbord{border-color:rgba(44,36,24,.15)!important}
.paper-mode .read-surface .rstat{background:rgba(44,36,24,.04)!important}
.hidden{display:none!important}
/* --- USP + power-word emotional hook --- */
.usp-eyebrow{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:11px;letter-spacing:.24em;color:var(--muted);border:1px solid var(--border);border-radius:999px;padding:6px 14px;margin-bottom:22px}
.usp-eyebrow .dot{width:6px;height:6px;border-radius:50%;background:var(--teal);box-shadow:0 0 8px var(--teal)}
.power-hook{display:flex;flex-wrap:wrap;justify-content:center;gap:8px 10px;margin:22px auto 0;max-width:640px}
.power-word{font-family:var(--mono);font-size:12.5px;letter-spacing:.1em;color:var(--muted);border:1px solid var(--border);border-radius:8px;padding:7px 13px;transition:color .5s,border-color .5s,box-shadow .5s,background .5s}
.power-word.on{color:var(--bg);background:var(--amber);border-color:var(--amber);box-shadow:0 0 18px rgba(232,163,61,.45)}
@media (prefers-reduced-motion:reduce){.power-word{color:var(--text)}}
/* --- Influence Meter --- */
.infl-board{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px}
.infl-card{background:var(--panel);border:1px solid var(--border);border-radius:16px;padding:16px 16px 14px;display:flex;flex-direction:column;gap:6px}
.infl-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.infl-name{font-weight:600;font-size:15px}
.infl-tag{font-size:9px;letter-spacing:.12em;color:var(--muted);border:1px solid var(--border);border-radius:5px;padding:2px 6px}
.infl-radar{padding:4px 10px 2px}
.infl-foot{display:flex;align-items:flex-end;justify-content:space-between;border-top:1px solid var(--border);padding-top:11px;margin-top:2px}
.infl-score{font-size:30px;font-weight:600;line-height:1;color:var(--amber)}
.infl-sub{display:block;font-size:9px;letter-spacing:.14em;color:var(--muted);margin-top:3px}
.infl-top{text-align:right}
.infl-topv{display:block;font-size:12.5px;font-weight:500;color:var(--teal);margin-top:2px}
/* .infl-region (the region hub's own meter) lives with the rest of the .ir-*
   panel further down — it was two rules in two places describing one panel. */
/* --- Heat-map chips + legend --- */
.heat-row{display:flex;flex-wrap:wrap;gap:7px;align-items:center}
.heat-chip{font-family:var(--mono);font-size:11px;letter-spacing:.03em;color:var(--muted);background:transparent;border:1px solid rgba(139,148,168,.3);border-radius:999px;padding:6px 12px;cursor:pointer;display:inline-flex;align-items:center;gap:6px}
.heat-chip:hover{border-color:var(--warn);color:var(--text)}
.heat-chip.on{color:var(--bg);background:linear-gradient(90deg,#FACC15,#FB923C,#F87171);border-color:transparent;font-weight:600}
.heat-legend{display:flex;align-items:center;gap:8px;font-family:var(--mono);font-size:10px;color:var(--muted)}
.heat-legend .bar{width:70px;height:7px;border-radius:4px;background:linear-gradient(90deg,#FACC15,#FB923C,#F87171)}
/* --- Relationship web / journey rail --- */
.rel-web{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
.rel-node{display:block;background:var(--panel);border:1px solid var(--border);border-radius:13px;padding:13px 15px}
.rel-node:hover{border-color:rgba(232,163,61,.5)}
.rel-kind{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;color:var(--teal);margin-bottom:5px}
.rel-title{font-size:13.5px;font-weight:500;line-height:1.35;color:var(--text)}
.journey{display:flex;align-items:stretch;gap:0;flex-wrap:wrap}
.journey-step{flex:1;min-width:150px;display:flex;flex-direction:column;gap:4px;padding:14px 16px;border:1px solid var(--border);background:var(--panel)}
.journey-step:first-child{border-radius:14px 0 0 14px}
.journey-step:last-child{border-radius:0 14px 14px 0}
.journey-step.here{border-color:rgba(232,163,61,.5);background:rgba(232,163,61,.06)}
.journey-k{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;color:var(--muted)}
.journey-t{font-size:14px;font-weight:600}
@media(max-width:640px){.journey-step{border-radius:12px!important}}
/* Demo banner — this build ships illustrative sample content, not sourced
   reporting. Remove this rule and the .demo-banner markup only once every
   figure on the page traces to a real, cited source. */
.demo-banner{
  display:flex; align-items:flex-start; gap:10px;
  max-width:1100px; margin:14px auto 0; padding:11px 15px;
  border:1px solid rgba(232,163,61,.45);
  border-left:3px solid var(--amber);
  border-radius:9px;
  background:rgba(232,163,61,.09);
  font-size:12.5px; line-height:1.5; color:var(--text);
}
.demo-banner b{ color:var(--amber); font-weight:600; letter-spacing:.04em; }
.demo-banner span{ color:var(--muted); }
@media (max-width:640px){ .demo-banner{ margin:12px 14px 0; font-size:12px; } }

/* ── Methodology page ──────────────────────────────────────────────
   Class-based, no inline styles. New pages should follow this pattern
   rather than the inline-style approach used by the earlier pages. */
.meth{max-width:820px;margin:0 auto;padding:36px 24px 90px}
.meth-lede{font-family:var(--serif);font-size:18px;line-height:1.7;color:var(--text);margin:0 0 10px;text-wrap:pretty}
.meth-sub{font-size:14px;line-height:1.65;color:var(--muted);margin:0 0 34px;text-wrap:pretty}
.meth h1{font-size:34px;font-weight:700;line-height:1.18;letter-spacing:-.01em;margin:0 0 18px;text-wrap:pretty}
.meth h2{font-size:20px;font-weight:600;margin:0 0 10px;scroll-margin-top:80px}
.meth h3{font-size:15.5px;font-weight:600;margin:0 0 6px}
.meth p{font-size:14.5px;line-height:1.7;color:var(--muted);margin:0 0 12px;text-wrap:pretty}
.meth section{margin-bottom:40px}
.meth strong{color:var(--text);font-weight:600}

.meth-kicker{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;font-weight:600;color:var(--amber);display:block;margin-bottom:12px}

/* Two-bucket explainer */
.meth-buckets{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px;margin:18px 0 6px}
.meth-bucket{border:1px solid var(--border);border-radius:14px;padding:18px 20px;background:var(--panel)}
.meth-bucket.is-measured{border-left:3px solid var(--teal)}
.meth-bucket.is-editorial{border-left:3px solid var(--amber)}
.meth-bucket h3{color:var(--text)}
.meth-bucket p{margin-bottom:0;font-size:13.5px}
.meth-bucket-tag{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;font-weight:600;display:block;margin-bottom:7px}
.is-measured .meth-bucket-tag{color:var(--teal)}
.is-editorial .meth-bucket-tag{color:var(--amber)}

/* Metric status table */
.meth-table-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:12px;background:var(--panel)}
.meth-table{width:100%;border-collapse:collapse;font-size:13px;min-width:520px}
.meth-table th,.meth-table td{text-align:left;padding:11px 14px;border-bottom:1px solid var(--border);vertical-align:top}
.meth-table tr:last-child td{border-bottom:none}
.meth-table th{font-family:var(--mono);font-size:10px;letter-spacing:.14em;color:var(--muted);font-weight:600;text-transform:uppercase}
.meth-table td:first-child{color:var(--text);font-weight:600;white-space:nowrap}
.meth-table td{color:var(--muted);line-height:1.55}

.meth-pill{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;font-weight:600;padding:3px 8px;border-radius:5px;white-space:nowrap;display:inline-block}
.meth-pill.computed{background:rgba(79,209,197,.14);color:var(--teal)}
.meth-pill.placeholder{background:rgba(232,163,61,.14);color:var(--amber)}

/* Formula block */
.meth-formula{font-family:var(--mono);font-size:12.5px;line-height:1.75;color:var(--text);background:rgba(139,148,168,.08);border:1px solid var(--border);border-radius:10px;padding:14px 16px;margin:12px 0;overflow-x:auto;white-space:pre}

/* Callout for the honest caveats */
.meth-note{border:1px solid var(--border);border-left:3px solid var(--muted);border-radius:9px;padding:13px 16px;margin:14px 0;font-size:13.5px;line-height:1.6;color:var(--muted)}
.meth-note b{color:var(--text);font-weight:600}
.meth-note.warn{border-left-color:var(--amber);background:rgba(232,163,61,.06)}

/* Empty track record */
.meth-empty{border:1px dashed rgba(139,148,168,.4);border-radius:12px;padding:26px 22px;text-align:center;color:var(--muted)}
.meth-empty-n{font-family:var(--mono);font-size:30px;font-weight:600;color:var(--text);display:block;margin-bottom:5px}
.meth-empty-l{font-family:var(--mono);font-size:10px;letter-spacing:.16em}

@media (max-width:640px){
  .meth{padding:26px 18px 70px}
  .meth h1{font-size:27px}
  .meth-lede{font-size:16.5px}
}

/* Mobile header — the nav overflowed the viewport at <=640px (431px of links
   in a 375px window, before the Method link widened it further). The links
   now scroll horizontally inside the header instead of pushing the whole
   document sideways. */
@media (max-width:640px){
  header.site{flex-wrap:wrap;padding:12px 16px;gap:10px}
  header.site nav{
    gap:14px; width:100%;
    overflow-x:auto; -webkit-overflow-scrolling:touch;
    scrollbar-width:none; -ms-overflow-style:none;
  }
  header.site nav::-webkit-scrollbar{display:none}
  header.site nav a{font-size:13px; white-space:nowrap}
  footer.site{padding:20px 16px}
}

/* ── Impact Score panel (rendered by impact.js) ────────────────────
   Geometry and values are computed in JS from the dimension ratings;
   nothing here hardcodes a score. */
.imp-panel{display:flex;gap:24px;align-items:center;flex-wrap:wrap;padding:20px 22px;border-radius:16px;margin-bottom:22px}
.imp-ring{position:relative;width:92px;height:92px;flex:none}
.imp-ring svg{width:100%;height:100%;transform:rotate(-90deg)}
.imp-track{fill:none;stroke:rgba(139,148,168,.2);stroke-width:9}
.imp-arc{fill:none;stroke:var(--amber);stroke-width:9;stroke-linecap:round}
.imp-ring-c{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.imp-score{font-size:24px;font-weight:600}
.imp-score-l{font-size:9px;letter-spacing:.14em;color:var(--muted)}
.imp-bars{flex:1;min-width:240px;display:flex;flex-direction:column;gap:7px}
.imp-row{display:flex;align-items:center;gap:10px}
.imp-dim{font-size:11.5px;color:var(--muted);width:96px;flex:none}
.imp-track-h{flex:1;height:5px;border-radius:3px;background:rgba(139,148,168,.18);overflow:hidden}
.imp-fill{height:100%;border-radius:3px;background:var(--amber)}
.imp-val{font-size:11px;width:24px;text-align:right}
.imp-foot{font-size:10px;color:var(--muted);margin-top:2px}
@media (max-width:640px){
  .imp-panel{gap:18px;padding:18px}
  .imp-dim{width:80px;font-size:11px}
}

/* ── Scenario vote (wired by vote.js) ──────────────────────────────
   No aggregate is shown: there is no vote store behind this yet, and an
   invented "x% agree" is worse than none. */
.vote-box{border-top:1px solid var(--border);margin-top:18px;padding-top:16px}
.vote-ask{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.vote-q{font-size:13.5px;font-weight:500}
/* Yes/No are a single unit, not two independent flex items — .vote-ask can
   wrap the pair onto its own line under a long question, but it can never
   split them from each other. Before this, a question just long enough to
   fill most of the row left "Yes" stranded at the end of line one and "No"
   alone at the start of line two, which read as the buttons being in the
   wrong place rather than as a question that wrapped. */
.vote-btns{display:flex;gap:8px;flex-shrink:0}
.vote-btn{background:none;font-size:12.5px;font-weight:600;padding:7px 16px;border-radius:8px;cursor:pointer;border:1px solid rgba(139,148,168,.4);color:var(--muted)}
.vote-btn.yes{border-color:var(--teal);color:var(--teal)}
.vote-btn:hover{border-color:var(--amber);color:var(--amber)}
.vote-done{font-size:13.5px;line-height:1.65}
.vote-answer{color:var(--amber)}
.vote-est{color:var(--teal)}
.vote-note{color:var(--muted)}
.vote-link{font-size:12.5px;white-space:nowrap}
@media (max-width:640px){ .vote-ask{gap:9px} .vote-q{width:100%} }

/* ── Analysis page (generated by tools/build.js) ───────────────────
   These replace inline styles that were repeated per question/pill in the
   hand-written HTML. Edit here, not in en/analysis/*/index.html — that file
   is generated and your changes will be overwritten. */
.q-num{font-size:12px;font-weight:600;color:var(--bg);background:var(--teal);width:24px;height:24px;border-radius:7px;display:flex;align-items:center;justify-content:center;flex:none}
.q-body{font-family:var(--serif);font-size:16.5px;line-height:1.75;margin:0 0 8px;text-wrap:pretty}
.conf-pill{display:inline-flex;align-items:center;gap:6px;font-size:10.5px;color:var(--muted);border:1px solid var(--border);border-radius:999px;padding:3px 10px;white-space:nowrap}
.conf-dot{width:7px;height:7px;border-radius:50%;flex:none}
.wim-node{font-size:13.5px;font-weight:500;background:rgba(232,163,61,.13);border-radius:8px;padding:6px 12px}

/* ── Shared chrome ─────────────────────────────────────────────────
   Header brand + footer, previously inline on every page.
   a.brand (not .brand) is deliberate: a:hover{color:var(--amber)} would
   otherwise win over a bare .brand class and turn the wordmark amber on
   hover. The inline style it replaces had no such hover, so we pin both
   states to keep the rendering identical. */
a.brand,a.brand:hover{display:flex;align-items:center;gap:11px;color:var(--text)}
.brand-name{display:block;font-weight:700;font-size:16px;letter-spacing:.14em}
.brand-tag{display:block;font-size:9.5px;letter-spacing:.22em;color:var(--muted)}
.lang-badge{font-size:11px;color:var(--muted);border:1px solid rgba(139,148,168,.3);padding:4px 9px;border-radius:6px}
.foot-l{font-size:11px;color:var(--muted)}
.foot-r{font-size:12px;color:var(--muted)}

/* ── Shared text/section utilities ─────────────────────────────────
   The handful of inline styles that repeated most across pages. */
.h-sec{font-size:19px;font-weight:600;margin:0}
.t-mut-11{font-size:11px;color:var(--muted)}
.t-mut-12{font-size:12px;color:var(--muted)}
.t-mut-105{font-size:10.5px;color:var(--muted)}
.meter{height:6px;border-radius:3px;background:rgba(139,148,168,.2);overflow:hidden}

/* ── Repeated patterns extracted from inline styles ────────────────
   Named for what they are, not what they look like, so a restyle happens
   here once rather than in N places across the pages. */
.sec-30{margin-bottom:30px}
.q-head{display:flex;align-items:center;gap:11px;margin-bottom:10px}
.h-sec-14{font-size:19px;font-weight:600;margin:0 0 14px}
.tl-body{padding-bottom:20px;flex:1}
.tl-title{font-weight:600;font-size:15px}
.tl-when{font-size:10.5px;color:var(--muted)}
.card-title{font-size:13.5px;font-weight:500;line-height:1.35;color:var(--text)}
.card-lede{font-size:13.5px;color:var(--muted);line-height:1.55;max-width:440px}
.stat-name{font-weight:600;font-size:15px;color:var(--text)}
.stat-head{font-weight:600;font-size:15.5px;margin-bottom:4px}
.eyebrow-13{font-size:13px;color:var(--muted);letter-spacing:.05em}

/* ── Analysis page layout (generated by tools/build.js) ────────────
   The generated page carries no layout inline styles. What remains inline
   there is DATA, not design: bar widths (width:44%) and semantic tone colors
   (var(--warn)) come from the JSON per analysis and cannot live in a
   stylesheet. Everything else belongs here. */
.an-main{max-width:760px;margin:0 auto;padding:32px 24px 90px}
.an-meta{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:18px}
.an-route{font-size:11px;color:var(--teal)}
.an-sep{color:var(--muted)}
.an-updated{margin-left:auto;display:flex;align-items:center;gap:6px;font-size:10.5px;color:var(--amber);white-space:nowrap}
.an-glow{width:7px;height:7px;border-radius:50%;background:var(--amber);animation:nmGlow 1.8s ease-in-out infinite}
.an-h1{font-size:34px;font-weight:700;line-height:1.18;margin:0 0 22px;letter-spacing:-.01em;text-wrap:pretty}
.an-tools{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:26px}
.an-segs{display:flex;border-radius:10px;padding:3px}
.btn-theme{margin-left:auto;background:none;border:1px solid rgba(139,148,168,.3);color:var(--muted);font-size:12.5px;padding:8px 14px;border-radius:10px;cursor:pointer;white-space:nowrap}
.an-surface{border-radius:18px;padding:30px 30px 26px;background:#131b2e;border:1px solid rgba(139,148,168,.18);transition:background .3s}

/* Why this matters */
.wim{border:1px dashed rgba(232,163,61,.5);border-radius:14px;padding:18px 20px;margin-bottom:30px}
.wim-k{font-size:10.5px;letter-spacing:.16em;color:var(--amber);font-weight:600;margin-bottom:12px}
.wim-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.wim-link{display:flex;align-items:center;gap:8px}
.wim-arrow{color:var(--amber);font-weight:600}
.wim-out{font-size:13.5px;font-weight:600;color:var(--amber)}

/* Dual-figure stat panel */
.stat-panel{background:var(--panel);border:1px solid var(--border);border-radius:14px;padding:20px 22px;margin-bottom:30px}
.stat-k{font-size:10.5px;letter-spacing:.16em;color:var(--muted);font-weight:600;margin-bottom:14px}
.stat-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.stat-cell{border-radius:10px;padding:14px 16px;background:rgba(139,148,168,.1)}
.stat-cell.alt{background:rgba(79,209,197,.1)}
.stat-cell-l{font-size:11px;color:var(--muted);margin-bottom:5px}
.stat-cell-v{font-size:26px;font-weight:600}
.trust-row{display:flex;justify-content:space-between;font-size:10.5px;color:var(--muted);margin:14px 0 6px}
.trust-row span:first-child{white-space:nowrap}
.trust-row span:last-child{text-align:right}
.trust-fill{height:100%;border-radius:3px;background:linear-gradient(90deg,#4FD1C5,#E8A33D)}
.stat-foot{font-size:10px;color:var(--muted);margin-top:8px}

/* Domino timeline */
.dom-h{font-size:19px;font-weight:600;margin:0 0 6px}
.dom-note{font-size:13px;color:var(--muted);margin:0 0 18px}
.dom-list{display:flex;flex-direction:column}
.dom-head{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap}
.dom-body{font-size:13.5px;color:var(--muted);line-height:1.55;margin-top:3px}
.dom-off{font-size:10px;color:var(--teal);margin-top:5px}
.alt-wrap{margin-left:31px}
.btn-alt{background:none;border:1px dashed rgba(232,163,61,.5);color:var(--amber);font-size:12.5px;font-weight:600;padding:9px 16px;border-radius:10px;cursor:pointer}
.alt-panel{border:1px dashed rgba(232,163,61,.5);border-radius:12px;padding:16px 18px;margin-top:10px}
.alt-k{font-size:10.5px;letter-spacing:.14em;color:var(--amber);font-weight:600;margin-bottom:8px}
.alt-body{font-family:var(--serif);font-size:15px;line-height:1.7;margin:0}

/* Probability engine */
.next-panel{border:1px solid var(--border);border-radius:14px;padding:20px 22px;margin-bottom:30px}
.next-head{display:flex;align-items:center;gap:11px;margin-bottom:6px}
.next-note{font-size:13px;color:var(--muted);margin:0 0 16px}
.prob-list{display:flex;flex-direction:column;gap:12px}
.prob-head{display:flex;justify-content:space-between;font-size:14px;margin-bottom:5px}
.prob-label{font-weight:500}
.prob-val{font-weight:600}
.prob-track{height:7px;border-radius:4px;background:rgba(139,148,168,.18);overflow:hidden}
.prob-fill{height:100%;border-radius:4px}

/* Founder's Lens */
.lens{background:var(--cream);color:var(--cream-text);border-radius:16px;padding:26px 28px}
.lens-head{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap}
.lens-note{font-size:12px;color:var(--cream-muted)}
.lens-body{font-family:var(--serif);font-size:16.5px;line-height:1.75;margin:0 0 10px;color:#453a28;text-wrap:pretty}
.lens-by{font-family:var(--serif);font-style:italic;font-size:14px;color:var(--cream-muted)}

/* Related web + journey */
.rel-sec{margin:34px 0 0}
.rel-k{font-size:10.5px;letter-spacing:.16em;color:var(--teal);font-weight:600;margin-bottom:6px}
.rel-lede{font-size:13px;color:var(--muted);margin:0 0 14px;line-height:1.55;max-width:560px}
.journey-sec{margin:30px 0 0}
.journey-k2{font-size:10.5px;letter-spacing:.16em;color:var(--muted);font-weight:600;margin-bottom:12px}
.journey-sub{font-size:12px;color:var(--muted)}
a.journey-step,a.journey-step:hover{color:inherit}

/* ── Corrections & revisions log (generated) ───────────────────────
   Deliberately plain. A correction log styled like a feature announcement
   reads as marketing; this should read like a receipt. */
.rev-sec{border-top:1px solid var(--border);padding-top:22px}
.rev-topline{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:6px}
.rev-count{font-size:11px;color:var(--muted);letter-spacing:.1em}
.rev-note{font-size:13px;color:var(--muted);margin:0 0 16px;line-height:1.6;max-width:600px}
.rev-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}
.rev-item{border-left:2px solid var(--border);padding:0 0 0 14px}
.rev-item:hover{border-left-color:var(--amber)}
.rev-head{display:flex;align-items:center;gap:9px;margin-bottom:4px;flex-wrap:wrap}
.rev-kind{font-size:9px;letter-spacing:.14em;font-weight:600;padding:2px 7px;border-radius:4px;background:rgba(139,148,168,.16);color:var(--muted)}
.rev-kind.correction{background:rgba(232,163,61,.15);color:var(--amber)}
.rev-kind.resolution{background:rgba(79,209,197,.15);color:var(--teal)}
.rev-at{font-size:10.5px;color:var(--muted)}
.rev-what{font-size:14px;font-weight:500;line-height:1.5;margin-bottom:3px}
.rev-delta{font-size:12px;color:var(--amber);background:rgba(232,163,61,.12);border-radius:4px;padding:1px 6px}
.rev-why{font-size:13px;color:var(--muted);line-height:1.6}
.rev-empty{font-size:13.5px;color:var(--muted);line-height:1.6;border:1px dashed rgba(139,148,168,.35);border-radius:10px;padding:16px 18px}

/* Estimate that has moved, shown on the bar itself */
.prob-trail{font-size:10.5px;color:var(--amber);background:rgba(232,163,61,.12);border-radius:4px;padding:1px 6px;margin-left:8px;white-space:nowrap}
.prob-res{display:inline-block;font-size:9.5px;letter-spacing:.12em;font-weight:600;margin-top:6px;padding:2px 7px;border-radius:4px}
.prob-res.yes{background:rgba(74,222,128,.15);color:var(--ok)}
.prob-res.no{background:rgba(248,113,113,.15);color:var(--danger)}
@media (max-width:640px){ .prob-trail{margin-left:0;display:inline-block;margin-top:3px} }

/* ── Track record (computed by track.js) ───────────────────────────── */
.trk-note{margin:12px 0 0;font-size:13.5px;line-height:1.6;color:var(--muted)}
.trk-note b{color:var(--text)}
.trk-bad{color:var(--danger)!important}
.trk-h3{font-size:15.5px;font-weight:600;margin:26px 0 6px}
.trk-table{margin-top:14px;border:1px solid var(--border);border-radius:10px;overflow:hidden}
.trk-row{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:9px 14px;font-size:13px;color:var(--muted);border-bottom:1px solid var(--border)}
.trk-row:last-child{border-bottom:none}
.trk-row b{color:var(--text);font-weight:600}
.vote-out{font-weight:600}
.vote-out.right{color:var(--ok)}
.vote-out.wrong{color:var(--danger)}

/* ── Trust Index empty state + sources ─────────────────────────────
   The empty state is shown, never hidden. Concealing a gap is how you end up
   believing you don't have one. */
.trust-none{font-size:12.5px;line-height:1.6;color:var(--muted);border:1px dashed rgba(139,148,168,.35);border-radius:9px;padding:11px 13px;margin-top:2px}
.cite-sec{border-top:1px solid var(--border);padding-top:22px}
.cite-note{font-size:13px;color:var(--muted);margin:0 0 14px;line-height:1.6;max-width:600px}
.cite-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px;counter-reset:cite}
.cite-item{border-left:2px solid var(--border);padding-left:13px}
.cite-item.supports{border-left-color:var(--teal)}
.cite-item.disputes{border-left-color:var(--crisis)}
.cite-link{font-size:14px;font-weight:500;line-height:1.45}
.cite-meta{font-size:10.5px;color:var(--muted);margin-top:3px}
.cite-pub{color:var(--text)}
.cite-stance{letter-spacing:.08em}
.cite-item.supports .cite-stance{color:var(--teal)}
.cite-item.disputes .cite-stance{color:var(--crisis)}

/* ============================================================
   FOCUS — every interactive element, one ring.
   There were no focus styles at all before this: the browser default
   outline was never restored after the reset, so keyboard users had no
   visible caret anywhere on the site. This is the single highest-impact
   a11y fix in the file, which is why it sits at the top of this block.
   :focus-visible, not :focus — mouse users should not see rings.
   ============================================================ */
:root{--focus:#FFD37A}
:where(a,button,summary,input,select,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--focus);outline-offset:2px;border-radius:6px}
/* Cards are links wrapping a block; make the ring hug the card, not the text run. */
.pulse-card-link,.conn-card-link,.conn-link,.rel-node,.journey-step{display:block;border-radius:14px}
.pulse-card-link:focus-visible,.conn-card-link:focus-visible,.conn-link:focus-visible,
.rel-node:focus-visible,.journey-step:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
/* Paper reading mode inverts the surface — the amber ring vanishes on cream. */
.paper-mode .read-surface :where(a,button):focus-visible{outline-color:#8A5A12}
/* The globe canvas is draggable, so it is focusable and must show it. */
#globe canvas:focus-visible,.map-globe canvas:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
/* RESERVE THE GLOBE'S HEIGHT BEFORE IT EXISTS.
   #globe is empty until globe.js builds a canvas into it, so it was 0px tall
   through first paint and then jumped to 300–480px, shoving every card, hub
   and paragraph below it down the page. That was the site's worst layout
   shift: CLS 0.41 on /en/map/ against a 0.1 hard fail, on a page whose own
   standfirst argues that a shift mid-sentence costs comprehension.

   These three lines restate globe.js's resize():
       h = opts.height || max(300, min(w * 0.66, 480))
   aspect-ratio gives the w*0.66, min/max-height give the clamp. Neither caller
   passes opts.height, so this is the whole formula — the box the browser
   reserves is the box the canvas ends up occupying, to the pixel, and nothing
   moves when it arrives.

   Keep the two in step: change one and you must change the other. globe.js
   carries the same warning above resize(). */
#globe{aspect-ratio:100/66;min-height:300px;max-height:480px}
.skip-link{position:absolute;left:-9999px;top:0;z-index:100;background:var(--amber);color:var(--bg);
  font-family:var(--mono);font-size:12px;font-weight:600;padding:10px 16px;border-radius:0 0 8px 0}
.skip-link:focus{left:0;color:var(--bg)}

/* ============================================================
   BREAKPOINTS — one scale, used everywhere.
     640px  phone     single column, stack everything
     960px  tablet    drop to one column where two sat side by side
   Sections previously each invented their own (620, 640, or nothing at
   all), so the layout broke at different widths in different places.
   Any new @media rule in this file uses one of these two numbers.
   ============================================================ */

/* ---- Region hubs (generated by tools/build.js) ---- */
.reg-main{padding:32px 28px 80px}
.reg-top{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.reg-h1{font-size:34px;font-weight:700;margin:0}
.reg-status{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;font-weight:500}
.reg-status.big{font-size:13.5px}
.reg-dot{width:9px;height:9px;border-radius:50%;flex:none;box-shadow:0 0 10px currentColor}
.reg-actions{margin-left:auto;display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.reg-link{font-size:13px}
.btn-follow{border-color:var(--teal);color:var(--teal)}
.btn-follow:hover{background:rgba(79,209,197,.12)}
.reg-lede{color:var(--muted);font-size:15px;margin:8px 0 26px;max-width:600px;line-height:1.6}
.reg-health{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;margin-bottom:10px}
.reg-hcard{padding:18px 20px}
.reg-h-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:10px}
.reg-h-val{font-size:15px;font-weight:600}
.reg-h-fill{height:100%;border-radius:3px}
.reg-h-trend{font-size:10.5px;color:var(--muted);margin-top:8px}
.reg-h-note{font-size:10.5px;color:var(--muted);margin:0 0 34px}
/* The not-yet-assessed state. Deliberately a full panel, not a quiet dash:
   the gap is the message. */
.reg-none{padding:20px 22px;margin-bottom:34px;border-style:dashed}
.reg-none-k{font-size:10.5px;letter-spacing:.14em;color:var(--muted);margin-bottom:8px}
.reg-none-b{margin:0;font-size:13.5px;line-height:1.6;color:var(--muted);max-width:640px}
.sec-34{margin-bottom:34px}
.reg-sec-top{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:6px;flex-wrap:wrap;gap:8px}
.reg-sec-lede{color:var(--muted);font-size:13.5px;margin:0 0 14px;max-width:560px;line-height:1.55}
.reg-tags{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:34px}
.reg-grid{display:grid;grid-template-columns:1.2fr .8fr;gap:28px;align-items:start}
.reg-side{display:flex;flex-direction:column;gap:26px}
.reg-planned{margin:0;padding-left:18px;color:var(--muted);font-size:13.5px;line-height:1.7}
.reg-planned li{margin-bottom:6px}
.echo-list{display:flex;flex-direction:column}
.echo-row{display:flex;gap:16px}
.echo-dot{width:11px;height:11px;border-radius:50%;flex:none;margin-top:4px;background:var(--panel);border:2px solid var(--muted)}
.echo-dot.now{background:var(--amber);border-color:rgba(232,163,61,.4)}
.echo-line{width:2px;flex:1;background:rgba(139,148,168,.25)}
.echo-body{padding-bottom:24px}
.echo-when{font-size:11px;color:var(--amber);margin-bottom:3px}
.prof-list{display:flex;flex-direction:column;gap:10px}
.prof-card{border-radius:14px;padding:14px 16px;display:flex;gap:13px;align-items:center}
.prof-av{width:44px;height:44px;border-radius:50%;flex:none;background:radial-gradient(circle at 35% 30%,#2a3552,#141c30);
  border:1px solid rgba(139,148,168,.3);display:flex;align-items:center;justify-content:center;font-weight:600;font-size:15px;color:var(--muted)}
.prof-name{font-weight:600;font-size:14.5px}
.prof-role{font-size:12px;color:var(--muted);margin:2px 0 5px}
.prof-traits{font-size:10px;color:var(--teal)}
.conn-list{display:flex;flex-direction:column;gap:8px}
.conn-item{display:flex;flex-direction:column;gap:4px}
.conn-card{display:flex;justify-content:space-between;align-items:center;gap:10px;border-radius:12px;padding:12px 15px}
/* A connection with no analysis behind it has no Impact Score. It used to
   show a hand-typed one regardless. */
.conn-noscore{font-size:10px;letter-spacing:.06em;color:var(--muted);border:1px dashed var(--border);
  padding:3px 8px;border-radius:6px;white-space:nowrap}
/* ---- Region hub Influence Meter ----
   One actor, generated into the HTML by tools/build.js (it was assembled by a
   script on load, so the hub's rating was invisible to crawlers and to readers
   without JS while the contest panel doing the same job was in the markup).

   The panel leads with the actor it is rating. The old layout was a radar and a
   stack of bars pushed apart by a `1fr` column with nothing naming the subject
   until a legend at the bottom — the reader met the numbers before the thing
   they described. Now: a header carrying the name, the composite and the
   strongest axis, then the radar and the six bars beneath it as evidence for
   the figure already stated. Bars are the same top-line-plus-meter shape as the
   region health cards, so the two panels on the page read as one system. */
.infl-region{display:grid;grid-template-columns:minmax(0,300px) 1fr;gap:10px 28px;align-items:start;padding:20px 22px}
.ir-head{grid-column:1/-1;display:flex;align-items:flex-end;gap:14px 26px;flex-wrap:wrap;
  border-bottom:1px solid var(--border);padding-bottom:14px;margin-bottom:6px}
.ir-id{display:flex;align-items:center;gap:9px;margin-right:auto}
.ir-name{font-size:17px;font-weight:600}
.ir-code{font-size:9px;letter-spacing:.12em;color:var(--muted);border:1px solid var(--border);border-radius:5px;padding:2px 6px}
.ir-stat{display:flex;flex-direction:column;gap:3px;text-align:right}
.ir-k{font-size:9px;letter-spacing:.14em;color:var(--muted)}
.ir-comp{font-size:30px;font-weight:600;line-height:1;color:var(--amber)}
.ir-strong-v{font-size:15px;font-weight:500;color:var(--teal);line-height:1.2}
.ir-radar{align-self:center;padding:4px 0}
.ir-bars{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px;align-self:center}
.ir-row-top{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:5px}
.ir-axis{font-size:12.5px;color:var(--text)}
.ir-val{font-size:12.5px;color:var(--amber);font-variant-numeric:tabular-nums}
.ir-fill{height:100%;border-radius:3px;background:var(--amber)}
@media(max-width:640px){
  .infl-region{grid-template-columns:1fr;padding:16px 18px}
  .ir-stat{text-align:left}
  .ir-id{margin-right:0;width:100%}
}

/* ---- Homepage World Pulse + Live connections ---- */
.pulse-card{cursor:pointer;height:100%}
.pulse-dot{width:10px;height:10px;border-radius:50%;flex:none}
/* A region with no considered read yet is not a failed reading — it is a blank
   we have not filled in. Drawn as a dimmer version of a live dot it reads as
   "broken"; the difference has to be in KIND, not in brightness. A hollow ring
   is an outline waiting to be filled, which is precisely what it is. No glow:
   the glow is the thing that says "this is a live signal". */
.pulse-dot.pending{background:none;box-shadow:none;border:1.5px solid var(--muted)}
.pulse-card.pending{border-style:dashed}
.pulse-status{font-size:12.5px;font-weight:500}
.conn-card-wrap{display:flex;flex-direction:column;gap:6px}
.conn-card-link{flex:1}
.conn-big{border-radius:16px;padding:20px;gap:12px}
.conn-big-top{display:flex;justify-content:space-between;align-items:center;gap:10px}
.conn-route{font-size:11px;color:var(--teal)}
.conn-big-title{font-weight:600;font-size:16.5px;line-height:1.35;color:var(--text);text-wrap:pretty}
.conn-big-chain{font-size:13px;color:var(--muted);line-height:1.55}
.conn-big-foot{display:flex;justify-content:space-between;align-items:center;margin-top:auto}
.conn-big-when{font-size:10.5px;color:var(--amber)}

/* ============================================================
   SOURCES PANEL (sources.js)
   The count is a button, and pressing it lists what the count is made of.
   ============================================================ */
.src-row,.conn-src-row{display:flex}
.src-row{margin-top:12px}
.src-trigger{display:inline-flex;align-items:center;gap:7px;background:rgba(79,209,197,.08);
  border:1px solid rgba(79,209,197,.35);color:var(--teal);font-size:10.5px;letter-spacing:.06em;
  padding:5px 11px;border-radius:999px;cursor:pointer;white-space:nowrap}
.src-trigger:hover{background:rgba(79,209,197,.16);color:var(--teal)}
/* Nothing cited is a state with a meaning, not an error — muted, not alarming. */
.src-trigger.empty{background:transparent;border-color:var(--border);border-style:dashed;color:var(--muted)}
.src-trigger.empty:hover{border-color:var(--muted);color:var(--text)}
.src-ico{font-size:9px}
.src-backdrop{position:fixed;inset:0;z-index:200;background:rgba(8,12,22,.72);backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;padding:24px;animation:srcIn .12s ease-out}
@keyframes srcIn{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){.src-backdrop{animation:none}}
.src-panel{background:var(--panel);border:1px solid var(--border);border-radius:18px;
  max-width:560px;width:100%;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 24px 70px rgba(0,0,0,.5)}
.src-head{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;
  padding:20px 22px 14px;border-bottom:1px solid var(--border)}
.src-k{font-size:10px;letter-spacing:.18em;color:var(--muted);margin-bottom:5px}
.src-title{font-size:16px;font-weight:600;margin:0;line-height:1.35;text-wrap:pretty}
.src-close{background:none;border:1px solid var(--border);color:var(--muted);font-size:17px;line-height:1;
  width:30px;height:30px;border-radius:8px;cursor:pointer;flex:none}
.src-close:hover{border-color:var(--amber);color:var(--amber)}
.src-body{padding:18px 22px 22px;overflow-y:auto}
.src-trust{display:flex;justify-content:space-between;gap:10px;font-size:10.5px;letter-spacing:.1em;color:var(--muted)}
.src-split{font-size:10.5px;color:var(--muted);margin-top:8px;line-height:1.5}
.src-list{margin:16px 0 0;padding:0 0 0 18px;display:flex;flex-direction:column;gap:14px}
.src-item{border-left:2px solid var(--border);padding-left:12px;margin-left:-18px;list-style:none}
.src-item.supports{border-left-color:var(--teal)}
.src-item.disputes{border-left-color:var(--crisis)}
.src-link{font-size:14px;font-weight:500;line-height:1.45}
.src-ext{font-size:11px;opacity:.7}
.src-meta{font-size:10.5px;color:var(--muted);margin-top:3px}
.src-stance{letter-spacing:.08em}
.src-item.supports .src-stance{color:var(--teal)}
.src-item.disputes .src-stance{color:var(--crisis)}
.src-none{margin:0;font-size:13.5px;line-height:1.65;color:var(--muted)}
.src-foot{font-size:11.5px;color:var(--muted);margin:16px 0 0;line-height:1.55}

/* ---- Responsive: the two documented breakpoints ---- */
@media (max-width:960px){
  .reg-grid{grid-template-columns:1fr;gap:34px}
}
@media (max-width:640px){
  .reg-main{padding:24px 18px 60px}
  .reg-h1{font-size:26px}
  .reg-actions{margin-left:0;width:100%}
  .reg-health{grid-template-columns:1fr}
  .reg-none{padding:16px 18px}
  .src-backdrop{padding:0;align-items:flex-end}
  .src-panel{max-width:none;border-radius:18px 18px 0 0;max-height:88vh}
  .conn-big{padding:16px}
  .conn-big-title{font-size:15px}
}

/* Region tags now filter the Active connections list, so they look and behave
   like the buttons they are. They stay inert labels on a hub with nothing to
   filter — build.js renders those as <span>, not <button>, because a control
   that filters an empty list advertises a click that does nothing. That was the
   original reason this block killed the affordance; the fix is to make the
   click work, not to hide that it's clickable. */
.reg-tags span.chip{cursor:default}
.reg-tags span.chip:hover{border-color:rgba(139,148,168,.3);color:var(--text)}
.reg-tags button.chip{background:none;color:var(--muted);font-family:inherit;display:inline-flex;align-items:center;gap:7px;transition:border-color .15s,color .15s,background .15s}
.reg-tags button.chip:hover{border-color:var(--amber);color:var(--amber)}
.reg-tags button.chip.on{border-color:var(--amber);background:rgba(232,163,61,.12);color:var(--amber)}
.chip-n{font-size:10px;opacity:.75;font-variant-numeric:tabular-nums}
.reg-tags button.chip.on .chip-n{opacity:.9}
.reg-filter-count{font-size:10.5px;letter-spacing:.06em;color:var(--muted);margin:0 0 12px}
.conn-cats{display:flex;flex-wrap:wrap;gap:5px;margin:6px 0 0}
.conn-cat{font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);border:1px solid var(--border);border-radius:4px;padding:2px 6px}

/* "Who competes here" — the panel a non-actor region gets in place of a radar.
   Teal, not amber: the amber Influence radar is a rating OF this page's subject,
   and this is deliberately not that. Reusing the radar's colour would blur the
   one distinction the panel exists to draw. */
.cont-panel{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:20px;padding:20px 22px}
.cont-row{display:flex;flex-direction:column;gap:7px}
.cont-top{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.cont-name{font-weight:600;font-size:14.5px}
.cont-score{font-size:19px;font-weight:600;color:var(--teal);line-height:1;display:flex;align-items:baseline;gap:5px}
.cont-score-k{font-size:8px;letter-spacing:.12em;color:var(--muted);font-weight:400}
.cont-meter{height:5px}
.cont-fill{height:100%;border-radius:3px;background:var(--teal)}
.cont-why{font-size:12.5px;line-height:1.5;color:var(--muted)}
.cont-top-dim{font-size:8.5px;letter-spacing:.1em;color:var(--muted);opacity:.75}
.cont-foot{font-size:10px;line-height:1.55;color:var(--muted);margin:11px 0 0;border-left:2px solid rgba(79,209,197,.4);padding-left:10px}
.cont-foot b{color:var(--teal)}
@media(max-width:640px){.cont-panel{grid-template-columns:1fr;padding:16px 18px}}

/* Health numbers that are still placeholders say so, in amber, attached to the
   figures rather than in a page-top banner that can be scrolled past or
   switched off wholesale. */
.reg-h-note.placeholder{border:1px solid rgba(232,163,61,.4);background:rgba(232,163,61,.06);border-radius:8px;padding:9px 12px;line-height:1.5;color:var(--muted)}
.reg-h-note.placeholder b{color:var(--amber)}

/* An assessed read ships its reasoning and what informed it. The number alone
   is a thing to believe; the number plus the why is a thing to argue with, and
   arguable is the whole promise on /en/methodology/. */
.reg-h-why{font-size:11.5px;line-height:1.55;color:var(--muted);margin-top:9px;padding-top:9px;border-top:1px solid var(--border)}
.reg-h-assessed{margin-top:12px}
.reg-h-note.subtle{margin-top:7px}
.reg-h-srcs{margin-top:12px;border-left:2px solid rgba(79,209,197,.4);padding:2px 0 2px 12px}
.reg-h-srcs-k{font-size:9px;letter-spacing:.14em;color:var(--teal);margin-bottom:6px}
.reg-h-srcs ol{margin:0;padding-left:16px;font-size:10.5px;line-height:1.7;color:var(--muted)}
.reg-h-srcs a{color:var(--text);text-decoration:underline;text-decoration-color:rgba(139,148,168,.4);text-underline-offset:2px}
.reg-h-srcs a:hover{color:var(--teal);text-decoration-color:var(--teal)}
.reg-h-src-meta{color:var(--muted)}

/* A sourced analysis gets a banner that says so. Same shape as the prototype
   banner, teal instead of amber: this is a statement of fact about the page,
   not a warning about it. */
.demo-banner.sourced{border-color:rgba(79,209,197,.45);background:rgba(79,209,197,.06)}
.demo-banner.sourced b{color:var(--teal)}

/* ---- Section index pages (/en/region/, /en/analysis/) ----
   The two front doors the nav was missing. They reuse the card language of the
   homepage deliberately: a reader arriving at "Analysis" from the nav should
   recognise the same cards they saw under Live connections, not meet a third
   way of showing the same five pieces. */
.idx-main{padding:34px 28px 70px}
.idx-top{max-width:660px;margin:0 0 26px}
.idx-eyebrow{font-size:10px;letter-spacing:.24em;color:var(--muted);display:block;margin-bottom:10px}
.idx-h1{font-size:34px;font-weight:600;margin:0 0 12px;line-height:1.15}
.idx-lede{font-size:15px;line-height:1.65;color:var(--muted);margin:0 0 14px;text-wrap:pretty}
.idx-count{font-size:10.5px;letter-spacing:.06em;color:var(--muted);margin:0;
  border-left:2px solid rgba(232,163,61,.5);padding-left:10px}
.idx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}
.idx-link{display:block;border-radius:14px}
.idx-link:focus-visible{outline:2px solid var(--amber);outline-offset:3px}
.idx-card{gap:10px;transition:border-color .15s,transform .15s}
.idx-link:hover .idx-card{border-color:rgba(232,163,61,.45);transform:translateY(-2px)}
.idx-card-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.idx-card-lede{font-size:13px;line-height:1.55;color:var(--muted);margin:0;flex:1}
/* The meta line reports what the hub has, including what it hasn't. Separators
   are drawn rather than typed so a screen reader doesn't read the dots. */
.idx-card-foot{display:flex;flex-wrap:wrap;gap:4px 8px;font-size:9px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);border-top:1px solid var(--border);padding-top:10px}
/* Separator trails its own item rather than leading the next one: as a flex
   item's ::before it wraps with the item, and a line starting "· INFLUENCE
   METER" reads as a bullet nobody asked for. */
.idx-card-foot span:not(:last-child)::after{content:"·";margin-left:8px;opacity:.5}
.idx-tag{font-size:9px;letter-spacing:.1em;color:var(--muted);border:1px solid var(--border);
  border-radius:5px;padding:2px 7px;white-space:nowrap}
.idx-tag.sourced{color:var(--teal);border-color:rgba(79,209,197,.4)}
.idx-foot{font-size:10px;line-height:1.55;color:var(--muted);margin:22px 0 0;max-width:660px;
  border-left:2px solid rgba(139,148,168,.35);padding-left:10px}
@media (max-width:640px){
  .idx-main{padding:24px 18px 60px}
  .idx-h1{font-size:27px}
  .idx-grid{grid-template-columns:1fr}
}

/* "All analyses →" on a homepage section heading. The section links were the
   only route to the full listings before the index pages existed, and the
   homepage still shows a subset — the way out of a subset should be visible
   from it. */
.sec-more{font-size:11px;letter-spacing:.06em;color:var(--teal);white-space:nowrap}
.sec-more:hover{color:var(--amber)}

/* ---- List layout preference: side by side / vertical (view.js) ----
   Vertical is FULL WIDTH, and every card is relaid as a horizontal row.

   The first cut just collapsed the grid to one narrow column, which was the
   wrong shape twice over: it left two thirds of the page empty, and a card
   built to be tall and narrow does not become a list item by being stacked —
   a World Pulse card is a name, a status and a note, so at any width it was a
   scrap of text in the top-left of a wide empty box.

   So each card type gets a row layout here: the thing you scan by on the left,
   its supporting text in the middle, its metadata right. That is what makes the
   full width worth taking — the text column ends up narrower than the card, so
   line length stays sane while the row uses the space.

   Default (no data-view attribute) is the grid, so a reader who has never
   touched the control, or whose storage is blocked, gets exactly what shipped
   before this existed. */
/* The Balance of Power board is deliberately NOT here. It is four actors held
   side by side to be read against each other — the comparison is the point, and
   a column of them is no longer that. It keeps its grid at every setting. */
:root[data-view="list"] .grid-cards,
:root[data-view="list"] .grid-conn,
:root[data-view="list"] .idx-grid{grid-template-columns:minmax(0,1fr)}
/* Stacked cards no longer need to match a neighbour's height. */
:root[data-view="list"] .card{height:auto}

/* Row layouts are for widths that have room for columns. Below 640px every list
   is already one column and the card keeps its stacked shape — the preference
   is site-wide and can be set from a desktop visit, so the narrow case has to
   hold on its own. */
@media (min-width:641px){
  /* World Pulse: region · status · what's driving it. */
  :root[data-view="list"] .pulse-card{display:grid;
    grid-template-columns:minmax(150px,1fr) minmax(120px,150px) minmax(0,2.4fr);
    align-items:center;gap:20px;padding:14px 18px}

  /* Live connections / the analysis index: the story on the left, the metadata
     rail on the right. .conn-big-top keeps route and Impact together at the top
     of the text column — the badge is inside it, so it cannot move to the rail
     without changing the markup on both the generated and hand-written pages. */
  :root[data-view="list"] .conn-big{display:grid;
    grid-template-columns:minmax(0,1fr) minmax(150px,190px);
    grid-template-areas:"top meta" "title meta" "chain meta";
    align-items:start;gap:7px 26px}
  /* Route and Impact sit together at the head of the row. Left spread apart,
     the badge lands in the middle of the card against nothing — a number
     floating between the text column and the rail, attached to neither. */
  :root[data-view="list"] .conn-big-top{grid-area:top;justify-content:flex-start;gap:12px}
  :root[data-view="list"] .conn-big-title{grid-area:title}
  :root[data-view="list"] .conn-big-chain{grid-area:chain;max-width:70ch}
  :root[data-view="list"] .conn-big-foot{grid-area:meta;align-self:center;margin-top:0;
    flex-direction:column;align-items:flex-end;gap:8px}
  /* A thumbnail earns its own narrow column instead of the full-bleed band the
     grid card uses — small and square, the way an avatar sits beside a list
     row, so the compact shape of list view holds. */
  :root[data-view="list"] .conn-big.has-thumb{
    grid-template-columns:64px minmax(0,1fr) minmax(150px,190px);
    grid-template-areas:"thumb top meta" "thumb title meta" "thumb chain meta"}
  :root[data-view="list"] .conn-big.has-thumb .conn-thumb{
    grid-area:thumb;display:block;width:64px;height:64px;aspect-ratio:1/1;
    margin:0;border-radius:10px;align-self:start}

  /* Region index: hub + status · lede · what the hub actually holds.
     The first column is wide enough for "North America" beside "Coverage
     expanding" without either wrapping — a name broken across two lines is the
     one thing in the row you scan by, and the ragged heights made the list look
     accidental.
     The meta facts stack one per line instead of running inline: no width fits
     the longest of them ("no connections yet · health not assessed · 4 powers
     contest it") on one line without starving the lede, and wrapping them left
     a separator dangling at the end of every line. Stacked, they need no
     separators at all — same shape as the rail on the analysis rows. */
  :root[data-view="list"] .idx-card{display:grid;
    grid-template-columns:minmax(230px,270px) minmax(0,1fr) minmax(190px,220px);
    align-items:center;gap:22px}
  :root[data-view="list"] .idx-card-top{align-items:center}
  :root[data-view="list"] .idx-card-top .stat-name,
  :root[data-view="list"] .idx-card-top .reg-status{white-space:nowrap}
  :root[data-view="list"] .idx-card-lede{max-width:70ch}
  :root[data-view="list"] .idx-card-foot{border-top:none;padding-top:0;
    flex-direction:column;align-items:flex-end;gap:3px;flex-wrap:nowrap}
  :root[data-view="list"] .idx-card-foot span:not(:last-child)::after{content:none}
  :root[data-view="list"] .idx-card.has-thumb{
    grid-template-columns:56px minmax(230px,270px) minmax(0,1fr) minmax(190px,220px)}
  :root[data-view="list"] .idx-card.has-thumb .conn-thumb{
    display:block;width:56px;height:56px;aspect-ratio:1/1;margin:0;border-radius:8px}

}

.view-segs{display:inline-flex;gap:2px;padding:3px;vertical-align:middle}
.view-segs .seg{font-size:11px;font-weight:500;letter-spacing:.04em;padding:6px 11px;border-radius:6px;
  font-family:var(--mono)}
.view-segs .seg:not(.on){color:var(--muted)}
.view-segs .seg:not(.on):hover{color:var(--text)}
.view-segs .seg:focus-visible{outline:2px solid var(--amber);outline-offset:2px}
/* The controls row above a listing: the count on the left, the layout toggle
   on the right, both reading as furniture around the list rather than part of
   the page's argument. */
.idx-controls{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:16px}
.idx-controls .idx-count{margin:0}
@media (max-width:640px){
  /* Every list is already one column here, so the control would toggle nothing. */
  .view-segs{display:none}
}

/* ── images ────────────────────────────────────────────────────
   Added when the site took its first images. An image here is treated like a
   citation: it always carries a visible credit + licence line (built in
   build.js creditLine()), so the styling's job is to make that line quiet but
   present, never to hide it. Dimensions come from the file via width/height on
   the <img>, so the browser reserves the box and nothing shifts on load. */

/* Inline figure inside the reading surface. Natural aspect — an inline photo is
   evidence, and cropping evidence to a band would defeat the point. */
.nm-fig{margin:22px 0}
.nm-fig img{display:block;width:100%;height:auto;max-height:540px;object-fit:contain;border:1px solid var(--border);border-radius:14px;background:var(--bg)}
.fig-foot{display:flex;flex-wrap:wrap;gap:4px 12px;align-items:baseline;padding:8px 2px 0}
.fig-cap{font-family:var(--serif);font-size:13.5px;line-height:1.45;color:var(--text)}
.fig-credit{font-size:10px;letter-spacing:.05em;color:var(--muted)}
.fig-credit a{color:var(--muted);text-decoration:underline;text-underline-offset:2px}
.fig-credit a:hover{color:var(--teal)}

/* Hero — the banner at the top of an analysis or region page, and the page's
   og:image. Cropped to a consistent 16/9 band so ten hubs don't each open at a
   different height; the crop is cosmetic framing, not the evidentiary use above. */
.nm-hero{margin:20px 0 6px}
.nm-hero img{aspect-ratio:16/9;max-height:none;height:auto;object-fit:cover;border-radius:16px}
.reg-main .nm-hero{margin-top:18px}

/* IMAGE STANDARD 1 (docs/EDITORIAL.md) — an article figure never disappears.
   Article figures (.nm-fig, .nm-hero) flow to the column at every width and are
   never display:none; tests/images.test.js fails the build if that regresses.
   A future desktop layout MAY float or grid a figure beside text, but it must
   return to the reading flow on narrow screens rather than be removed — this is
   the collapse pattern to copy. The <img> caps at 100% so it resizes, never
   overflows, and the box the browser reserved (width/height) still holds. */
.nm-fig img,.nm-hero img{max-width:100%}
@media (max-width:640px){
  .nm-fig,.nm-hero{float:none;width:auto;margin-left:0;margin-right:0}
}

/* Paper reading mode recolours the reading surface to cream; the caption and
   credit have to follow or they vanish against it. */
.paper-mode .read-surface .nm-fig img{border-color:rgba(44,36,24,.15)}
.paper-mode .read-surface .fig-cap{color:var(--cream-text)}
.paper-mode .read-surface .fig-foot,
.paper-mode .read-surface .fig-credit,
.paper-mode .read-surface .fig-credit a{color:var(--cream-muted)}

/* Card thumbnail — a cropped preview bleeding to the card edges. overflow:hidden
   on the card clips it to the rounded corners; the credit rides along as the
   <img> title tooltip since the card has no room for a caption. */
.conn-thumb{aspect-ratio:16/9;overflow:hidden;background:var(--bg)}
.conn-thumb img{display:block;width:100%;height:100%;object-fit:cover}
.card.has-thumb{overflow:hidden}
.conn-big.has-thumb .conn-thumb{margin:-20px -20px 4px}
.idx-card.has-thumb .conn-thumb{margin:-16px -18px 6px}
@media (max-width:640px){
  .conn-big.has-thumb .conn-thumb{margin:-16px -16px 4px}
}
/* List view is the compact mode, so the full-bleed thumbnail above shrinks to
   a small square beside the row instead of disappearing — see the
   .has-thumb overrides in the list-layout block above (min-width:641px). Below
   that width every list is already one column and keeps the grid card's
   full-bleed shape, same as every other list-view exception at that width. */

/* --- Citation Explorer (/en/sources/) --------------------------------
   Reuses .cite-item's stance colouring rather than restating it: teal
   supports, orange disputes, everywhere a citation appears. Two definitions of
   "what a disputing source looks like" is the drift this file already learned
   about the hard way. */
.src-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--border);border-radius:14px;overflow:hidden;margin:0 0 34px}
.src-stat{background:var(--panel);padding:18px 16px;display:flex;flex-direction:column;gap:5px}
.src-stat-v{font-size:26px;font-weight:600;color:var(--amber);line-height:1}
.src-stat-k{font-size:11.5px;color:var(--muted)}
.src-shared-sec{margin-bottom:38px}
.src-shared-note{font-size:14.5px;line-height:1.6;max-width:74ch;margin:6px 0 16px}
.src-shared-list{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px}
.src-shared-card{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:14px 16px}
.src-shared-pub{font-size:14px;font-weight:600;display:block}
.src-shared-n{font-size:10.5px;color:var(--teal);letter-spacing:.08em}
.src-shared-links{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-direction:column;gap:5px}
.src-shared-links a{font-size:12.5px;line-height:1.4}

.src-filters{display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end;margin-bottom:14px}
.src-f{display:flex;flex-direction:column;gap:5px}
.src-f-k{font-size:10px;letter-spacing:.16em;color:var(--muted)}
.src-f input,.src-f select{background:var(--panel);border:1px solid var(--border);border-radius:8px;color:var(--text);font-family:var(--sans);font-size:13px;padding:8px 11px;min-width:190px}
.src-f input:hover,.src-f select:hover{border-color:rgba(232,163,61,.5)}
.src-reset{background:none;border:1px solid var(--border);color:var(--muted);font-size:13px;padding:8px 15px;border-radius:8px;cursor:pointer}
.src-reset:hover{border-color:var(--amber);color:var(--amber)}
.src-count{font-size:11px;color:var(--muted);letter-spacing:.06em;margin:0 0 14px}
.src-pub-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.src-pub{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:15px 18px}
.src-pub-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:11px}
.src-pub-name{font-size:15px;font-weight:600;margin:0}
.src-pub-meta{font-size:10.5px;color:var(--muted)}
.src-span{font-size:10px;letter-spacing:.08em;color:var(--bg);background:var(--teal);padding:2px 8px;border-radius:5px}
.src-cite-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px}
.src-cite{border-left:2px solid var(--border);padding-left:13px}
.src-cite.supports{border-left-color:var(--teal)}
.src-cite.disputes{border-left-color:var(--crisis)}
.src-cite.supports .cite-stance{color:var(--teal)}
.src-cite.disputes .cite-stance{color:var(--crisis)}
.src-empty{font-size:14px;color:var(--muted);padding:26px 0}
.src-reset-inline{background:none;border:none;color:var(--teal);font-size:14px;cursor:pointer;padding:0;text-decoration:underline}
.src-reset-inline:hover{color:var(--amber)}
@media (max-width:960px){ .src-stats{grid-template-columns:repeat(2,1fr)} }
@media (max-width:640px){
  .src-stats{grid-template-columns:repeat(2,1fr)}
  .src-f,.src-f input,.src-f select{width:100%;min-width:0}
  .src-filters{gap:10px}
  .src-reset{width:100%}
}

/* --- Confidence history (an estimate that moved, and why) ------------
   Closed by default. 28 of 30 probabilities have never been revised, and
   opening a disclosure on all of them to show a single "initial estimate" row
   would bury the two that did move in the noise of the ones that didn't. */
.prob-hist{margin-top:9px}
.prob-hist-sum{font-size:10.5px;letter-spacing:.06em;color:var(--muted);cursor:pointer;list-style:none;display:inline-flex;align-items:center;gap:6px}
.prob-hist-sum::-webkit-details-marker{display:none}
.prob-hist-sum::before{content:"▸";font-size:9px;transition:transform .15s ease}
.prob-hist[open] .prob-hist-sum::before{transform:rotate(90deg)}
.prob-hist-sum:hover{color:var(--amber)}
.prob-hist-list{list-style:none;margin:10px 0 0;padding:0 0 0 14px;border-left:1px solid var(--border);display:flex;flex-direction:column;gap:12px}
.prob-hist-item{display:flex;flex-direction:column;gap:4px}
.prob-hist-head{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.prob-hist-v{font-size:13px;font-weight:600}
.prob-hist-d{font-size:10px;padding:1px 6px;border-radius:4px;background:rgba(139,148,168,.14);color:var(--muted)}
.prob-hist-d.up{color:var(--danger);background:rgba(248,113,113,.14)}
.prob-hist-d.down{color:var(--ok);background:rgba(74,222,128,.14)}
.prob-hist-at{font-size:10px;color:var(--muted)}
.prob-hist-why{font-size:12.5px;line-height:1.55;color:var(--muted);margin:0;max-width:70ch}

/* ── command palette + /en/search/ ──────────────────────────────
   The palette is a modal dialog, so it needs a real scrim, a locked page
   behind it, and a focus ring that survives on a dark surface. `.pal-sr` is
   the visually-hidden pattern used for the dialog label, the live region and
   the keyboard instructions — all things a screen reader needs and a sighted
   reader gets from the layout itself. */
.pal-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.pal-lock{overflow:hidden}
.pal-overlay{position:fixed;inset:0;z-index:200;background:rgba(6,9,16,.72);backdrop-filter:blur(3px);
  display:flex;align-items:flex-start;justify-content:center;padding:8vh 16px 16px}
.pal-overlay[hidden]{display:none}
.pal-dialog{width:min(720px,100%);max-height:80vh;display:flex;flex-direction:column;
  background:var(--panel);border:1px solid var(--border);border-radius:16px;overflow:hidden;
  box-shadow:0 24px 64px rgba(0,0,0,.5)}
.pal-inputwrap{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--border)}
.pal-input{flex:1;background:transparent;border:0;color:var(--text);font-family:var(--sans);font-size:17px;outline:none;min-width:0}
.pal-input::placeholder{color:var(--muted)}
.pal-esc{border:1px solid var(--border);border-radius:6px;padding:2px 7px;font-size:10.5px;color:var(--muted)}
.pal-list{list-style:none;margin:0;padding:6px;overflow-y:auto;flex:1}
.pal-group{margin:0 0 4px}
.pal-group-h{font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
  margin:10px 10px 4px;font-weight:500;display:flex;gap:8px;align-items:center}
.pal-count{color:var(--muted);font-weight:400}
.pal-sublist{list-style:none;margin:0;padding:0}
.pal-row{border-radius:10px}
.pal-row.is-active{background:rgba(232,163,61,.13);outline:1px solid rgba(232,163,61,.45)}
.pal-link{display:block;padding:9px 11px;color:var(--text)}
.pal-link:hover{color:var(--text)}
.pal-title{display:block;font-size:14.5px;font-weight:500;line-height:1.35;text-wrap:pretty}
.pal-snip{display:block;font-size:12.5px;line-height:1.5;color:var(--muted);margin-top:3px}
.pal-meta{display:block;font-size:10.5px;color:var(--muted);margin-top:4px}
.pal-ep{text-transform:uppercase;letter-spacing:.08em}
.pal-ep-sourced{color:var(--teal)}
.pal-ep-judgment{color:var(--warn)}
.pal-ep-projection{color:#A78BFA}
.pal-hint{color:var(--muted);font-size:13.5px;line-height:1.6;padding:18px 14px;margin:0}
.pal-foot{display:flex;justify-content:space-between;align-items:center;gap:10px;
  padding:9px 14px;border-top:1px solid var(--border);font-size:10.5px;color:var(--muted)}
.nav-search{display:inline-flex;align-items:center;gap:6px;background:transparent;border:1px solid var(--border);
  border-radius:8px;color:var(--muted);font-size:11.5px;padding:5px 9px;cursor:pointer}
.nav-search:hover{color:var(--text);border-color:var(--muted)}
.nav-k{border:1px solid var(--border);border-radius:4px;padding:0 4px;font-size:10px}
/* The search page reuses .pal-list and its rows, so the two surfaces cannot
   drift apart visually any more than they can behaviourally. */
.sf-form{display:flex;gap:10px;flex-wrap:wrap;margin:18px 0 8px}
.sf-l{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.sf-input{flex:1;min-width:240px;background:var(--panel);border:1px solid var(--border);border-radius:10px;
  color:var(--text);font-family:var(--sans);font-size:16px;padding:11px 14px}
.sf-go{background:var(--amber);color:var(--bg);border:0;border-radius:10px;font-weight:600;font-size:14px;padding:11px 20px;cursor:pointer}
.sf-help{font-size:11px;color:var(--muted);margin:0 0 14px;line-height:1.6}
.sf-facets{display:flex;flex-direction:column;gap:7px;margin:0 0 12px}
.sf-group{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.sf-label{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);min-width:64px}
.sf-chip{background:transparent;border:1px solid var(--border);border-radius:999px;color:var(--muted);
  font-size:11px;padding:4px 10px;cursor:pointer}
.sf-chip:hover{color:var(--text);border-color:var(--muted)}
.sf-chip.on{background:rgba(232,163,61,.14);border-color:var(--amber);color:var(--text)}
.sf-n{color:var(--muted)}
.sf-status{font-size:11px;color:var(--muted);margin:0 0 8px}
.sf-results{padding:0}
.sf-noscript{color:var(--muted);font-size:14px;line-height:1.7;border:1px solid var(--border);border-radius:12px;padding:14px 16px}
@media (max-width:640px){.nav-search-t,.nav-k{display:none}.pal-overlay{padding:4vh 8px 8px}}
/* axe `link-in-text-block`: a link inside running prose must be distinguishable
   from the text around it by more than colour. The site's nav and card links
   are their own blocks and do not need this; these are the places where a link
   sits mid-sentence. */
.pal-hint a,.sf-noscript a,.sf-help a,.idx-foot a{text-decoration:underline;text-underline-offset:2px}
.pal-hint-li{list-style:none}
.pal-group{list-style:none}

/* ── /en/timeline/ ──────────────────────────────────────────────
   Reuses .tl-row / .tl-rail / .tl-line from the per-analysis dominoes section
   — FEATURES.md §3 says the visual language already exists, and a second one
   would be a second thing to keep in step. */
.tlx-filters{margin:16px 0 8px}
.tlx-precnote{font-size:11px;color:var(--muted);line-height:1.7;margin:0 0 18px;
  border-left:2px solid var(--border);padding-left:12px}
.tlx-list,.tlx-items{list-style:none;margin:0;padding:0}
.tlx-group{margin:0 0 22px}
.tlx-group[hidden]{display:none}
.tlx-month{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
  font-weight:500;margin:0 0 10px;padding-bottom:6px;border-bottom:1px solid var(--border);
  display:flex;justify-content:space-between}
.tlx-n{color:var(--muted)}
.tlx-row{display:flex;gap:2px}
.tlx-row[hidden]{display:none}
.tlx-dot{width:9px;height:9px;border-radius:50%;flex:none;margin-top:5px;background:var(--muted)}
.tlx-dot-event{background:var(--amber)}
.tlx-dot-source{background:var(--teal)}
.tlx-dot-estimate{background:#A78BFA}
.tlx-dot-revision{background:var(--warn)}
.tlx-dot-published{background:var(--text)}
.tlx-body{padding-bottom:16px;min-width:0}
.tlx-date{display:block;font-size:10.5px;color:var(--muted);letter-spacing:.06em}
.tlx-title{display:block;font-size:14.5px;font-weight:500;line-height:1.4;margin-top:2px;text-wrap:pretty}
.tlx-note{font-size:12.5px;line-height:1.55;color:var(--muted);margin:4px 0 0;text-wrap:pretty}
.tlx-meta{font-size:10px;color:var(--muted);margin-top:5px;display:flex;flex-wrap:wrap;gap:5px}
.tlx-kind{text-transform:uppercase;letter-spacing:.08em}
.tlx-ep-sourced{color:var(--teal)}
.tlx-ep-judgment{color:var(--warn)}
.tlx-ep-projection{color:#A78BFA}
.tlx-val{color:var(--text)}
.tlx-prec{border:1px solid var(--border);border-radius:999px;padding:0 6px}

/* ── print ──────────────────────────────────────────────────────
   FEATURES.md Feature 9, Tier 1. Pure progressive enhancement: nothing here
   can affect the screen, and a browser that ignores it prints what it printed
   before.

   THE PRINTOUT IS THE ARGUMENT PLUS ITS EVIDENCE. What survives is the chain,
   the four framework answers, the sourced/prototype banner, the confidence
   labels and — above all — the citations, with their URLs spelled out, because
   a printed link a reader cannot follow is not a citation. What goes is
   everything that only makes sense on a screen: the nav, the search trigger,
   the vote widget, the reading-progress rail, the related-web, the theme
   toggle.

   No `content: attr(href)` on every link — that turns "the EU adopted
   Regulation 2026/261" into an unreadable line of URL. Only citation links get
   their address printed, because those are the ones a reader is expected to go
   and check.

   Reuses the paper-mode palette rather than inventing a print one: the site
   already has a considered cream reading surface, and print is exactly the
   place it belongs. */
@media print {
  /* Ink. The dark theme is a screen choice; on paper it is a solid rectangle
     of toner and unreadable at any sensible printer setting. */
  /* EVERY status colour is re-pointed, not just the brand ones. The first
     version of this block missed --crisis, and `disputes` printed orange at
     2.2:1 — a stance label, which is one of the things a printed citation
     exists to carry. On paper the word does the work and the colour only has
     to stay readable. */
  :root{--bg:#fff;--panel:#fff;--text:#111;--muted:#4a4a4a;--border:rgba(0,0,0,.28);
    --amber:#8A5A12;--teal:#0F6E66;--cream:#fff;--cream-text:#111;--cream-muted:#4a4a4a;
    --ok:#1B6B33;--warn:#7A5A00;--crisis:#9A3412;--danger:#9B1C1C;--focus:#111}
  html,body{background:#fff!important;color:#111!important}
  .read-surface,.panel,.card,.an-surface{background:#fff!important;color:#111!important;
    border-color:rgba(0,0,0,.28)!important;box-shadow:none!important}

  /* Screen-only furniture. */
  header.site,footer.site,.skip-link,.nav-search,.journey,.an-tools,.btn-theme,
  .vote-ask,.vote-q,.vote-btn,.pal-overlay,.view-controls,.src-filters,
  .tlx-filters,.sf-form,.sf-facets,.sf-help,#tlx-status,#search-status,
  .rel-web,.src-reset,.src-reset-inline{display:none!important}

  /* Let the page breathe at print width rather than at a screen container. */
  .container{max-width:none!important;padding:0!important}
  main{padding:0!important}

  /* Never split a claim from its evidence, or a heading from what it heads. */
  .q-head,.dom-head,.rev-head,.next-head,.h-sec,h1,h2,h3{break-after:avoid-page;page-break-after:avoid}
  .tl-row,.cite-list li,.rev-item,.prob-hist-item,.q-body,.stat-cell,
  .src-cite,.tlx-row,.pal-row{break-inside:avoid-page;page-break-inside:avoid}

  /* The one place a URL earns its ink. */
  .cite-list a[href]::after,.src-cite a[href]::after{
    content:" <" attr(href) ">";font-size:9.5px;color:#333;word-break:break-all}
  a{color:#111!important;text-decoration:underline}

  /* The epistemic labels are the point of the page, so they must survive being
     printed in black and white — colour alone cannot carry them on paper. */
  .conf-pill,.demo-banner,.tlx-ep,.pal-ep{border:1px solid rgba(0,0,0,.4)!important;
    color:#111!important;background:transparent!important}
  .conf-dot,.tlx-dot{outline:1px solid #111}

  /* Meters and bars are decoration once they cannot animate; the number beside
     them already says it. */
  .meter,.prob-track,.imp-track-h,.trust-fill,.prob-fill,.an-glow{display:none!important}

  img{max-width:100%!important;break-inside:avoid}
  .conn-thumb{display:none!important}

  @page{margin:16mm 14mm}
}

/* WCAG 1.4.1 (use of colour) — axe `link-in-text-block`. A link inside running
   prose must be distinguishable from the text around it by something other than
   hue. Nav items, cards and buttons are their own blocks and are exempt; these
   are the places a link sits mid-sentence.
   --muted went #8B94A8 -> #949CB0 and --cream-muted #8a7d63 -> #6F6450 in the
   same pass: both were under 4.5:1 on their own surfaces (4.45 and 3.53). */
.stat-foot a,.imp-note a,.lens-note a,.q-body a,.wim-out a,.rev-why a,
.dom-note a,.prob-hist-why a,.an-meta a,.trust-note a,.reg-h-note a,.reg-lede a,
.reg-h-basis a,.meth-lede a,.demo-banner a{text-decoration:underline;text-underline-offset:2px}
/* The general rule, rather than an ever-growing list of containers: a link in
   running prose carries no class of its own, while every component link
   (cards, nav, chips, source triggers) has one. `:not([class])` separates them
   exactly, and stops the next paragraph from reintroducing the failure. */
p a:not([class]),li a:not([class]),span.imp-foot a,.stat-foot a,.fig-foot a{text-decoration:underline;text-underline-offset:2px}

/* Audio mode. The button is created by audio.js and only when speechSynthesis
   exists, so these styles apply to a control that is always functional. */
.aud-btn{display:inline-flex;align-items:center;gap:6px;background:transparent;
  border:1px solid var(--border);border-radius:8px;color:var(--muted);
  font-size:11.5px;padding:5px 10px;cursor:pointer}
.aud-btn:hover{color:var(--text);border-color:var(--muted)}
.aud-btn[aria-pressed="true"]{border-color:var(--amber);color:var(--amber)}

/* ============================================================================
   Design-system layer (additive). Everything below EXTENDS the palette at the
   top of this file — it does not replace it. --bg stays #0F1626 (the deliberate
   brand base); --bg-primary is an alias so new components can speak the
   design-token vocabulary without forking a colour. See styles.css :root above.
   ========================================================================== */
:root{
  --bg-primary:var(--bg);
  /* glass surfaces: a translucent panel tint over the dark base, a top-light
     hairline, and the blur radius as one knob. Composited over --bg the tint
     lands near #151d30, so --text (#EDEFF4) keeps a well-above-AA contrast. */
  --glass-bg:rgba(26,35,56,.55);
  --glass-hi:rgba(255,255,255,.05);
  --border-glass:rgba(139,148,168,.22);
  --surface-blur:14px;
  /* spacing + radius scales, so component padding stops being magic numbers */
  --sp-1:6px;--sp-2:10px;--sp-3:16px;--sp-4:22px;--sp-5:32px;--sp-6:48px;
  --r-sm:8px;--r-md:12px;--r-lg:16px;--r-xl:22px;
  --ease-out:cubic-bezier(.22,1,.36,1);
  --shadow-1:0 8px 30px rgba(6,10,20,.45);
  /* the globe's outer atmosphere; #globe shows it through the canvas corners,
     which globe.js clears to transparent. */
  --atmos:radial-gradient(closest-side,rgba(79,209,197,.16),rgba(79,209,197,.05) 55%,transparent 78%);
}

/* Glassmorphic surface — opt-in via .glass on any panel/card/article shell.
   backdrop-filter is progressive: where it is unsupported (@supports below) the
   element falls back to the solid --panel it would have had anyway. */
.glass{background:var(--glass-bg);border:1px solid var(--border-glass);border-radius:var(--r-lg);
  box-shadow:var(--shadow-1),inset 0 1px 0 var(--glass-hi);
  -webkit-backdrop-filter:blur(var(--surface-blur));backdrop-filter:blur(var(--surface-blur))}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.glass{background:var(--panel)}}

/* Subtle hover elevation for analytics cards. Transform + shadow only — no
   layout property animates, so this can never cause reflow or CLS. */
.card,.infl-card{transition:transform .25s var(--ease-out),border-color .25s var(--ease-out),box-shadow .25s var(--ease-out)}
a .card:hover,.infl-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-1)}
@media (prefers-reduced-motion:reduce){.card,.infl-card{transition:none}a .card:hover,.infl-card:hover{transform:none}}

/* Reading mode — an optimal measure for long prose. The framework answers and
   "why it matters" body are constrained to ~68 characters; the structural
   elements (meters, figures, source lists) keep the full surface width.
   scroll-margin clears the sticky header when a TOC link jumps to a section. */
.read-surface .q-body,.read-surface .wim-out{max-width:68ch}
.q-head{scroll-margin-top:84px}

/* Fixed table of contents (built by audio.js on analysis pages) with scroll-spy.
   It is position:fixed and additive, so it never reflows the article, and it
   only appears where the centred 1100px column leaves real gutter room for it —
   below that the article simply reads without it. */
.toc{position:fixed;top:92px;left:clamp(16px,calc(50vw - 748px),560px);width:184px;
  max-height:72vh;overflow-y:auto;z-index:40;display:none}
.toc-h{font-family:var(--mono);font-size:10px;letter-spacing:.18em;color:var(--muted);margin:0 0 10px;text-transform:uppercase}
.toc ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.toc a{display:block;font-size:12.5px;line-height:1.35;color:var(--muted);padding:5px 10px;
  border-left:2px solid var(--border);border-radius:0 6px 6px 0;
  transition:color .2s,border-color .2s,background .2s}
.toc a:hover{color:var(--text)}
.toc a.on{color:var(--amber);border-left-color:var(--amber);background:rgba(232,163,61,.08)}
@media (min-width:1520px){.toc.ready{display:block}}
@media (prefers-reduced-motion:reduce){.toc a{transition:none}}

/* Waveform beside the Listen button — five bars that animate only while the
   reader is speaking (.on) and hold flat otherwise. Decorative (aria-hidden),
   and fully stilled under reduced-motion, where the flat bars still read as an
   active-vs-idle state without any movement. */
.aud-wave{display:inline-flex;align-items:flex-end;gap:2px;height:14px;opacity:0;transition:opacity .2s}
.aud-wave.on{opacity:1}
.aud-wave i{width:2px;height:4px;background:var(--amber);border-radius:1px}
.aud-wave.on i{animation:audWave .9s var(--ease-out) infinite}
.aud-wave.on i:nth-child(2){animation-delay:.15s}
.aud-wave.on i:nth-child(3){animation-delay:.3s}
.aud-wave.on i:nth-child(4){animation-delay:.45s}
.aud-wave.on i:nth-child(5){animation-delay:.6s}
@keyframes audWave{0%,100%{height:4px}50%{height:14px}}
@media (prefers-reduced-motion:reduce){.aud-wave.on i{animation:none;height:9px}}

/* Atmospheric glow behind the globe. globe.js clears the canvas to transparent
   outside the sphere, so this radial gradient shows through around the limb and
   gives the globe outer depth. It is an absolutely-positioned pseudo-element, so
   it changes no box size and cannot shift the reserved #globe height (no CLS).
   pointer-events:none keeps the drag surface intact. */
#globe,.map-globe{position:relative;isolation:isolate}
#globe::before,.map-globe::before{content:"";position:absolute;inset:-8% -8% -12%;z-index:-1;
  background:var(--atmos);pointer-events:none}

/* Mobile bottom sheets (< 768px). A centre modal opens away from the thumb; the
   command palette (the site's one modal) instead slides up from the bottom as a
   sheet with a grab-bar handle in the thumb zone. Pure CSS over the existing
   .pal-overlay markup — palette.js is untouched, and the focus trap / aria-modal
   it already sets still hold. .info-panel is the same treatment as a reusable
   class for any future sheet. */
@media (max-width:767px){
  .pal-overlay{align-items:flex-end;padding:0}
  .pal-dialog,.info-panel{width:100%;max-height:86vh;border-radius:20px 20px 0 0;border-bottom:0;
    padding-top:8px;animation:sheetUp .32s var(--ease-out)}
  .pal-dialog::before,.info-panel::before{content:"";display:block;width:38px;height:4px;border-radius:999px;
    background:var(--border-glass);margin:0 auto 6px}
}
@keyframes sheetUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
@media (max-width:767px) and (prefers-reduced-motion:reduce){.pal-dialog,.info-panel{animation:none}}

@media print{.toc,.aud-wave{display:none!important}}
