/* css/third-country.css — native #third-country tab frame + TCD engine UI.
   Engine UI (.tcd-counters/.tcd-detail) is appended INTO #tcd-globe by tcd.js;
   theme.js scopes --tcd-* vars onto #tcd-globe (.tcd-root), so these descendants resolve them.
   Arc/dot colors mirror themes/icetracking.json (arc #7d94f5, arc2 #D9EF56). */

.tcd-container {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 2rem;
    overflow: hidden;
}

/* Below-map frame (2026-07-27 feedback): "Coverage" through "Methodology & Sources"
   sat as loose text directly on the section — no card of its own, so it had no
   internal padding between its content and the section's edge. That's invisible in
   the dark default theme (the section has no fill, so it blends with the page), but
   in the tab's scoped light "newsprint" theme (#third-country.tcd-theme-light), the
   section itself is painted as a paper rectangle and the text touched that paper's
   edge directly. Give it the SAME outer-card treatment as #tcd-container above (same
   tokens, same radius) so the two frames read as one consistent system, plus
   generous padding so nothing inside — article cards, the status band, the table —
   ever touches the border. Nested elements that already carry their own card
   treatment (.table-container, .tcd-asylum-explainer, .corporate-methodology) stay
   as-is; they read as cards-within-the-card, the same relationship #tcd-container
   already has with .tcd-am-neatline. */
.tcd-below-map {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 2rem;
    margin: 0.5rem 0 2rem;
}
.tcd-below-map > *:first-child { margin-top: 0; }
@media (max-width: 600px) {
    .tcd-below-map { padding: 1.25rem; }
}

/* Preset-view chips */
.tcd-presets {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--border);
}
.tcd-presets-label {
    font-family: 'Outfit', 'Century Gothic', sans-serif;
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-caption);
    margin-right: 0.25rem;
}
.tcd-preset {
    font-family: 'DM Sans', sans-serif;
    font-size: 0.78rem;
    color: var(--text-secondary);
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.3rem 0.7rem;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
    min-height: 32px;
}
.tcd-preset:hover { color: var(--text-primary); border-color: var(--accent); }
.tcd-preset.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Globe viewport — engine canvas + overlays live here */
.tcd-globe {
    position: relative;
    width: 100%;
    height: 70vh;
    min-height: 420px;
    max-height: 640px;
    overflow: hidden;
    background: var(--tcd-bg, #1A1819);
}
.tcd-globe .maplibregl-canvas { outline: none; }

/* Counters overlay (engine-rendered) */
.tcd-counters {
    position: absolute;
    left: 12px;
    bottom: 12px;
    z-index: 3;
    display: flex;
    gap: 1.1rem;
    padding: 0.5rem 0.8rem;
    background: rgba(26, 24, 25, 0.78); /* fallback for browsers without color-mix (Safari < 16.2) */
    background: color-mix(in srgb, var(--tcd-bg, #1A1819) 78%, transparent);
    border: 1px solid var(--tcd-border, #3a3738);
    border-radius: 6px;
    backdrop-filter: blur(4px);
}
.tcd-counter { display: flex; flex-direction: column; line-height: 1.05; }
.tcd-counter-v { font-family: 'Outfit', 'Century Gothic', sans-serif; font-size: 1.35rem; color: var(--tcd-text, #F6F3EA); }
.tcd-counter-l { font-family: 'DM Sans', sans-serif; font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--tcd-textDim, #a09d94); }

/* Timelapse date readout (default globe view) — bottom-right clock tracking the sweep cursor */
.tcd-date-readout {
    position: absolute;
    right: 12px;
    bottom: 12px;
    z-index: 3;
    padding: 0.4rem 0.7rem;
    font-family: 'Outfit', 'Century Gothic', sans-serif;
    font-size: 1.05rem;
    letter-spacing: 0.04em;
    font-variant-numeric: tabular-nums;
    color: var(--tcd-text, #F6F3EA);
    background: rgba(26, 24, 25, 0.78); /* fallback for browsers without color-mix */
    background: color-mix(in srgb, var(--tcd-bg, #1A1819) 78%, transparent);
    border: 1px solid var(--tcd-border, #3a3738);
    border-radius: 6px;
    backdrop-filter: blur(4px);
}
.tcd-date-readout[hidden] { display: none; }

/* Detail "receipts" card (engine-rendered) */
.tcd-detail {
    position: absolute;
    right: 12px;
    top: 12px;
    width: 280px;
    max-width: calc(100% - 24px);
    z-index: 4;
    background: var(--tcd-surface, #222021);
    color: var(--tcd-text, #F6F3EA);
    border: 1px solid var(--tcd-border, #3a3738);
    border-radius: 8px;
    padding: 14px;
    font-family: 'DM Sans', sans-serif;
}
.tcd-detail[hidden] { display: none; }
.tcd-detail-close { float: right; background: none; border: none; color: inherit; font-size: 18px; line-height: 1; cursor: pointer; }
.tcd-detail-title { font-family: 'Outfit', sans-serif; margin: 0 0 0.35rem; font-size: 1.05rem; }
.tcd-detail-route, .tcd-detail-count, .tcd-detail-date { margin: 0.15rem 0; font-size: 0.82rem; color: var(--tcd-textDim, #a09d94); }
.tcd-detail-sources { margin-top: 0.5rem; display: flex; flex-direction: column; gap: 0.15rem; }
.tcd-detail-src { color: var(--tcd-accent, #4460D8); text-decoration: underline; text-underline-offset: 2px; font-size: 0.8rem; }

/* Legend */
.tcd-legend {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 0.5rem 0.75rem;
    border-top: 1px solid var(--border);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.7rem;
    color: var(--text-secondary);
}
.tcd-legend-item { display: inline-flex; align-items: center; gap: 0.35rem; }
.tcd-legend-line { display: inline-block; width: 16px; height: 0; border-top: 2px solid #7d94f5; }
.tcd-legend-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #D9EF56; }
.tcd-legend-note { color: var(--text-caption); font-style: italic; }
.tcd-legend-src { color: var(--text-primary); text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 2px; font-size: 0.85em; }

@media (max-width: 600px) {
    .tcd-globe { height: 60vh; min-height: 340px; }
    .tcd-counters { left: 8px; bottom: 30px; gap: 0.8rem; padding: 0.4rem 0.6rem; }
    .tcd-counter-v { font-size: 1.1rem; }
    .tcd-detail { right: 8px; top: 8px; width: auto; left: 8px; }
}

/* Country-label overlay (#3) */
.tcd-label-layer { position: absolute; inset: 0; pointer-events: none; z-index: 2; overflow: hidden; }
.tcd-label {
    position: absolute; top: 0; left: 0; white-space: nowrap; pointer-events: none;
    font-family: 'DM Sans', sans-serif; font-size: 0.74rem; font-weight: 600; letter-spacing: 0.01em;
    color: #F6F3EA; text-shadow: 0 1px 3px rgba(0,0,0,0.95), 0 0 2px rgba(0,0,0,0.9);
    transform: translate(-9999px, -9999px); margin-top: -0.5em; margin-left: 5px;
}
.tcd-label-dest { color: #F6F3EA; }
.tcd-label-origin { color: var(--tcd-text, #F6F3EA); opacity: 0.85; }
/* Dodged-circle labels — displaced into open water with a leader line back to the centroid. */
.tcd-dodge-label {
    display: inline-block; width: max-content;      /* shrink-wrap: see MapLibre marker gotcha */
    pointer-events: none; font-family: 'Inter', sans-serif; font-size: 11px;
    color: #EDE8DA; opacity: 0.9; text-shadow: 0 1px 2px rgba(0,0,0,0.8);
    transform: translateY(2px);
}
.tcd-dodge-label[hidden] { display: none; }
/* Ocean labels — curved diagonal per-letter text (Pacific + Atlantic) */
.tcd-ocean { position: absolute; inset: 0; pointer-events: none; }
.tcd-ocean-ch {
    position: absolute; left: 0; top: 0; white-space: pre;
    /* Heavier weight (400→500) + brighter water-blue (#6f8aa6→#8badd0) + higher opacity for
       readability. Size 0.62rem — dropped ~1pt from 0.68 so the all-caps ocean labels read with more
       air (esp. PACIFIC OCEAN, which sits in the compressed western basin). */
    font-family: 'DM Sans', sans-serif; font-style: italic; font-weight: 500;
    font-size: 0.62rem; letter-spacing: 0.01em;
    color: var(--tcd-water-label, #8badd0); opacity: 0.9;
    text-shadow: 0 1px 2px rgba(0,0,0,0.85);
    transform: translate(-9999px, -9999px); will-change: transform;
}

.tcd-section-h { font-family: 'Outfit', sans-serif; font-size: 1.1rem; margin: 1.5rem 0 0.6rem; }
/* Section headings that carry an inline "Embed" button: the button sits RIGHT NEXT TO the title
   text (not pushed to the container edge). flex with the title as the first item; the gap supplies
   the padding, and we cancel .embed-viz-btn's margin-left:auto so it hugs the title. Wraps on mobile. */
.tcd-section-h--embed { display: flex; align-items: center; justify-content: flex-start; gap: 0.7rem; flex-wrap: wrap; }
.tcd-section-h--embed .embed-viz-btn { margin-left: 0; }

/* Pinned outlet sub-sections (Third Country Deportation Watch, Ice Flight Monitor) sit above the
   general Coverage feed — see js/third-country-articles.js. Each is its own .article-feed, so
   spacing/border pairs it visually with the general feed below without merging the two: a reader
   scanning past should read "this outlet's own reporting," then "everything else," not one list. */
.tcd-pinned-outlet { margin: 0 0 1.6rem; padding-bottom: 1.4rem; border-bottom: 1px solid var(--border); }
/* 2026-09-19 feedback (round 2, item 3): a small grey box around the pinned outlet's name, so it
   reads as a labeled sub-section header rather than a plain heading indistinguishable from the
   cards below it. */
.tcd-pinned-outlet-h { display: inline-block; font-family: 'Outfit', sans-serif; font-size: 1rem;
  margin: 0 0 0.7rem; padding: 0.2rem 0.65rem; background: var(--bg-tertiary);
  border: 1px solid var(--border); border-radius: 6px; }

/* "Also cited" — the coverage links whose publishers block an automated request, so the feed
   has a URL and no headline. Set BELOW the card feed and typographically quieter than it: these
   are citations, not cards, and dressing them up as cards would mean inventing the headline the
   publisher would not give us. See js/third-country-articles.js. */
.tcd-articles-also { margin: 1.6rem 0 0; padding-top: 1.1rem; border-top: 1px solid var(--border); }
.tcd-articles-also .tcd-also-h { font-family: 'Outfit', sans-serif; font-size: 0.95rem; margin: 0 0 0.35rem; }
.tcd-articles-also .tcd-also-note { font-size: 0.85rem; color: var(--text-secondary); margin: 0 0 0.8rem; max-width: 46rem; }
.tcd-also-list { list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); gap: 0.4rem 1.6rem; }
.tcd-also-list li { font-size: 0.88rem; line-height: 1.45; }
/* Site-wide dark-mode link rule: readable ink, accent underline (see CLAUDE.md). */
.tcd-also-list a { color: var(--text-primary); text-decoration: underline;
    text-decoration-color: var(--accent); text-underline-offset: 2px; }
.tcd-also-list a:hover, .tcd-also-list a:focus-visible { text-decoration-color: var(--text-primary); }

/* Detention-centers panel (#6) */
.tcd-center-panel { position: absolute; left: 12px; top: 12px; right: 12px; max-width: 320px; z-index: 5;
    background: var(--tcd-surface, #222021); color: var(--tcd-text, #F6F3EA); border: 1px solid var(--tcd-border, #3a3738);
    border-radius: 8px; padding: 12px 14px; font-family: 'DM Sans', sans-serif; max-height: 70%; overflow: auto; }
.tcd-center-close { float: right; background: none; border: none; color: inherit; font-size: 18px; cursor: pointer; }
.tcd-center-name { font-family: 'Outfit', sans-serif; margin: 0 0 0.3rem; font-size: 1rem; }
.tcd-center-count { margin: 0.1rem 0; font-size: 0.78rem; color: var(--tcd-textDim, #a09d94); }
.tcd-center-cond { margin: 0.5rem 0 0; font-size: 0.82rem; line-height: 1.45; }
.tcd-toggle.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ============================================================
   Volume map UI: region chips, side rail (the flights view + its toggle/picker were removed).
   Data accent = #D9EF56 (corridor lime); UI accent = var(--accent).
   ============================================================ */

/* The map card is the positioning context for the rail (a sibling of #tcd-globe). */
.tcd-container { position: relative; }
#tcd-volume-rail[hidden], #tcd-region-chips[hidden] { display: none !important; }
/* #tcd-mode-toggle is retained as an (empty) container; zero footprint. */
.tcd-mode-toggle { display: inline-flex; }

/* --- Region roll-up chips (lime = tied to the data bubbles) --- */
.tcd-region-chips { display: inline-flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }
.tcd-region-chip {
    font-family: 'DM Sans', sans-serif; font-size: 0.72rem; color: var(--text-secondary);
    background: transparent; border: 1px solid var(--border); border-radius: 999px;
    padding: 0.22rem 0.6rem; min-height: 28px; cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.tcd-region-chip:hover { color: var(--text-primary); border-color: #D9EF56; }
.tcd-region-chip.active {
    color: #D9EF56; border-color: #D9EF56;
    background: color-mix(in srgb, #D9EF56 14%, transparent);
}

/* --- Ranked side rail (glassy overlay, bottom-right of the globe) --- */
.tcd-volume-rail {
    position: absolute; right: 12px; top: 12px; z-index: 6;
    width: min(300px, 42%); max-height: calc(100% - 24px); overflow-y: auto;
    background: color-mix(in srgb, var(--tcd-surface, #222021) 86%, transparent);
    -webkit-backdrop-filter: blur(10px) saturate(1.1); backdrop-filter: blur(10px) saturate(1.1);
    border: 1px solid var(--tcd-border, #3a3738); border-radius: 10px;
    padding: 12px 13px 11px; color: var(--tcd-text, #F6F3EA);
    box-shadow: 0 8px 28px rgba(0,0,0,0.4);
    scrollbar-width: thin; scrollbar-color: var(--tcd-border, #3a3738) transparent;
}
.tcd-volume-rail::-webkit-scrollbar { width: 7px; }
.tcd-volume-rail::-webkit-scrollbar-thumb { background: var(--tcd-border, #3a3738); border-radius: 7px; }
.tcd-volume-rail-title {
    font-family: 'Outfit', 'Century Gothic', sans-serif; font-size: 0.7rem;
    text-transform: uppercase; letter-spacing: 0.11em; color: var(--tcd-textDim, #a09d94);
    margin: 0 0 0.1rem;
}
.tcd-volume-rail-title::after {
    content: 'Line thickness = people sent · tap a row to fly there';
    display: block; margin-top: 3px; font-family: 'DM Sans', sans-serif;
    font-size: 0.62rem; letter-spacing: 0; text-transform: none;
    color: var(--tcd-textDim, #a09d94); opacity: 0.8; font-style: italic;
}
.tcd-volume-rail-list { list-style: none; margin: 0.55rem 0 0; padding: 0; }
.tcd-volume-row { margin: 0; }
.tcd-volume-row-dim { opacity: 0.3; }
.tcd-volume-row-btn {
    display: grid; grid-template-columns: minmax(0, 5.6rem) 1fr auto; align-items: center; gap: 0.5rem;
    width: 100%; background: transparent; border: none; cursor: pointer;
    padding: 0.28rem 0.3rem; border-radius: 6px; color: inherit; text-align: left;
    transition: background 0.14s ease;
}
.tcd-volume-row-btn:hover { background: color-mix(in srgb, #D9EF56 9%, transparent); }
.tcd-volume-row-name {
    font-family: 'DM Sans', sans-serif; font-size: 0.78rem; color: var(--tcd-text, #F6F3EA);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tcd-volume-row-btn:hover .tcd-volume-row-name { color: #D9EF56; }
.tcd-volume-row-barwrap {
    height: 6px; border-radius: 999px; overflow: hidden;
    background: color-mix(in srgb, var(--tcd-text, #F6F3EA) 9%, transparent);
}
.tcd-volume-row-bar { display: block; height: 100%; min-width: 2px; border-radius: 999px; background: #D9EF56; }
.tcd-volume-row-count {
    font-family: 'DM Sans', sans-serif; font-variant-numeric: tabular-nums;
    font-size: 0.74rem; color: var(--tcd-textDim, #a09d94); min-width: 2.6rem; text-align: right;
}

/* Mexico / land-border callout — amber, prominent ABOVE the flown ranking (by-bus returns are an
   order of magnitude larger than any flown total, so they get their own highlighted box). */
.tcd-volume-landborder {
    display: block; margin: 0 0 0.85rem; padding: 0.6rem 0.7rem;
    border: 1px solid color-mix(in srgb, #E8A23D 45%, transparent); border-left: 3px solid #E8A23D;
    border-radius: 8px; background: color-mix(in srgb, #E8A23D 11%, transparent);
}
.tcd-volume-landborder-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem;
}
.tcd-volume-landborder-name {
    font-family: 'Outfit', sans-serif; font-size: 0.82rem; color: #E8A23D; font-weight: 600;
}
.tcd-volume-landborder-count {
    font-family: 'Outfit', 'Century Gothic', sans-serif; font-variant-numeric: tabular-nums;
    font-size: 1.05rem; font-weight: 700; color: #E8A23D; line-height: 1;
}
.tcd-volume-landborder-detail {
    display: block; margin-top: 4px; font-family: 'DM Sans', sans-serif;
    font-size: 0.7rem; line-height: 1.35; color: var(--tcd-text, #F6F3EA); opacity: 0.85;
}

/* Hover tooltip over a bubble */
.tcd-volume-tooltip {
    position: absolute; z-index: 10; pointer-events: none; transform: translate(-50%, calc(-100% - 12px));
    background: var(--tcd-surface, #222021); border: 1px solid var(--tcd-border, #3a3738);
    border-radius: 7px; padding: 5px 9px; box-shadow: 0 6px 18px rgba(0,0,0,0.45);
    font-family: 'DM Sans', sans-serif; white-space: nowrap;
}
.tcd-volume-tooltip[hidden] { display: none; }
.tcd-volume-tip-country { display: block; font-size: 0.78rem; color: var(--tcd-text, #F6F3EA); font-weight: 600; }
.tcd-volume-tip-count { display: block; font-size: 0.7rem; color: #D9EF56; font-variant-numeric: tabular-nums; }

/* --- People on the map (accent-red = a human, vs the lime data corridors). One per flown country. --- */
/* MUST NOT set position here: MapLibre positions the marker via `.maplibregl-marker`
   (position:absolute; top:0; left:0) + a transform. Overriding it (e.g. position:relative) drops the
   marker back into document flow, so pins drift by the accumulated size of the others. The absolute
   marker is itself the containing block for the (absolute) hover label. Fixed 30×30 so anchor:'center'
   lands the pin on the country. */
.tcd-person-marker {
    display: block; width: 30px; height: 30px; background: none; border: none;
    padding: 0; cursor: pointer; font-family: 'DM Sans', sans-serif;
}
.tcd-person-marker:hover, .tcd-person-marker:focus-visible { z-index: 30; }
/* display:block is REQUIRED — the pin is a <span> (inline by default, which ignores width/height);
   it only sized correctly when the old marker was a flex parent that blockified it. */
.tcd-person-pin { display: block; position: relative; width: 30px; height: 30px; }
.tcd-person-pin-mono {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    border-radius: 50%; background: var(--accent); color: #fff; font-weight: 700; font-size: 0.66rem;
    border: 2px solid var(--tcd-bg, #14110f); box-shadow: 0 2px 10px rgba(0,0,0,0.55); z-index: 2;
}
.tcd-person-pin-pulse {
    position: absolute; inset: 0; border-radius: 50%;
    border: 2px solid var(--accent); z-index: 1; pointer-events: none;
    animation: tcd-person-pulse 2.2s ease-out infinite;
}
@keyframes tcd-person-pulse {
    0%   { transform: scale(1); opacity: 0.8; }
    100% { transform: scale(2.6); opacity: 0; }
}
/* Label floats out of the pin ONLY on hover/focus, so the map isn't cluttered with 10 labels and
   the clickable target is unambiguously the pin (item: map too busy / hard to click). */
.tcd-person-label {
    position: absolute; left: calc(100% + 5px); top: 50%; transform: translateY(-50%) translateX(-6px);
    display: flex; flex-direction: column; gap: 0; line-height: 1.15; white-space: nowrap;
    background: color-mix(in srgb, var(--tcd-surface, #222021) 94%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--tcd-border, #3a3738));
    border-radius: 8px; padding: 3px 9px; box-shadow: 0 2px 12px rgba(0,0,0,0.55);
    opacity: 0; pointer-events: none; transition: opacity 0.14s ease, transform 0.14s ease;
}
.tcd-person-marker:hover .tcd-person-label,
.tcd-person-marker:focus .tcd-person-label,
.tcd-person-marker:focus-visible .tcd-person-label { opacity: 1; transform: translateY(-50%) translateX(0); border-color: var(--accent); }
.tcd-person-label-name { font-size: 0.74rem; font-weight: 700; color: var(--tcd-text, #F6F3EA); }
.tcd-person-label-cue { font-size: 0.58rem; font-weight: 600; letter-spacing: 0.02em; color: var(--accent); text-transform: uppercase; }
@media (prefers-reduced-motion: reduce) { .tcd-person-label { transition: none; } }
@media (prefers-reduced-motion: reduce) { .tcd-person-pin-pulse { animation: none; opacity: 0; } }

/* Story pop-up (anchored on the map via maplibregl.Popup) */
.tcd-person-popup .maplibregl-popup-content {
    background: var(--tcd-surface, #222021); color: var(--tcd-text, #F6F3EA);
    border: 1px solid var(--tcd-border, #3a3738); border-radius: 10px;
    padding: 12px 13px; box-shadow: 0 10px 30px rgba(0,0,0,0.5);
}
.tcd-person-popup .maplibregl-popup-tip { border-top-color: var(--tcd-surface, #222021); border-bottom-color: var(--tcd-surface, #222021); }
.tcd-person-popup .maplibregl-popup-close-button { color: var(--tcd-textDim, #a09d94); font-size: 1.1rem; padding: 2px 7px; }
.tcd-person-card-kicker {
    display: block; font-family: 'Outfit', sans-serif; font-size: 0.6rem; text-transform: uppercase;
    letter-spacing: 0.13em; color: var(--accent); font-weight: 700;
}
.tcd-person-card-name { margin: 3px 0 2px; font-family: 'Outfit', sans-serif; font-size: 1.05rem; font-weight: 700; color: var(--tcd-text, #F6F3EA); }
.tcd-person-card-meta { margin: 0; font-family: 'DM Sans', sans-serif; font-size: 0.74rem; line-height: 1.4; color: var(--tcd-textDim, #a09d94); }
.tcd-person-card-flag {
    display: inline-block; margin-top: 6px; font-family: 'DM Sans', sans-serif; font-size: 0.66rem;
    color: #D9EF56; border: 1px solid color-mix(in srgb, #D9EF56 40%, transparent); border-radius: 999px; padding: 1px 7px;
}
.tcd-person-card-cta {
    display: block; margin-top: 9px; width: 100%; cursor: pointer;
    background: var(--accent); color: #fff; border: none; border-radius: 7px; padding: 7px 10px;
    font-family: 'Outfit', sans-serif; font-size: 0.74rem; font-weight: 600;
    transition: filter 0.15s ease;
}
.tcd-person-card-cta:hover { filter: brightness(1.1); }
.tcd-person-card-note { display: block; margin-top: 6px; font-family: 'DM Sans', sans-serif; font-size: 0.64rem; color: var(--tcd-textDim, #a09d94); font-style: italic; }
/* Anonymized subject → white head-and-shoulders silhouette on accent (no initials, no identity). */
.tcd-person-pin-sil { position: absolute; inset: 0; border-radius: 50%; background: var(--accent); border: 2px solid var(--tcd-bg, #14110f); box-shadow: 0 2px 10px rgba(0,0,0,0.55); z-index: 2; overflow: hidden; }
.tcd-person-pin-sil::before { content: ''; position: absolute; left: 50%; top: 6px; width: 8px; height: 8px; border-radius: 50%; background: #fff; transform: translateX(-50%); }
.tcd-person-pin-sil::after { content: ''; position: absolute; left: 50%; bottom: 3px; width: 15px; height: 9px; border-radius: 10px 10px 0 0; background: #fff; transform: translateX(-50%); }
/* Documented-removals anchor (no consent-cleared person) → lime dot = data, not a person. */
.tcd-person-pin--count .tcd-person-pin-dot { position: absolute; inset: 5px; border-radius: 50%; background: color-mix(in srgb, #D9EF56 85%, #14110f); border: 2px solid var(--tcd-bg, #14110f); box-shadow: 0 2px 10px rgba(0,0,0,0.55); z-index: 2; }
.tcd-person-pin--count .tcd-person-pin-pulse { border-color: #D9EF56; }
.tcd-person-card-kicker--data { color: #D9EF56; }
.tcd-person-card-cta--data { background: color-mix(in srgb, #D9EF56 88%, #14110f); color: #14110f; }

/* --- Asylum explainer (item 8): the legal stakes, above the negotiation pipeline --- */
.tcd-asylum-explainer {
    margin: 1.75rem 0 1.25rem; padding: 1.1rem 1.35rem;
    border-left: 3px solid var(--accent); border-radius: 0 10px 10px 0;
    background: color-mix(in srgb, var(--text-primary) 5%, transparent);
}
.tcd-asylum-explainer-title { font-family: 'Playfair Display', serif; font-size: 1.2rem; margin: 0 0 0.55rem; color: var(--text-primary); }
.tcd-asylum-explainer p { margin: 0 0 0.6rem; color: var(--text-secondary); line-height: 1.6; }
.tcd-asylum-explainer p:last-child { margin-bottom: 0; }
.tcd-asylum-explainer strong { color: var(--text-primary); }
/* Headline figures inside the explainer (item: explainer had no numbers). */
.tcd-asylum-stats { display: flex; flex-wrap: wrap; gap: 1.5rem 2.5rem; margin: 1rem 0 0.6rem; padding: 0; }
.tcd-asylum-stat { margin: 0; }
.tcd-asylum-stat dt { font-family: 'Playfair Display', serif; font-size: 1.9rem; line-height: 1; color: var(--accent); font-weight: 700; }
.tcd-asylum-stat dd { margin: 0.3rem 0 0; max-width: 16rem; font-size: 0.86rem; line-height: 1.35; color: var(--text-secondary); }
.tcd-asylum-stats-src { margin: 0.2rem 0 0 !important; font-size: 0.78rem !important; color: var(--text-tertiary, var(--text-secondary)) !important; opacity: 0.85; }
/* Per-country asylum-tracker figures in the country file. */
.tcd-cf-asylum-nums { display: flex; flex-wrap: wrap; gap: 0.4rem 1.4rem; margin: 0.6rem 0 0; }
.tcd-cf-asylum-num { margin: 0; }
.tcd-cf-asylum-num dt { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--tcd-textDim, #a09d94); }
.tcd-cf-asylum-num dd { margin: 1px 0 0; font-family: 'DM Sans', sans-serif; font-variant-numeric: tabular-nums; font-size: 0.95rem; font-weight: 700; color: var(--tcd-text, #F6F3EA); }

/* ── Forbidden Stories package index (spec 2026-09-08) ──────────────────────
   Paints the MAP's ground (--tcd-surface), where the Coverage feed below paints the
   PAGE's. That one difference is what stops two story surfaces reading as one feed. */
.tcd-package {
  margin: 1.25rem 0 1.75rem; padding: 1.4rem 1.5rem;
  background: var(--tcd-surface, #222021);
  border: 1px solid var(--tcd-border, #3a3738); border-radius: 10px;
}
.tcd-pkg-heading { margin-top: 0; }
/* FS brand red appears exactly twice on this tab: here and on the hub link. NEVER as a
   UI accent -- red on this site is --danger, the colour of a death in custody. */
.tcd-pkg-fs { color: #E4002B; }
/* The consortium's own cover art precedes the heading it introduces. 2026-09-18 feedback:
   halved from the original full-bleed treatment (which spanned the card edge to edge) down to
   half the card's width -- a credit thumbnail ahead of the heading, not a masthead competing
   with it. Left-aligned to match the heading and statement text below it. */
.tcd-pkg-banner-link {
  display: block; margin: 0 0 1.2rem; border-radius: 6px; overflow: hidden;
  max-width: 50%;
}
.tcd-pkg-banner { display: block; width: 100%; height: auto; }
.tcd-pkg-statement {
  font-family: 'Source Serif 4', Georgia, serif; color: var(--text-secondary);
  font-size: 0.95rem; line-height: 1.6; max-width: 62ch; margin: 0 0 1.2rem;
}

.tcd-pkg-list { display: flex; flex-direction: column; gap: 0.9rem; }
/* A class that sets `display` OUTRANKS the UA's `[hidden] { display: none }` — one class
   selector against one attribute selector goes to whichever comes later, and the UA sheet is
   always first. Without this the collapsed rows rendered in full and the disclosure did
   nothing; the browser tests caught it, reporting 11 visible rows where 6 were expected. */
.tcd-pkg-list[hidden] { display: none; }
.tcd-pkg-row {
  display: grid; grid-template-columns: 8.5rem 5.5rem 1fr; gap: 0 1rem; align-items: start;
}
.tcd-pkg-row.no-photo { grid-template-columns: 8.5rem 1fr; }
.tcd-pkg-row.no-photo .tcd-pkg-body { grid-column: 2; }

/* The gutter: the map's own place-label typography (Task 3 tokens), so the reader
   recognises the name they just saw on the map rather than a lookalike.
   NOTE the var() fallback on color: #tcd-package sits as a DOM SIBLING of
   #tcd-container/.tcd-answer-map (index.html), not a descendant, so --tcd-am-dest
   (declared on .tcd-answer-map, line ~1606) does not cascade to it in dark theme --
   the same gap already documented and fixed this way for the embed-button focus
   ring at line ~2683. Without the literal #7d94f5 fallback, destination gutters
   render in inherited body text (#F6F3EA), not indigo -- confirmed by computed
   style during Task 5 verification. */
.tcd-pkg-gutter {
  font-family: var(--tcd-place-font);
  font-size: var(--tcd-place-size-ui); font-weight: var(--tcd-place-weight);
  letter-spacing: var(--tcd-place-tracking); text-transform: uppercase;
  color: var(--tcd-am-dest, #7d94f5); line-height: 1.5; padding-top: 0.1rem;
}
/* The one asymmetry that carries the argument: the origin is amber, every destination
   indigo -- the same distinction .tcd-am-usmark makes on the map, and scoped just as
   narrowly. Same sibling-scope gap as --tcd-am-dest above: --tcd-am-home-ink is declared
   on .tcd-answer-map (line 1693: #f3d18c), and #tcd-package is that element's DOM sibling,
   not its descendant, so the token cannot resolve here in dark theme either. The fallback
   below must equal line 1693's value, not merely look close -- the gutter's whole point is
   naming the SAME object the map's "UNITED STATES" label already painted, so a near-miss
   amber reads as an error rather than a deliberate distinction (controller ruling R7). */
.tcd-pkg-row.is-origin .tcd-pkg-gutter { color: var(--tcd-am-home-ink, #f3d18c); }
/* Task 7: the gutter is lit while it drives the map above, via --text-primary/--accent —
   both declared on the page root, so (unlike --tcd-am-* above) no sibling-scope gap here. */
.tcd-pkg-gutter.is-lit { color: var(--text-primary); }
/* Fix round 1 (2026-09-08, ruling): the rule above is (0,2,0) and loses to the origin-row
   amber rule at :485 (0,3,0) regardless of source order, so the origin row's gutter (the
   UNITED STATES row) never actually lit. Re-declare under the same .is-origin qualifier at
   (0,4,0) so lit wins for that row too. Dark theme only; the light-theme mirror of both
   this rule and the base one above lives at ~line 2875, because those two are additionally
   ID-scoped (#third-country.tcd-theme-light) and this dark-theme pair can never reach them. */
.tcd-pkg-row.is-origin .tcd-pkg-gutter.is-lit { color: var(--text-primary); }
.tcd-pkg-gutter:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.tcd-pkg-photo { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 4px; }
.tcd-pkg-title {
  font-family: 'Outfit', sans-serif; font-size: 1rem; line-height: 1.35;
  color: var(--text-primary); text-decoration: none; display: block;
}
a.tcd-pkg-title:hover, a.tcd-pkg-title:focus-visible {
  text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 2px;
}
.tcd-pkg-credit {
  font-family: 'DM Sans', sans-serif; font-size: 0.78rem;
  color: var(--tcd-textDim, #a09d94); margin-top: 0.2rem;
}
.tcd-pkg-sep { margin: 0 0.4rem; }

/* The group break. No heading, no label -- the rule alone says the country every flight
   departed from is not the same kind of thing as the countries they arrived in. */
.tcd-pkg-break {
  height: 1px; background: var(--tcd-border, #3a3738); margin: 0.3rem 0;
}

.tcd-pkg-wall { margin: 1.4rem 0 0; display: flex; flex-wrap: wrap; gap: 0.4rem 1.1rem; align-items: baseline; }
.tcd-pkg-wall-label {
  font-family: 'DM Sans', sans-serif; font-size: 0.75rem; color: var(--tcd-textDim, #a09d94);
}
.tcd-pkg-partner {
  font-family: var(--tcd-place-font); font-size: var(--tcd-place-size-ui);
  font-weight: var(--tcd-place-weight); letter-spacing: var(--tcd-place-tracking);
  text-transform: uppercase; color: var(--text-secondary);
}
/* The disclosure that opens the rest of the package (2026-09-09). A quiet control, not a
   call to action: the six rows above it are the index, and this is the way to the remainder.
   Sized past 24px for touch; the focus ring is the site's. */
.tcd-pkg-more { display: inline-flex; align-items: center; gap: 0.4rem;
    margin: 0.9rem 0 0; padding: 0.45rem 0.85rem; min-height: 32px;
    font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.82rem; letter-spacing: 0.01em;
    color: var(--text-primary); background: transparent;
    border: 1px solid var(--border); border-radius: 999px; cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease; }
.tcd-pkg-more:hover { border-color: var(--text-secondary); background: color-mix(in srgb, var(--text-primary) 6%, transparent); }
.tcd-pkg-more:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tcd-pkg-more::after { content: '\2304'; font-size: 0.9em; line-height: 1; transform: translateY(-0.15em); }
.tcd-pkg-more[aria-expanded="true"]::after { content: '\2303'; transform: translateY(0.15em); }
/* The revealed rows share .tcd-pkg-list, so they inherit the same column grid and the gutter
   stays in line with the rows above. The rule above the first revealed row marks the seam. */
.tcd-pkg-rest { margin-top: 0.9rem; padding-top: 0.9rem; border-top: 1px solid var(--border); }
.tcd-pkg-hub { margin: 1.2rem 0 0; font-size: 0.88rem; color: var(--text-secondary); }
.tcd-pkg-hub-link {
  color: #E4002B; text-decoration: underline; text-underline-offset: 2px;
}

@media (max-width: 640px) {
  .tcd-package { padding: 1.1rem 1rem; }
  /* Gutter above the row rather than beside it -- 8.5rem of label plus a photo plus a
     headline does not fit 375px without the title column collapsing to a word per line. */
  .tcd-pkg-row, .tcd-pkg-row.no-photo { grid-template-columns: 1fr; gap: 0.35rem; }
  .tcd-pkg-row.no-photo .tcd-pkg-body { grid-column: 1; }
  .tcd-pkg-photo { max-width: 9rem; }
}

/* --- Amber land-border chip centered over Mexico (by-bus returns, shown separately) --- */
.tcd-landborder-marker {
    display: flex; flex-direction: column; align-items: center; gap: 1px; cursor: pointer;
    padding: 5px 11px; font-family: 'DM Sans', sans-serif; text-align: center;
    background: color-mix(in srgb, #E8A23D 16%, var(--tcd-surface, #222021));
    border: 1px solid color-mix(in srgb, #E8A23D 55%, transparent); border-radius: 9px;
    box-shadow: 0 3px 12px rgba(0,0,0,0.45);
}
.tcd-landborder-marker:hover { background: color-mix(in srgb, #E8A23D 24%, var(--tcd-surface, #222021)); }
.tcd-landborder-marker-country {
    font-family: 'Outfit', sans-serif; font-size: 0.82rem; font-weight: 700; color: #F2C277; line-height: 1.1;
}
.tcd-landborder-marker-count {
    font-size: 0.62rem; color: #E8A23D; white-space: nowrap; font-variant-numeric: tabular-nums;
}

/* Mobile: rail stacks below the globe instead of overlaying it */
@media (max-width: 760px) {
    .tcd-volume-rail {
        position: static; width: auto; max-height: none; margin: 0.6rem 0.75rem 0.75rem;
        -webkit-backdrop-filter: none; backdrop-filter: none;
        background: var(--tcd-surface, #222021); box-shadow: none;
    }
}

/* ============================================================
   Phase 3 — time scrubber (Volume mode): escalation curve + playhead
   ============================================================ */
.tcd-scrubber {
    padding: 0.7rem 0.85rem 0.85rem; border-top: 1px solid var(--border);
    background: color-mix(in srgb, var(--tcd-surface, #222021) 38%, transparent);
}
.tcd-scrubber[hidden] { display: none !important; }

/* SVG "curve of escalation". preserveAspectRatio:none stretches the viewBox to the
   container width, so all strokes use non-scaling-stroke to stay crisp + undistorted. */
.tcd-scrubber-svg { display: block; width: 100%; height: 74px; }
.tcd-scrubber-baseline { stroke: var(--tcd-border, #3a3738); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tcd-scrubber-area { fill: color-mix(in srgb, #D9EF56 16%, transparent); }
.tcd-scrubber-line { stroke: #D9EF56; stroke-width: 1.5; fill: none; vector-effect: non-scaling-stroke; }
.tcd-scrubber-sign { stroke: #E8A23D; stroke-width: 1; stroke-dasharray: 2 2; opacity: 0.85; vector-effect: non-scaling-stroke; }
.tcd-scrubber-estimated { fill: color-mix(in srgb, var(--tcd-text, #F6F3EA) 5%, transparent); }
.tcd-scrubber-cursor { stroke: var(--accent); stroke-width: 1.5; vector-effect: non-scaling-stroke; }

.tcd-scrubber-axis {
    display: flex; justify-content: space-between; margin-top: 2px;
    font-family: 'DM Sans', sans-serif; font-size: 0.62rem; color: var(--tcd-textDim, #a09d94);
}

.tcd-scrubber-controls { display: flex; align-items: center; gap: 0.7rem; margin-top: 0.55rem; }

/* Play / pause — circular accent button; triangle/bars drawn via ::before */
.tcd-scrubber-play {
    flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%;
    border: 1px solid var(--accent); background: color-mix(in srgb, var(--accent) 16%, transparent);
    color: var(--accent); cursor: pointer; display: flex; align-items: center; justify-content: center;
    transition: background 0.15s ease;
}
.tcd-scrubber-play:hover { background: var(--accent); color: #fff; }
.tcd-scrubber-play::before {
    content: ''; display: block; width: 0; height: 0; margin-left: 2px;
    border-left: 9px solid currentColor; border-top: 6px solid transparent; border-bottom: 6px solid transparent;
}
.tcd-scrubber-play.playing::before {
    width: 9px; height: 11px; margin-left: 0; border: none;
    border-left: 3px solid currentColor; border-right: 3px solid currentColor;
}
.tcd-scrubber-play-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.tcd-scrubber-track {
    position: relative; flex: 1 1 auto; height: 6px; border-radius: 999px; cursor: pointer;
    background: color-mix(in srgb, var(--tcd-text, #F6F3EA) 10%, transparent);
}
.tcd-scrubber-playhead {
    position: absolute; top: 50%; left: 100%; transform: translate(-50%, -50%); padding: 0;
    width: 16px; height: 16px; border-radius: 50%; background: var(--accent);
    border: 2px solid var(--bg-card); box-shadow: 0 1px 4px rgba(0,0,0,0.45); cursor: grab;
}
.tcd-scrubber-playhead:active { cursor: grabbing; }
.tcd-scrubber-playhead:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.tcd-scrubber-readout {
    flex: 0 0 auto; min-width: 9.5rem; text-align: right;
    font-family: 'DM Sans', sans-serif; font-size: 0.74rem; color: var(--tcd-text, #F6F3EA);
    font-variant-numeric: tabular-nums;
}
@media (max-width: 760px) {
    .tcd-scrubber-svg { height: 58px; }
    .tcd-scrubber-readout { min-width: 0; font-size: 0.68rem; }
}

/* ============================================================
   Phase 4 — agreements layer: Sankey, country file, directory table
   ============================================================ */

/* --- Sankey: US -> destination region (agreement-type column removed) --- */
.tcd-sankey { padding: 0.4rem 0 0.2rem; position: relative; }
.tcd-sankey-svg { display: block; width: 100%; height: auto; }
.tcd-sankey-link { fill: var(--tcd-textDim, #a09d94); opacity: 0.18; transition: opacity 0.15s ease, fill 0.15s ease; }
.tcd-sankey-link:hover, .tcd-sankey-link.is-hot { opacity: 0.5; fill: #D9EF56; }
.tcd-sankey-rect { rx: 2; }
.tcd-sankey-rect-col0 { fill: var(--accent); }
/* col1 = destination region (US → region); lime matches the map corridors. */
.tcd-sankey-rect-col1 { fill: #D9EF56; }
.tcd-sankey-rect-col2 { fill: #D9EF56; } /* legacy (agreement-type column removed) */
.tcd-sankey-node-interactive { cursor: pointer; }
.tcd-sankey-node-interactive:hover .tcd-sankey-rect { filter: brightness(1.2); }
.tcd-sankey-label { font-family: 'DM Sans', sans-serif; font-size: 11px; fill: var(--tcd-text, #F6F3EA); }
.tcd-sankey-label-region { font-family: 'DM Sans', sans-serif; font-size: 11px; fill: var(--tcd-text, #F6F3EA); }
.tcd-sankey-tooltip {
    position: absolute; z-index: 10; pointer-events: none; transform: translate(-50%, calc(-100% - 10px));
    background: var(--tcd-surface, #222021); border: 1px solid var(--tcd-border, #3a3738); border-radius: 7px;
    padding: 5px 9px; box-shadow: 0 6px 18px rgba(0,0,0,0.45); white-space: nowrap;
    font-family: 'DM Sans', sans-serif; font-size: 0.74rem; color: var(--tcd-text, #F6F3EA);
}
.tcd-sankey-tooltip[hidden] { display: none; }

/* --- Country file: right slide-in panel over the globe --- */
.tcd-country-file {
    position: absolute; top: 12px; right: 12px; bottom: 12px; z-index: 8;
    width: min(360px, 48%); overflow-y: auto;
    background: color-mix(in srgb, var(--tcd-surface, #222021) 92%, transparent);
    -webkit-backdrop-filter: blur(12px) saturate(1.1); backdrop-filter: blur(12px) saturate(1.1);
    border: 1px solid var(--tcd-border, #3a3738); border-radius: 12px;
    box-shadow: -10px 0 34px rgba(0,0,0,0.5); padding: 14px 16px 16px; color: var(--tcd-text, #F6F3EA);
    animation: tcd-cf-in 0.18s ease;
}
@keyframes tcd-cf-in { from { transform: translateX(14px); opacity: 0; } to { transform: none; opacity: 1; } }
.tcd-country-file[hidden] { display: none; }
.tcd-cf-close {
    position: absolute; top: 10px; right: 12px; background: none; border: none; color: var(--tcd-textDim, #a09d94);
    font-size: 20px; line-height: 1; cursor: pointer; padding: 0;
}
.tcd-cf-close:hover { color: var(--tcd-text, #F6F3EA); }
.tcd-cf-country { font-family: 'Outfit', sans-serif; font-size: 1.25rem; margin: 0 1.5rem 0.1rem 0; }
.tcd-cf-region { font-family: 'DM Sans', sans-serif; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--tcd-textDim, #a09d94); }
.tcd-cf-headline { font-family: 'Source Serif 4', Georgia, serif; font-size: 0.92rem; color: var(--tcd-text, #F6F3EA); margin: 0.5rem 0 0.7rem; }
.tcd-cf-headline-num { color: #D9EF56; font-weight: 700; }
.tcd-cf-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 0.55rem 0.8rem; margin-bottom: 0.7rem; }
.tcd-cf-fact-label { display: block; font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--tcd-textDim, #a09d94); }
.tcd-cf-fact-value { display: block; font-family: 'DM Sans', sans-serif; font-size: 0.8rem; color: var(--tcd-text, #F6F3EA); margin-top: 1px; }
.tcd-cf-harm { border-left: 3px solid #C75D5D; padding: 0.1rem 0 0.1rem 0.7rem; margin: 0.4rem 0 0.7rem; }
.tcd-cf-harm-label { display: block; font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.05em; color: #C75D5D; margin-bottom: 0.2rem; }
.tcd-cf-harm-text { font-family: 'Source Serif 4', Georgia, serif; font-size: 0.82rem; font-style: italic; line-height: 1.45; color: var(--tcd-text, #F6F3EA); }

/* --- Safety & legality (asylum-system assessment, from asylumSafety) --- */
.tcd-cf-asylum { margin: 0 0 0.8rem; }
.tcd-cf-asylum-title { font-family: 'Outfit', sans-serif; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--tcd-textDim, #a09d94); margin: 0 0 0.4rem; }
.tcd-cf-asylum-banner { font-family: 'DM Sans', sans-serif; font-size: 0.8rem; font-weight: 600; border-radius: 8px; padding: 0.4rem 0.6rem; margin: 0 0 0.55rem; display: flex; align-items: center; gap: 0.45rem; }
.tcd-cf-asylum-banner::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.tcd-cf-asylum-high { color: #E8908F; background: color-mix(in srgb, #C75D5D 14%, transparent); border: 1px solid color-mix(in srgb, #C75D5D 45%, transparent); }
.tcd-cf-asylum-moderate { color: #E3C07A; background: color-mix(in srgb, #D8A657 12%, transparent); border: 1px solid color-mix(in srgb, #D8A657 40%, transparent); }
.tcd-cf-asylum-low { color: #9FC27E; background: color-mix(in srgb, #7BA05B 12%, transparent); border: 1px solid color-mix(in srgb, #7BA05B 38%, transparent); }
.tcd-cf-asylum-facts { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0.4rem 0.8rem; margin: 0 0 0.5rem; }
.tcd-cf-asylum-fact dt { font-size: 0.57rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--tcd-textDim, #a09d94); }
.tcd-cf-asylum-fact dd { margin: 1px 0 0; font-family: 'DM Sans', sans-serif; font-size: 0.78rem; color: var(--tcd-text, #F6F3EA); }
.tcd-cf-asylum-treaties { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0 0 0.45rem; }
.tcd-cf-treaty { display: inline-flex; flex-direction: column; border-radius: 6px; padding: 0.22rem 0.45rem; border: 1px solid var(--tcd-border, #3a3738); }
.tcd-cf-treaty-name { font-size: 0.56rem; color: var(--tcd-textDim, #a09d94); }
.tcd-cf-treaty-status { font-family: 'DM Sans', sans-serif; font-size: 0.72rem; color: var(--tcd-text, #F6F3EA); }
.tcd-cf-treaty-ratified .tcd-cf-treaty-status { color: #9FC27E; }
.tcd-cf-treaty-signed .tcd-cf-treaty-status { color: #E3C07A; }
.tcd-cf-treaty-none { border-color: color-mix(in srgb, #C75D5D 45%, transparent); }
.tcd-cf-treaty-none .tcd-cf-treaty-status { color: #E8908F; }
.tcd-cf-asylum-src { font-size: 0.58rem; color: var(--tcd-textDim, #a09d94); margin: 0; }

/* --- The wider bargain (parallel U.S. dealings, from record.leverage) --- */
.tcd-cf-leverage { margin: 0 0 0.8rem; }
.tcd-cf-leverage-title { font-family: 'Outfit', sans-serif; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--tcd-textDim, #a09d94); margin: 0 0 0.15rem; }
.tcd-cf-leverage-sub { font-family: 'Source Serif 4', Georgia, serif; font-size: 0.73rem; font-style: italic; color: var(--tcd-textDim, #a09d94); margin: 0 0 0.5rem; }
.tcd-cf-leverage-list { list-style: none; margin: 0; padding: 0; }
.tcd-cf-leverage-item { padding: 0.3rem 0 0.3rem 0.7rem; border-left: 2px solid color-mix(in srgb, #D9B45B 45%, transparent); margin-bottom: 0.35rem; }
.tcd-cf-leverage-date { font-family: 'DM Sans', sans-serif; font-size: 0.61rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--tcd-textDim, #a09d94); margin-right: 0.4rem; }
.tcd-cf-leverage-desc { font-family: 'Source Serif 4', Georgia, serif; font-size: 0.8rem; line-height: 1.42; color: var(--tcd-text, #F6F3EA); }
.tcd-cf-leverage-amount { display: inline-block; margin-left: 0.4rem; font-family: 'DM Sans', sans-serif; font-size: 0.7rem; font-weight: 700; color: #D9B45B; }
.tcd-cf-leverage-src { font-size: 0.58rem; color: var(--tcd-textDim, #a09d94); margin: 0.25rem 0 0; }

/* --- First-hand accounts (consent-gated; js/third-country-country-file.js renderTestimonies) --- */
.tcd-cf-testimony { margin-top: 1rem; }
.tcd-cf-testimony-title { font-family: 'Outfit', sans-serif; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--tcd-textDim, #a09d94); margin: 0 0 0.5rem; }
.tcd-cf-testimony-item { margin: 0 0 0.9rem; padding-left: 0.6rem; border-left: 2px solid #EDE8DA; }
.tcd-cf-testimony-quote { margin: 0 0 0.25rem; font-style: italic; }
.tcd-cf-testimony-name { font-size: 0.82em; opacity: 0.8; }
.tcd-cf-testimony-open { margin-top: 0.3rem; }
.tcd-cf-testimony-held { font-style: italic; opacity: 0.75; }

/* --- Sources (per-country agreement source note + deduplicated flight-record links) --- */
.tcd-cf-sources { margin-top: 1rem; }
.tcd-cf-sources-title { font-family: 'Outfit', sans-serif; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--tcd-textDim, #a09d94); margin: 0 0 0.4rem; }
.tcd-cf-sources-note { font-size: 0.85em; opacity: 0.85; }
.tcd-cf-sources-list { margin: 0.4rem 0 0; padding-left: 1.1rem; font-size: 0.85em; }
.tcd-cf-sources-list a { color: var(--text-primary); text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 2px; }

.tcd-cf-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.tcd-cf-action {
    font-family: 'DM Sans', sans-serif; font-size: 0.74rem; padding: 0.32rem 0.7rem; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--tcd-border, #3a3738); background: transparent; color: var(--tcd-text, #F6F3EA);
}
.tcd-cf-show-map { border-color: var(--accent); color: var(--accent); }
.tcd-cf-show-map:hover { background: var(--accent); color: #fff; }
.tcd-cf-open-full[disabled] { opacity: 0.45; cursor: not-allowed; }

/* --- Country-file arrangement-status badge --- */
.tcd-cf-status-badge { display: inline-block; margin: 0.35rem 0 0; font-family: 'DM Sans', sans-serif; font-size: 0.6rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; padding: 0.16rem 0.5rem; border-radius: 999px; border: 1px solid currentColor; }
.tcd-cf-status-confirmed { color: #D9B45B; }
.tcd-cf-status-negotiating { color: #5B8DD9; }
.tcd-cf-status-implied { color: #9B7BD9; }
.tcd-cf-status-declined { color: #C75D5D; }
.tcd-cf-status-unknown { color: #8A8780; }

/* --- Negotiation pipeline panel (#tcd-status) --- */
.tcd-status-intro { font-family: 'Source Serif 4', Georgia, serif; color: var(--text-secondary); font-size: 0.95rem; line-height: 1.5; margin: 0 0 1rem; max-width: 62ch; }
.tcd-status-summary { font-family: 'DM Sans', sans-serif; font-size: 0.95rem; color: var(--text-secondary); margin: 0 0 1.1rem; }
.tcd-status-summary-num { color: var(--text-primary); font-weight: 700; }
.tcd-status-summary-sep { color: var(--border-strong, #4a4748); }
/* Round2 (2026-07-27): the band's border-left previously sat flush with the tab's content
   edge — the same x as every other block on the page, but with no padding/background of
   its own (unlike e.g. .tcd-asylum-explainer) to read as a self-contained card, so the
   colored rule + chips looked like they were touching the edge (most visible in light
   mode, where the accent color pops against the white page). A small left margin insets
   the whole band, the same treatment CLAUDE.md's "Case Tag Spacing" rule uses for other
   border-left tags. */
.tcd-status-band { --st: #8A8780; border-left: 3px solid var(--st); padding: 0.1rem 0 0.3rem 0.85rem; margin: 0 0 0.95rem 0.4rem; }
.tcd-status-band-confirmed { --st: #D9B45B; }
.tcd-status-band-negotiating { --st: #5B8DD9; }
.tcd-status-band-implied { --st: #9B7BD9; }
.tcd-status-band-declined { --st: #C75D5D; }
.tcd-status-band-unknown { --st: #8A8780; }
.tcd-status-band-head { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; margin-bottom: 0.5rem; }
.tcd-status-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--st); flex: 0 0 auto; }
.tcd-status-band-label { font-family: 'Outfit', sans-serif; font-size: 0.95rem; font-weight: 700; color: var(--text-primary); }
.tcd-status-band-count { font-family: 'DM Sans', sans-serif; font-size: 0.8rem; font-weight: 700; color: var(--st); }
.tcd-status-band-blurb { font-family: 'Source Serif 4', Georgia, serif; font-size: 0.82rem; font-style: italic; color: var(--text-caption, #a09d94); }
.tcd-status-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4rem; }
.tcd-status-chip-wrap { margin: 0; }
.tcd-status-chip { display: inline-block; font-family: 'DM Sans', sans-serif; font-size: 0.78rem; color: var(--text-primary); background: color-mix(in srgb, var(--st) 8%, transparent); border: 1px solid color-mix(in srgb, var(--st) 30%, transparent); border-radius: 999px; padding: 0.22rem 0.6rem; }
button.tcd-status-chip-link { cursor: pointer; }
button.tcd-status-chip-link:hover, button.tcd-status-chip-link:focus-visible { background: color-mix(in srgb, var(--st) 18%, transparent); border-color: var(--st); outline: none; }
.tcd-status-note { margin: 0.6rem 0 0; }

/* --- Agreements directory table --- */
.tcd-agr-toolbar { display: flex; justify-content: flex-end; margin-bottom: 0.5rem; }
.tcd-agr-csv-btn {
    font-family: 'DM Sans', sans-serif; font-size: 0.74rem; padding: 0.3rem 0.8rem; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--border); background: transparent; color: var(--text-secondary);
}
.tcd-agr-csv-btn:hover { color: var(--text-primary); border-color: var(--accent); }
.tcd-agr-table { width: 100%; border-collapse: collapse; font-family: 'DM Sans', sans-serif; font-size: 0.8rem; }
.tcd-agr-th { text-align: left; border-bottom: 1px solid var(--border); padding: 0; }
.tcd-agr-th-num { text-align: right; }
.tcd-agr-sort-btn {
    width: 100%; background: none; border: none; cursor: pointer; color: var(--text-secondary);
    font: inherit; font-weight: 600; padding: 0.5rem 0.6rem; display: flex; align-items: center; gap: 0.3rem;
}
.tcd-agr-th-num .tcd-agr-sort-btn { justify-content: flex-end; }
.tcd-agr-sort-btn:hover { color: var(--text-primary); }
.tcd-agr-th-active .tcd-agr-sort-btn { color: var(--accent); }
.tcd-agr-sort-caret { font-size: 0.7em; }
.tcd-agr-row { border-bottom: 1px solid var(--border); cursor: pointer; transition: background 0.12s ease; }
.tcd-agr-row:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.tcd-agr-td { padding: 0.5rem 0.6rem; color: var(--text-secondary); vertical-align: top; }
.tcd-agr-td-country { color: var(--text-primary); font-weight: 600; }
.tcd-agr-td-num { text-align: right; font-variant-numeric: tabular-nums; }
.tcd-agr-note { margin-top: 0.8rem; font-size: 0.78rem; }

/* Mobile: country file becomes a full-width sheet; Sankey + table scroll */
@media (max-width: 760px) {
    .tcd-country-file { position: static; width: auto; max-height: none; margin: 0.6rem 0.75rem 0.75rem;
        -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
    .tcd-agr-table { font-size: 0.74rem; }
    .tcd-agr-td, .tcd-agr-sort-btn { padding: 0.4rem 0.4rem; }
}

/* ============================================================
   The People: voices gallery + single-voice modal.
   Editorial restraint; consent state is visible at all times.
   The gallery styles (.tcd-voice-*) and "From the record" band (below) now render ONLY on the
   standalone third-country/people-embed.html (js/third-country-voices.js + record-band.js are
   no longer loaded on the main tab — see index.html/tab.js, removed 2026-07-27). The single-voice
   modal (.tcd-voice-modal / .tcd-vp-*) is shared: it still renders on the main tab too, lazily
   created on <body> by js/third-country-voice-player.js when a country-file testimony link is
   opened (ICE.openVoice). .tcd-sr-only is a general sr-only utility reused well beyond this
   section (answer-map, busflow, views) — do not remove even if the rest of this block goes.
   ============================================================ */
.tcd-sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* --- filter bar --- */
.tcd-voice-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.8rem; margin: 0.7rem 0 1.1rem; }
.tcd-voice-filter-label { font-family: 'Outfit', sans-serif; font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-caption); margin-right: 0.15rem; }
.tcd-voice-filter-roles { display: inline-flex; flex-wrap: wrap; gap: 0.35rem; }
.tcd-voice-chip {
    font-family: 'DM Sans', sans-serif; font-size: 0.74rem; color: var(--text-secondary);
    background: transparent; border: 1px solid var(--border); border-radius: 999px; padding: 0.24rem 0.7rem; cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.tcd-voice-chip:hover { color: var(--text-primary); border-color: var(--accent); }
.tcd-voice-chip.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.tcd-voice-country-select {
    font-family: 'DM Sans', sans-serif; font-size: 0.74rem; color: var(--text-secondary);
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 999px; padding: 0.26rem 0.6rem; cursor: pointer;
}
.tcd-voice-filter-transcript { display: inline-flex; align-items: center; gap: 0.35rem; font-family: 'DM Sans', sans-serif; font-size: 0.74rem; color: var(--text-secondary); cursor: pointer; }

/* --- role groups + grid --- */
.tcd-voice-group { margin-bottom: 1.4rem; }
.tcd-voice-group-heading { display: flex; align-items: baseline; gap: 0.5rem; margin: 0 0 0.6rem; }
.tcd-voice-group-label { font-family: 'Outfit', sans-serif; font-size: 1rem; color: var(--text-primary); }
.tcd-voice-group-count { font-family: 'DM Sans', sans-serif; font-size: 0.72rem; color: var(--text-caption); }
/* minmax(0,...) (not the default minmax(auto,...)) so columns shrink below a card's
   content min-content instead of forcing the track wider than the viewport. */
.tcd-voice-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 0.7rem; }

/* --- voice card --- */
.tcd-voice-card {
    display: flex; gap: 0.6rem; align-items: flex-start; text-align: left; cursor: pointer;
    background: var(--tcd-surface, #222021); border: 1px solid var(--tcd-border, #3a3738); border-radius: 10px;
    padding: 0.7rem 0.75rem; color: var(--tcd-text, #F6F3EA); transition: border-color 0.14s ease, transform 0.14s ease;
}
.tcd-voice-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.tcd-voice-avatar { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 50%; overflow: hidden; display: flex; align-items: center; justify-content: center; }
.tcd-voice-avatar-monogram { background: color-mix(in srgb, var(--accent) 22%, transparent); }
.tcd-voice-monogram-text, .tcd-vp-monogram-text { font-family: 'Outfit', sans-serif; font-weight: 600; color: var(--accent); }
.tcd-voice-silhouette { width: 100%; height: 100%; display: block; }
.tcd-voice-silhouette-bg { fill: var(--tcd-border, #3a3738); }
.tcd-voice-hatch-line { stroke: var(--tcd-textDim, #a09d94); stroke-width: 1; opacity: 0.5; }
.tcd-voice-card-body { min-width: 0; flex: 1; overflow: hidden; }
.tcd-voice-card-name { font-family: 'DM Sans', sans-serif; font-size: 0.82rem; font-weight: 600; display: flex; align-items: center; gap: 0.35rem; min-width: 0; }
.tcd-voice-card-name > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tcd-voice-card-sub { font-size: 0.72rem; color: var(--tcd-textDim, #a09d94); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; }
.tcd-voice-card-country { font-size: 0.66rem; color: var(--tcd-textDim, #a09d94); text-transform: uppercase; letter-spacing: 0.04em; margin-top: 3px; }
.tcd-voice-card-badges { display: flex; gap: 4px; margin-top: 5px; }
.tcd-voice-badge { font-size: 0.56rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--tcd-textDim, #a09d94); border: 1px solid var(--tcd-border, #3a3738); border-radius: 4px; padding: 1px 4px; }
.tcd-voice-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.tcd-voice-dot-on { background: #D9EF56; }
.tcd-voice-dot-off { background: var(--tcd-textDim, #a09d94); }
.tcd-voice-card-off { opacity: 0.82; }

/* --- single-voice modal --- */
.tcd-voice-modal[hidden] { display: none; }
/* Backdrop + dialog are SIBLINGS (the player builds them so), so the dialog centres itself
   with position:fixed rather than relying on the backdrop as a flex parent. */
.tcd-vp-backdrop { position: fixed; inset: 0; z-index: 1000; background: rgba(10, 9, 9, 0.66); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.tcd-vp-dialog {
    position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1001;
    width: min(540px, calc(100% - 2rem)); max-height: 86vh; overflow-y: auto;
    background: var(--tcd-surface, #222021); border: 1px solid var(--tcd-border, #3a3738); border-radius: 14px;
    box-shadow: 0 24px 64px rgba(0,0,0,0.6); padding: 1.3rem 1.4rem 1.5rem; color: var(--tcd-text, #F6F3EA);
    animation: tcd-vp-fade 0.18s ease;
}
@keyframes tcd-vp-fade { from { opacity: 0; } to { opacity: 1; } }
.tcd-vp-close { position: absolute; top: 12px; right: 14px; background: none; border: none; color: var(--tcd-textDim, #a09d94); font-size: 22px; line-height: 1; cursor: pointer; }
.tcd-vp-close:hover { color: var(--tcd-text, #F6F3EA); }
.tcd-vp-header { display: flex; gap: 0.9rem; align-items: center; margin: 0 1.5rem 0.8rem 0; }
.tcd-vp-avatar { flex: 0 0 auto; width: 54px; height: 54px; border-radius: 50%; overflow: hidden; display: flex; align-items: center; justify-content: center; }
.tcd-vp-avatar-monogram { background: color-mix(in srgb, var(--accent) 22%, transparent); }
.tcd-vp-monogram-text { font-size: 1.2rem; }
.tcd-vp-name { font-family: 'Outfit', sans-serif; font-size: 1.2rem; margin: 0; }
.tcd-vp-role { font-size: 0.74rem; color: var(--tcd-textDim, #a09d94); text-transform: uppercase; letter-spacing: 0.05em; }
.tcd-vp-loc { font-family: 'DM Sans', sans-serif; font-size: 0.82rem; color: var(--tcd-text, #F6F3EA); margin-top: 2px; }
.tcd-vp-role-detail { font-size: 0.78rem; color: var(--tcd-textDim, #a09d94); margin-top: 1px; }
.tcd-vp-consent { display: inline-block; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.05em; border-radius: 999px; padding: 0.18rem 0.6rem; margin-bottom: 0.8rem; }
.tcd-vp-consent-on { color: #1A1819; background: #D9EF56; }
.tcd-vp-consent-off { color: #E8A23D; border: 1px solid #E8A23D; }
.tcd-vp-content { }
.tcd-vp-quote { font-family: 'Source Serif 4', Georgia, serif; font-size: 1.05rem; line-height: 1.5; color: var(--tcd-text, #F6F3EA); border-left: 3px solid #D9EF56; padding-left: 0.9rem; margin: 0 0 0.9rem; }
.tcd-vp-quote-pending { border-left-color: var(--tcd-border, #3a3738); }
.tcd-vp-quote-pending-text { color: var(--tcd-textDim, #a09d94); font-style: italic; font-size: 0.86rem; }
.tcd-vp-transcript { display: inline-block; font-family: 'DM Sans', sans-serif; font-size: 0.82rem; color: var(--accent); text-decoration: underline; text-underline-offset: 3px; margin: 0.2rem 0 0.7rem; }
.tcd-vp-transcript:hover { color: var(--text-primary); }
.tcd-vp-media { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.4rem; }
.tcd-vp-media-badge { font-size: 0.66rem; color: var(--tcd-textDim, #a09d94); border: 1px solid var(--tcd-border, #3a3738); border-radius: 6px; padding: 0.2rem 0.5rem; }

/* Footer: "Embed this account" — drop one interview into another newsroom's page */
.tcd-vp-footer { margin-top: 1rem; padding-top: 0.85rem; border-top: 1px solid var(--tcd-border, #3a3738); }
.tcd-vp-embed-btn {
    display: inline-flex; align-items: center; gap: 0.4rem;
    font-family: 'DM Sans', sans-serif; font-size: 0.78rem; font-weight: 600;
    color: var(--tcd-text, #F6F3EA); background: transparent;
    border: 1px solid var(--tcd-border, #3a3738); border-radius: 7px;
    padding: 0.38rem 0.7rem; cursor: pointer; transition: border-color 0.15s, background 0.15s;
}
.tcd-vp-embed-btn::before {
    content: '< >'; font-family: 'DM Sans', sans-serif; font-weight: 700; letter-spacing: -1px;
    color: #D9EF56;
}
.tcd-vp-embed-btn:hover { border-color: #D9EF56; background: rgba(217, 239, 86, 0.08); }
.tcd-vp-embed-btn:focus-visible { outline: 2px solid #D9EF56; outline-offset: 2px; }

/* Portrait avatars (when a photo source is supplied) */
.tcd-voice-avatar-photo, .tcd-vp-avatar-photo { background: var(--tcd-border, #3a3738); }
.tcd-voice-avatar-img, .tcd-vp-avatar-img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Playable media in the voice modal */
.tcd-vp-video { display: block; width: 100%; max-height: 320px; border-radius: 8px; margin: 0 0 0.7rem; background: #000; }
.tcd-vp-audio { display: block; width: 100%; margin: 0 0 0.7rem; }

@media (max-width: 760px) {
    .tcd-voice-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .tcd-vp-dialog { top: auto; bottom: 0; left: 0; transform: none; width: 100%; max-height: 92vh; border-radius: 14px 14px 0 0; }
}

/* ============================================================
   Phase 6 — braided masthead (dual-entry hero) + share + focus
   ============================================================ */
.tcd-standfirst { color: var(--text-secondary); max-width: 60ch; font-family: 'Source Serif 4', Georgia, serif; }

/* (The #tcd-figures key-figure stat row was removed per redesign feedback.) */

/* The two front doors + Play-the-story */
.tcd-doors { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; margin-bottom: 0.4rem; }
.tcd-door {
    font-family: 'Outfit', 'Century Gothic', sans-serif; font-size: 0.92rem; font-weight: 600; cursor: pointer;
    background: transparent; color: var(--text-primary); border: 1px solid var(--border); border-left: 3px solid var(--accent);
    border-radius: 8px; padding: 0.6rem 1.1rem; transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.tcd-door:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); border-color: var(--accent); }
.tcd-door-people { border-left-color: #D9EF56; }
.tcd-door-people:hover { background: color-mix(in srgb, #D9EF56 14%, transparent); border-color: #D9EF56; }
.tcd-play-story {
    font-family: 'DM Sans', sans-serif; font-size: 0.82rem; cursor: pointer; color: var(--text-secondary);
    background: transparent; border: 1px solid var(--border); border-radius: 999px; padding: 0.5rem 1rem; margin-left: auto;
}
.tcd-play-story:hover { color: var(--text-primary); border-color: var(--accent); }

/* Share controls + "Link copied" toast */
.tcd-share-views { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-bottom: 1.4rem; }
.tcd-share-views-label { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-caption); font-family: 'Outfit', sans-serif; }
.tcd-share-btn {
    font-family: 'DM Sans', sans-serif; font-size: 0.72rem; cursor: pointer; color: var(--text-secondary);
    background: transparent; border: 1px solid var(--border); border-radius: 999px; padding: 0.24rem 0.7rem;
}
.tcd-share-btn:hover { color: var(--text-primary); border-color: var(--accent); }
.tcd-share-toast {
    position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%) translateY(8px); z-index: 1200;
    background: var(--tcd-surface, #222021); color: var(--tcd-text, #F6F3EA); border: 1px solid var(--tcd-border, #3a3738);
    border-radius: 999px; padding: 0.5rem 1.1rem; font-family: 'DM Sans', sans-serif; font-size: 0.8rem;
    box-shadow: 0 8px 28px rgba(0,0,0,0.45); opacity: 0; pointer-events: none; transition: opacity 0.2s ease, transform 0.2s ease;
}
.tcd-share-toast-show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Consistent keyboard focus ring across the tab's interactive elements */
.tcd-door:focus-visible, .tcd-play-story:focus-visible, .tcd-share-btn:focus-visible,
.tcd-voice-card:focus-visible, .tcd-voice-chip:focus-visible, .tcd-region-chip:focus-visible,
.tcd-mode-btn:focus-visible, .tcd-agr-row:focus-visible, .tcd-agr-sort-btn:focus-visible,
.tcd-cf-action:focus-visible, .tcd-vp-close:focus-visible, .tcd-cf-close:focus-visible,
.tcd-volume-row-btn:focus-visible, .tcd-scrubber-playhead:focus-visible, .tcd-scrubber-play:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 2px;
}

@media (max-width: 760px) {
    .tcd-doors { flex-direction: column; align-items: stretch; }
    .tcd-door, .tcd-play-story { text-align: center; margin-left: 0; }
}

/* --- Shared alternate-view toggle (roads-not-taken comparisons) --- */
.tcd-alt-toggle { display: inline-flex; align-items: center; gap: 0.25rem; flex-wrap: wrap;
  padding: 0.2rem; border: 1px solid var(--border, #2a2a2a); border-radius: 999px; background: rgba(0,0,0,0.18); }
.tcd-alt-toggle-label { font: 600 0.72rem/1 Inter, sans-serif; text-transform: uppercase;
  letter-spacing: 0.06em; opacity: 0.7; padding: 0 0.4rem; }
.tcd-alt-opt { display: inline-flex; align-items: center; gap: 0.3rem; cursor: pointer;
  border: 0; border-radius: 999px; background: transparent; color: var(--text-primary, #eee);
  font: 600 0.82rem/1 Inter, sans-serif; padding: 0.32rem 0.7rem; }
.tcd-alt-opt.active { background: var(--accent, #D9EF56); color: #111; }
.tcd-alt-opt:focus-visible { outline: 2px solid var(--accent, #D9EF56); outline-offset: 2px; }
.tcd-alt-opt-tag { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.05em;
  padding: 0.05rem 0.3rem; border-radius: 999px; border: 1px solid currentColor; opacity: 0.65; }
.tcd-alt-opt.active .tcd-alt-opt-tag { opacity: 0.8; }

/* Wall-of-voices alternate: one dense ungrouped grid (mobile-safe minmax(0,1fr)). */
.tcd-voice-wall { display: grid; gap: 0.6rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 180px), 1fr)); }
.tcd-voice-grouping { margin-left: auto; }

/* Stacked-area alternate time view */
.tcd-time-toggle { margin: 0.5rem 0; }
.tcd-time-toggle:empty { display: none; }
.tcd-stackedarea { margin: 0.5rem 0 1rem; }
.tcd-sa-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.4rem; }
.tcd-sa-title { font: 600 0.85rem/1.2 Inter, sans-serif; opacity: 0.85; }
.tcd-sa-back { border: 1px solid var(--border,#2a2a2a); background: transparent; color: var(--text-primary,#eee);
  border-radius: 999px; padding: 0.2rem 0.6rem; font: 600 0.78rem Inter, sans-serif; cursor: pointer; }
.tcd-sa-svg { width: 100%; height: 220px; display: block; }
.tcd-sa-baseline { stroke: var(--border,#444); stroke-width: 1; }
.tcd-sa-band { stroke: rgba(0,0,0,0.25); stroke-width: 0.5; opacity: 0.9; }
.tcd-sa-band:hover { opacity: 1; }
.tcd-sa-sign { stroke: #F4A259; stroke-width: 1; stroke-dasharray: 2 3; opacity: 0.8; }
.tcd-sa-axis { position: relative; height: 1.1rem; margin-top: 0.15rem; font: 0.62rem Inter, sans-serif; opacity: 0.7; }
.tcd-sa-axis-tick { position: absolute; top: 0; white-space: nowrap; }
.tcd-sa-legend { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; margin-top: 0.5rem; }
.tcd-sa-legend-item { display: inline-flex; align-items: center; gap: 0.35rem; font: 0.78rem Inter, sans-serif; }
.tcd-sa-swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }

/* Radial (WRV) alternate encoding */
.tcd-altviz { min-height: 420px; padding: 0.5rem; }
.tcd-altviz-note { font: 0.78rem Inter, sans-serif; opacity: 0.7; margin: 0 0 0.5rem; }
.tcd-radial-caption, .tcd-radial-title { font: 600 0.82rem Inter, sans-serif; opacity: 0.85; }
.tcd-radial-grid { display: grid; gap: 0.8rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 180px), 1fr)); }
.tcd-radial-cell { background: rgba(255,255,255,0.03); border: 1px solid var(--border,#2a2a2a); border-radius: 12px;
  padding: 0.5rem; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 0.3rem; }
.tcd-radial-cell:hover, .tcd-radial-cell:focus-visible { border-color: var(--accent,#D9EF56); outline: none; }
.tcd-radial-glyph { width: 100%; max-width: 200px; aspect-ratio: 1; }
.tcd-radial-ring { stroke: var(--border,#333); stroke-width: 1; }
.tcd-radial-spoke { stroke: var(--accent,#D9EF56); stroke-width: 2; }
.tcd-radial-node { fill: var(--accent,#D9EF56); }
.tcd-radial-hub { fill: #fff; }
.tcd-radial-cell-cap { display: flex; flex-direction: column; align-items: center; }
.tcd-radial-cell-region { font: 600 0.82rem Inter, sans-serif; }
.tcd-radial-cell-total { font: 0.78rem Inter, sans-serif; opacity: 0.7; }
.tcd-radial-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.5rem; }
.tcd-radial-back { border: 1px solid var(--border,#2a2a2a); background: transparent; color: var(--text-primary,#eee);
  border-radius: 999px; padding: 0.2rem 0.6rem; cursor: pointer; font: 600 0.78rem Inter, sans-serif; }
.tcd-radial-solo { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 1rem; align-items: center; }
@media (max-width: 600px) { .tcd-radial-solo { grid-template-columns: minmax(0,1fr); } }
.tcd-radial-list { list-style: none; margin: 0; padding: 0; }
.tcd-radial-list-item { display: flex; justify-content: space-between; padding: 0.2rem 0; border-bottom: 1px solid var(--border,#222); font: 0.85rem Inter, sans-serif; }

/* Chord alternate encoding */
.tcd-chord-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.4rem; }
.tcd-chord-title { font: 600 0.82rem Inter, sans-serif; opacity: 0.85; }
.tcd-chord-back { border: 1px solid var(--border,#2a2a2a); background: transparent; color: var(--text-primary,#eee);
  border-radius: 999px; padding: 0.2rem 0.6rem; cursor: pointer; font: 600 0.78rem Inter, sans-serif; }
.tcd-chord-svg { width: 100%; max-width: 460px; aspect-ratio: 1; display: block; margin: 0 auto; }
.tcd-chord-arc { stroke: rgba(0,0,0,0.3); stroke-width: 0.5; }
.tcd-chord-ribbon { opacity: 0.45; }
.tcd-chord-ribbon:hover { opacity: 0.75; }
.tcd-chord-label { fill: var(--text-primary,#ddd); font: 0.62rem Inter, sans-serif; }

/* Encoding toggle host (Map ▸ Radial ▸ Chord) */
.tcd-mode-toggle:empty { display: none; }
.tcd-altviz { background: rgba(255,255,255,0.02); border: 1px solid var(--border,#222); border-radius: 12px; }

/* ============================================================================
   Alternate map VIEWS — cartogram / transit / pressure (js/third-country-views.js
   switcher in #tcd-mode-toggle). Shared chrome first, then per-view specifics.
   Uses var(--tcd-*, fallback) so it renders correctly outside the globe's scope.
   ============================================================================ */
.tcd-view { padding: 0.25rem 0 0.5rem; }
.tcd-view[hidden] { display: none; }
.tcd-view-head { margin: 0.2rem 0 0.6rem; }
.tcd-view-title { font-family: 'Outfit', sans-serif; font-size: 1.5rem; font-weight: 600; margin: 0; color: var(--tcd-text, #F6F3EA); letter-spacing: -0.01em; }
.tcd-view-sub { font-family: 'Source Serif 4', Georgia, serif; font-size: 0.95rem; line-height: 1.45; color: var(--tcd-textDim, #a09d94); margin: 0.3rem 0 0; max-width: 60ch; }
.tcd-view-stage { position: relative; width: 100%; }
.tcd-view-stage svg { width: 100%; height: auto; display: block; }
.tcd-view-fallback { font-family: 'Outfit', sans-serif; color: var(--tcd-textDim, #a09d94); padding: 2rem; text-align: center; }

/* play / scrub transport bar */
.tcd-view-transport { display: flex; align-items: center; gap: 0.75rem; margin: 0.55rem 0 0.4rem; }
.tcd-view-play { font-family: 'Outfit', sans-serif; font-size: 0.82rem; font-weight: 600; cursor: pointer;
  background: var(--accent, #4460D8); color: #fff; border: none; border-radius: 999px; padding: 0.42rem 1.05rem; white-space: nowrap;
  transition: filter 0.15s ease; min-width: 92px; }
.tcd-view-play:hover { filter: brightness(1.12); }
.tcd-view-play:focus-visible { outline: 2px solid var(--accent, #4460D8); outline-offset: 2px; }
.tcd-view-scrub { flex: 1; min-width: 80px; accent-color: var(--accent, #4460D8); height: 4px; cursor: pointer; }
.tcd-view-readout { font-family: 'Outfit', sans-serif; font-variant-numeric: tabular-nums; font-size: 0.86rem; color: var(--tcd-text, #F6F3EA);
  min-width: 8.5ch; text-align: right; letter-spacing: 0.01em; }

/* legend + footnote */
.tcd-view-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 0.55rem 0.9rem; margin: 0.35rem 0; font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.74rem; color: var(--tcd-textDim, #a09d94); }
.tcd-view-legend-item { display: inline-flex; align-items: center; gap: 0.35rem; }
.tcd-view-legend-lbl { font-style: italic; }
.tcd-view-legend-sep { width: 1px; height: 0.9rem; background: var(--tcd-border, #3a3738); }
.tcd-view-foot { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.68rem; color: var(--tcd-textDim, #a09d94); opacity: 0.85; margin: 0.2rem 0 0; }

/* shared tooltip */
.tcd-view-tip[hidden] { display: none; } /* author display:flex would otherwise beat the hidden attr */
.tcd-view-tip { position: absolute; z-index: 6; pointer-events: none; max-width: 230px;
  background: color-mix(in srgb, var(--tcd-bg, #1A1819) 92%, #000); border: 1px solid var(--tcd-border, #3a3738);
  border-radius: 8px; padding: 0.5rem 0.65rem; box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  display: flex; flex-direction: column; gap: 0.12rem; }
.tcd-view-tip strong { font-family: 'Outfit', sans-serif; font-size: 0.9rem; color: var(--tcd-text, #F6F3EA); }
.tcd-view-tip-n { font-family: 'Outfit', sans-serif; font-variant-numeric: tabular-nums; font-size: 0.82rem; color: var(--accent-warm, #f5a623); }
.tcd-view-tip-sub { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.72rem; color: var(--tcd-textDim, #a09d94); line-height: 1.3; }
.tcd-dim { opacity: 0.12; pointer-events: none; }

/* ---- A World Remade (abstract Demers squares cartogram — no basemap) ---- */
/* value squares — lime "people" family; teal signatory border when the agreements chip is on.
   Light hairline stroke: low-count squares sit at the near-black end of the ramp and would
   vanish into the dark stage with a dark stroke. */
.tcd-cartogram-square { stroke: rgba(237,232,218,0.4); stroke-width: 0.8px; cursor: pointer; }
.tcd-cartogram-svg.is-ag-on .tcd-cartogram-square { stroke: #6FA7AE; stroke-width: 1.25px; }
.tcd-cartogram-svg .tcd-cartogram-square:hover { stroke: #fff; stroke-width: 1.25px; }
/* agreement-only squares — hollow teal ("deals") — with their own name labels */
.tcd-cartogram-agsquare { fill: rgba(63,126,134,0.16); stroke: #6FA7AE; stroke-width: 1.4px; cursor: pointer; }
.tcd-cartogram-agsquare:hover { stroke: #fff; }
.tcd-cartogram-aglabel { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 9px; fill: #6FA7AE; text-anchor: middle; pointer-events: none; }
/* faint region ghost-labels — the empty stage's "world map" affordance */
.tcd-cartogram-region { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 13px; letter-spacing: 0.35em;
  fill: var(--tcd-textDim, #a09d94); opacity: 0.28; text-anchor: middle; pointer-events: none; }
/* per-square labels: hanging below small squares (off-white name, dim count); inside the
   Mexico-tier squares the ink is set inline per the square's fill */
.tcd-cartogram-label { font-family: 'DM Sans', 'Inter', sans-serif; text-anchor: middle; pointer-events: none; }
.tcd-cartogram-label-name { font-size: 9.5px; font-weight: 600; }
.tcd-cartogram-label-count { font-size: 9px; font-variant-numeric: tabular-nums; }
.tcd-cartogram-label:not(.is-inside) .tcd-cartogram-label-name { fill: #EDE8DA; }
.tcd-cartogram-label:not(.is-inside) .tcd-cartogram-label-count { fill: var(--tcd-textDim, #a09d94); }
.tcd-cartogram-label.is-inside .tcd-cartogram-label-name { font-size: 11px; }
.tcd-cartogram-label.is-inside .tcd-cartogram-label-count { font-size: 10px; }
.tcd-cartogram-label-mode { font-size: 8.5px; opacity: 0.75; }
/* in-SVG size key — drawn at true square scale */
.tcd-cartogram-key rect { fill: none; stroke: #EDE8DA; stroke-opacity: 0.45; stroke-width: 1px; }
.tcd-cartogram-key text { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 9.5px; fill: var(--tcd-textDim, #a09d94); }
.tcd-cartogram-key-title { text-transform: uppercase; letter-spacing: 0.06em; font-size: 8.5px; }
.tcd-cartogram-ramp { width: 70px; height: 10px; border-radius: 2px; display: inline-block;
  background: linear-gradient(90deg, #2E3418, #D9EF56); }
/* the agreements toggle chip in the legend row */
.tcd-cartogram-agchip { display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer;
  font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.72rem; color: var(--tcd-text, #F6F3EA);
  background: transparent; border: 1px solid var(--tcd-border, #3a3738); border-radius: 999px; padding: 0.28rem 0.7rem;
  transition: border-color 0.15s ease, background 0.15s ease; }
.tcd-cartogram-agchip:hover { border-color: #6FA7AE; }
.tcd-cartogram-agchip[aria-pressed="true"] { border-color: #6FA7AE; background: rgba(63,126,134,0.18); }
.tcd-cartogram-agchip:focus-visible { outline: 2px solid var(--accent, #4460D8); outline-offset: 2px; }
.tcd-cartogram-agchip:disabled { opacity: 0.5; cursor: default; }
.tcd-cartogram-agswatch { width: 9px; height: 9px; display: inline-block; border: 1.5px solid #6FA7AE; background: rgba(63,126,134,0.25); }

/* ---- The Strange Routes (transit) ---- */
.tcd-transit-line { fill: none; opacity: 0.82; stroke-linecap: round; stroke-linejoin: round; transition: opacity 0.15s ease; cursor: pointer; }
.tcd-transit-line:hover { opacity: 1; }
.tcd-transit-station { fill: var(--tcd-bg, #1A1819); stroke-width: 2.5px; cursor: pointer; }
.tcd-transit-station:hover { fill: #fff; }
.tcd-transit-intch { fill: var(--tcd-bg, #1A1819); stroke: var(--tcd-text, #F6F3EA); stroke-width: 2px; }
.tcd-transit-intch-lbl { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 10px; fill: var(--tcd-textDim, #a09d94); }
.tcd-transit-station-lbl { cursor: pointer; }
.tcd-transit-name { font-family: 'Outfit', sans-serif; font-size: 13px; fill: var(--tcd-text, #F6F3EA); }
.tcd-transit-station-lbl:hover .tcd-transit-name { fill: #fff; text-decoration: underline; }
.tcd-transit-meta { font-family: 'DM Sans', 'Inter', sans-serif; font-variant-numeric: tabular-nums; font-size: 10.5px; fill: var(--tcd-textDim, #a09d94); }
.tcd-transit-band { font-family: 'Outfit', sans-serif; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; opacity: 0.85; }
.tcd-transit-hub { fill: color-mix(in srgb, var(--accent, #4460D8) 22%, var(--tcd-bg, #1A1819)); stroke: var(--accent, #4460D8); stroke-width: 2px; }
.tcd-transit-hub-lbl { font-family: 'Outfit', sans-serif; font-size: 13px; font-weight: 700; letter-spacing: 0.04em; fill: var(--tcd-text, #F6F3EA); }
.tcd-transit-hub-sub { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 10px; fill: var(--tcd-textDim, #a09d94); }
.tcd-transit-swatch { width: 18px; height: 4px; border-radius: 2px; display: inline-block; }
.tcd-transit-intch-key { width: 11px; height: 11px; border-radius: 50%; background: var(--tcd-bg, #1A1819); border: 2px solid var(--tcd-text, #F6F3EA); display: inline-block; }
/* Route highlight (item 4b): on hover, one full journey lights up and the rest recede. */
.tcd-transit-station, .tcd-transit-intch, .tcd-transit-station-lbl, .tcd-transit-intch-lbl { transition: opacity 0.15s ease; }
.tcd-transit-dim .tcd-transit-line:not(.tcd-transit-hot) { opacity: 0.08; }
.tcd-transit-dim .tcd-transit-station:not(.tcd-transit-hot),
.tcd-transit-dim .tcd-transit-intch:not(.tcd-transit-hot) { opacity: 0.16; }
.tcd-transit-dim .tcd-transit-station-lbl:not(.tcd-transit-hot),
.tcd-transit-dim .tcd-transit-intch-lbl:not(.tcd-transit-hot) { opacity: 0.18; }
.tcd-transit-line.tcd-transit-hot { opacity: 1; filter: drop-shadow(0 0 5px currentColor); }
.tcd-transit-intch.tcd-transit-hot { stroke-width: 3px; }
.tcd-transit-station.tcd-transit-hot { fill: #fff; }
.tcd-transit-station-lbl.tcd-transit-hot .tcd-transit-name { fill: #fff; }
.tcd-transit-intch-lbl.tcd-transit-hot { fill: var(--tcd-text, #F6F3EA); font-weight: 600; }
/* Destinations with a documented total but no individually-logged flight yet (item 6). */
.tcd-transit-line--est { stroke-dasharray: 3 6; opacity: 0.5; }

/* ---- The Pressure Campaign (choropleth + ticker) ---- */
.tcd-pressure-stage { display: flex; gap: 1rem; align-items: stretch; }
.tcd-pressure-mapwrap { position: relative; flex: 3 1 0; min-width: 0; }
.tcd-pressure-ticker { flex: 1 1 230px; max-width: 280px; border-left: 1px solid var(--tcd-border, #3a3738); padding-left: 0.85rem; overflow: hidden; }
.tcd-pressure-ticker-h { font-family: 'Outfit', sans-serif; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--tcd-textDim, #a09d94); margin: 0 0 0.5rem; }
.tcd-pressure-ticker-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.tcd-pressure-tick { display: grid; grid-template-columns: 1fr; gap: 0.05rem; border-left: 2px solid #f5a623; padding-left: 0.5rem; }
.tcd-pressure-tick.is-signed { border-left-color: #D9EF56; }
.tcd-pressure-tick-date { font-family: 'DM Sans', 'Inter', sans-serif; font-variant-numeric: tabular-nums; font-size: 0.66rem; color: var(--tcd-textDim, #a09d94); }
.tcd-pressure-tick-country { font-family: 'Outfit', sans-serif; font-size: 0.82rem; font-weight: 600; color: var(--tcd-text, #F6F3EA); }
.tcd-pressure-tick-text { font-family: 'Source Serif 4', Georgia, serif; font-size: 0.74rem; line-height: 1.35; color: var(--tcd-textDim, #a09d94);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tcd-pressure-ocean { fill: var(--tcd-bg, #1A1819); }
.tcd-pressure-base path { fill: rgba(255,255,255,0.04); stroke: var(--tcd-border, #3a3738); stroke-width: 0.4px; }
.tcd-pressure-country { stroke: rgba(0,0,0,0.5); stroke-width: 0.5px; cursor: pointer; transition: opacity 0.2s ease; }
.tcd-pressure-country:hover { stroke: #fff; stroke-width: 1.1px; }
.tcd-pressure-islet { stroke: rgba(0,0,0,0.6); stroke-width: 0.9px; cursor: pointer; }
.tcd-pressure-islet:hover { stroke: #fff; }
.tcd-pressure-swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.tcd-pressure-legend-btn { background: none; border: 1px solid transparent; border-radius: 6px; cursor: pointer; color: inherit;
  font: inherit; padding: 0.15rem 0.4rem; }
.tcd-pressure-legend-btn:hover { border-color: var(--tcd-border, #3a3738); }
.tcd-pressure-legend-btn.active { border-color: var(--tcd-text, #F6F3EA); background: rgba(255,255,255,0.06); }

@media (max-width: 720px) {
  .tcd-view-title { font-size: 1.25rem; }
  .tcd-pressure-stage { flex-direction: column; }
  .tcd-pressure-ticker { max-width: none; border-left: none; border-top: 1px solid var(--tcd-border, #3a3738); padding-left: 0; padding-top: 0.6rem; }
  .tcd-pressure-ticker-list { flex-direction: row; overflow-x: auto; }
  .tcd-pressure-tick { min-width: 180px; }
}

/* ============================================================================
   Treated-document quote styling (.tcd-doc / .tcd-doc-* / mark.tcd-doc-hl).
   Documentary artifact: faint transcript surface + lifted editorial quote with a
   chartreuse highlighter + mono marginalia. Tokens mirror the voices wall (with
   hex fallbacks, since --tcd-* are scoped onto #tcd-globe).
   Built by js/third-country-record-band.js's ICE.tcdBuildTreatedDoc(view, opts),
   which is called from ONE surviving place: the single-voice modal's
   buildContent() in js/third-country-voice-player.js (`opts.bare`), rendering the
   consent-gated pull-quote for both the main tab and the standalone
   third-country/people-embed.html. That call is guarded
   (`if (ICE.tcdBuildTreatedDoc)`) and falls back to a plain quote block if
   record-band.js isn't loaded. record-band.js's OWN band UI (the
   `#tcd-record-band` grid of cards, `ICE.initThirdCountryRecordBand`) has no
   caller anywhere in the codebase — verified 2026-07-27 (not index.html/tab.js,
   not people-embed.html's inline script) — so its `.tcd-record-band*` CSS was
   dead and has been removed. Keep .tcd-doc/.tcd-doc-*/mark.tcd-doc-hl below.
   ============================================================================ */

/* --- one treated document --- */
.tcd-doc {
  position: relative; overflow: hidden; border-radius: 4px; isolation: isolate;
  background:
    repeating-linear-gradient(180deg, transparent 0 27px, color-mix(in srgb, var(--tcd-text, #F6F3EA) 4%, transparent) 27px 28px),
    linear-gradient(180deg, var(--tcd-surface, #222021), color-mix(in srgb, var(--tcd-surface, #222021) 80%, #000));
  border: 1px solid var(--tcd-border, #3a3738);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.03), 0 16px 38px -26px rgba(0,0,0,0.9);
  padding: 1.5rem 1.45rem 1.25rem; color: var(--tcd-text, #F6F3EA);
  opacity: 0; transform: translateY(14px);
  animation: tcd-doc-rise 0.7s cubic-bezier(0.2,0.7,0.2,1) forwards;
  animation-delay: calc(var(--tcd-doc-i, 0) * 0.09s);
}
.tcd-doc[role="button"] { cursor: pointer; transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease; }
.tcd-doc[role="button"]:hover { border-color: color-mix(in srgb, #D9EF56 55%, var(--tcd-border, #3a3738)); transform: translateY(-2px); box-shadow: 0 22px 44px -26px rgba(0,0,0,0.95); }
.tcd-doc[role="button"]:focus-visible { outline: 2px solid #D9EF56; outline-offset: 2px; }
@keyframes tcd-doc-rise { to { opacity: 1; transform: none; } }

.tcd-doc-ghost {
  position: absolute; inset: 0; padding: 1.4rem 1.4rem; z-index: -1; pointer-events: none;
  font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.66rem; line-height: 1.9;
  color: var(--tcd-text, #F6F3EA); opacity: 0.05; white-space: pre-wrap; overflow: hidden; user-select: none;
}
.tcd-doc-margin {
  font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.64rem; letter-spacing: 0.01em;
  color: var(--tcd-textDim, #a09d94); display: flex; gap: 0.7rem; flex-wrap: wrap; margin-bottom: 0.95rem;
}
.tcd-doc-tc { color: #D9EF56; opacity: 0.9; }

.tcd-doc-quote {
  font-family: 'Source Serif 4', Georgia, serif; font-weight: 400; font-size: 1.33rem; line-height: 1.36;
  letter-spacing: -0.004em; color: var(--tcd-text, #F6F3EA); margin: 0 0 1.15rem;
}
.tcd-doc-compact .tcd-doc-quote { font-size: 1.18rem; }
/* highlighter: dark text on a solid chartreuse mark. The background lives on the <mark> with
   box-decoration-break:clone so EVERY wrapped line fragment is covered — otherwise the dark text
   on an uncovered second line goes dark-on-dark and disappears. */
mark.tcd-doc-hl {
  color: var(--tcd-bg, #1A1819);
  background: #D9EF56;
  box-shadow: 0 0 0 0.5px color-mix(in srgb, #D9EF56 62%, #000);
  padding: 0.06em 0.16em; border-radius: 3px;
  font-weight: 600; box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
/* end-of-quote cursor: a thin chartreuse bar that blinks like a transcript caret when the document
   is opened (modal) or the card is engaged (hover / keyboard focus). */
.tcd-doc-cursor {
  display: inline-block; width: 2px; height: 1.02em; margin-left: 0.12em; vertical-align: -0.14em;
  background: #D9EF56; border-radius: 1px; opacity: 0;
}
.tcd-doc-bare .tcd-doc-cursor,
.tcd-doc[role="button"]:hover .tcd-doc-cursor,
.tcd-doc[role="button"]:focus-visible .tcd-doc-cursor {
  animation: tcd-doc-blink 1.06s steps(1) infinite;
}
@keyframes tcd-doc-blink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }

/* held / withheld */
.tcd-doc-held { margin: 0 0 1.1rem; }
.tcd-doc-redact {
  display: block; height: 2.4em; border-radius: 2px; margin-bottom: 0.6rem; user-select: none;
  background: repeating-linear-gradient(90deg, var(--tcd-border, #3a3738) 0 7px, transparent 7px 9px);
}
.tcd-doc-held-note { font-family: 'DM Sans', sans-serif; font-size: 0.82rem; color: var(--tcd-textDim, #a09d94); margin: 0; }

/* illustrative badge */
.tcd-doc-illus-badge {
  position: absolute; top: 0.85rem; right: 0.85rem; z-index: 1;
  font-family: 'DM Sans', sans-serif; font-size: 0.56rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: #E8A23D; border: 1px solid color-mix(in srgb, #E8A23D 55%, transparent); border-radius: 4px; padding: 0.14rem 0.42rem;
}

/* identity row */
.tcd-doc-who { display: flex; align-items: center; gap: 0.7rem; margin-top: 0.2rem; padding-top: 1rem; border-top: 1px solid var(--tcd-border, #3a3738); }
.tcd-doc-avatar { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center; overflow: hidden; }
.tcd-doc-avatar-mono { background: color-mix(in srgb, #D9EF56 16%, transparent); }
.tcd-doc-mono-text { font-family: 'Outfit', sans-serif; font-weight: 600; font-size: 1rem; color: #D9EF56; }
.tcd-doc-avatar-photo { background: var(--tcd-border, #3a3738); }
.tcd-doc-avatar-img { width: 100%; height: 100%; object-fit: cover; }
.tcd-doc-sil { width: 100%; height: 100%; display: block; }
.tcd-doc-sil-bg { fill: var(--tcd-border, #3a3738); }
.tcd-doc-hatch-line { stroke: var(--tcd-textDim, #a09d94); stroke-width: 1; opacity: 0.5; }
.tcd-doc-who-meta { min-width: 0; flex: 1; }
.tcd-doc-name { font-family: 'Outfit', sans-serif; font-weight: 500; font-size: 1rem; line-height: 1.1; color: var(--tcd-text, #F6F3EA); }
.tcd-doc-sub { font-family: 'DM Sans', sans-serif; font-size: 0.74rem; color: var(--tcd-textDim, #a09d94); margin-top: 1px; }
.tcd-doc-rolechip { font-family: 'DM Sans', sans-serif; font-size: 0.58rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--tcd-textDim, #a09d94); border: 1px solid var(--tcd-border, #3a3738); border-radius: 999px; padding: 0.16rem 0.55rem; white-space: nowrap; }

.tcd-doc-consent { font-family: 'DM Sans', sans-serif; font-size: 0.62rem; letter-spacing: 0.06em; text-transform: uppercase; margin-top: 0.8rem; display: flex; align-items: center; gap: 0.45rem; color: var(--tcd-textDim, #a09d94); }
.tcd-doc-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.tcd-doc-dot-on { background: #D9EF56; box-shadow: 0 0 8px color-mix(in srgb, #D9EF56 70%, transparent); }
.tcd-doc-dot-off { background: var(--tcd-textDim, #a09d94); }
.tcd-doc-badges { display: flex; gap: 0.32rem; margin-top: 0.65rem; flex-wrap: wrap; }
.tcd-doc-badge { font-family: 'DM Sans', sans-serif; font-size: 0.56rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--tcd-textDim, #a09d94); border: 1px solid var(--tcd-border, #3a3738); border-radius: 4px; padding: 0.12rem 0.4rem; }
.tcd-doc-badge-live { color: #D9EF56; border-color: color-mix(in srgb, #D9EF56 45%, transparent); }
.tcd-doc-sronly { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* empty / arriving */
.tcd-doc-empty { text-align: left; }
.tcd-doc-empty-k { font-family: 'Outfit', sans-serif; font-weight: 500; font-size: 1.05rem; margin: 0 0 0.4rem; color: var(--tcd-text, #F6F3EA); }
.tcd-doc-empty-t { font-family: 'DM Sans', sans-serif; font-size: 0.86rem; color: var(--tcd-textDim, #a09d94); margin: 0; }

@media (max-width: 760px) {
  .tcd-doc-quote { font-size: 1.2rem; }
}
@media (prefers-reduced-motion: reduce) {
  .tcd-doc { opacity: 1; transform: none; animation: none; }
  .tcd-doc-bare .tcd-doc-cursor { animation: none; opacity: 1; }
}

/* bare variant — the treated-document body embedded inside the single-voice modal: strip the card
   chrome (the dialog supplies the surface, avatar header, consent badge, and media). */
.tcd-doc-bare { background: none; border: 0; box-shadow: none; padding: 0; overflow: visible; opacity: 1; transform: none; animation: none; margin: 0 0 0.4rem; }
.tcd-doc-bare .tcd-doc-margin { margin-bottom: 0.7rem; }
.tcd-doc-bare .tcd-doc-quote { font-size: 1.2rem; margin-bottom: 0.5rem; }
.tcd-doc-bare .tcd-doc-illus-badge { position: static; display: inline-block; margin: 0 0 0.55rem; }
.tcd-doc-bare .tcd-doc-held { margin-bottom: 0.4rem; }
.tcd-doc-pending { color: var(--tcd-textDim, #a09d94); font-style: italic; font-size: 0.9rem; }

/* Drive-streamed media embeds in the single-voice modal (raw footage streamed by Google, not hosted). */
.tcd-vp-embed { margin: 0 0 0.85rem; }
.tcd-vp-embed-frame { width: 100%; border: 1px solid var(--tcd-border, #3a3738); border-radius: 8px; display: block; background: #000; }
.tcd-vp-embed-video .tcd-vp-embed-frame { aspect-ratio: 16 / 9; height: auto; }
.tcd-vp-embed-audio .tcd-vp-embed-frame { height: 62px; background: var(--tcd-surface, #222021); }
.tcd-vp-embed-cap { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.62rem; letter-spacing: 0.01em; color: var(--tcd-textDim, #a09d94); margin: 0.32rem 0 0; }

/* --- Negotiation-pipeline hover detail (folds in the retired "All agreements" table) --- */
.tcd-status { position: relative; }
.tcd-status-csv-btn { font-family: 'Outfit', sans-serif; font-size: 0.72rem; font-weight: 600; cursor: pointer;
  background: transparent; color: var(--tcd-text, #F6F3EA); border: 1px solid var(--tcd-border, #3a3738);
  border-radius: 999px; padding: 0.3rem 0.8rem; margin: 0 0 0.8rem; }
.tcd-status-csv-btn:hover { border-color: var(--accent, #4460D8); }
.tcd-status-csv-btn:focus-visible { outline: 2px solid var(--accent, #4460D8); outline-offset: 2px; }
.tcd-status-chip[tabindex] { cursor: help; }
.tcd-status-tip { position: absolute; z-index: 30; pointer-events: none; max-width: 290px; min-width: 200px;
  background: color-mix(in srgb, var(--tcd-bg, #1A1819) 94%, #000); border: 1px solid var(--tcd-border, #3a3738);
  border-radius: 10px; padding: 0.6rem 0.7rem; box-shadow: 0 10px 30px rgba(0,0,0,0.55);
  display: flex; flex-direction: column; gap: 0.18rem; }
.tcd-status-tip-title { font-family: 'Outfit', sans-serif; font-size: 0.95rem; color: var(--tcd-text, #F6F3EA); }
.tcd-status-tip-status { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.68rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em; margin: 0 0 0.25rem; }
.tcd-status-tip-confirmed { color: #D9EF56; }
.tcd-status-tip-negotiating { color: #f5a623; }
.tcd-status-tip-implied { color: #8aa0e8; }
.tcd-status-tip-declined { color: #ff5c5c; }
.tcd-status-tip-unknown { color: var(--tcd-textDim, #a09d94); }
.tcd-status-tip-row { display: grid; grid-template-columns: 9.5em 1fr; gap: 0.5rem; font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.74rem; line-height: 1.3; }
.tcd-status-tip-k { color: var(--tcd-textDim, #a09d94); }
.tcd-status-tip-v { color: var(--tcd-text, #F6F3EA); font-variant-numeric: tabular-nums; }
.tcd-status-tip-cta { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.68rem; color: var(--accent-2, #8aa0e8); margin: 0.3rem 0 0; }
.tcd-status-tip-empty { font-family: 'Source Serif 4', Georgia, serif; font-size: 0.76rem; color: var(--tcd-textDim, #a09d94); line-height: 1.35; }

/* --- Sankey magnitude headline: land-vs-air split (includes Mexico; flights magnified below) --- */
.tcd-split { margin: 0 0 1.1rem; }
.tcd-split-caption { font-family: 'Source Serif 4', Georgia, serif; font-size: 0.95rem; line-height: 1.45;
  color: var(--tcd-text, #F6F3EA); margin: 0 0 0.55rem; max-width: 64ch; }
.tcd-split-track { display: flex; width: 100%; height: 52px; border-radius: 8px; overflow: hidden; gap: 2px; background: var(--tcd-border, #3a3738); }
.tcd-split-seg { display: flex; flex-direction: column; justify-content: center; min-width: 0; padding: 0 0.7rem;
  color: #1a1819; overflow: hidden; border: 0; text-align: left; }
.tcd-split-seg-land { background: #E8A23D; cursor: pointer; }
.tcd-split-seg-land:hover { filter: brightness(1.06); }
.tcd-split-seg-land:focus-visible { outline: 2px solid #fff; outline-offset: -3px; }
.tcd-split-seg-air { background: #D9EF56; }
.tcd-split-seg-name { font-family: 'Outfit', sans-serif; font-weight: 700; font-size: 0.86rem; letter-spacing: 0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tcd-split-seg-num { font-family: 'Outfit', sans-serif; font-variant-numeric: tabular-nums; font-size: 0.78rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0.85; }
.tcd-split-sub { font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.72rem; color: var(--tcd-textDim, #a09d94); margin: 0.5rem 0 0; font-style: italic; }
@media (max-width: 600px) {
  .tcd-split-track { height: 46px; }
  .tcd-split-seg { padding: 0 0.4rem; }
  .tcd-split-seg-name { font-size: 0.72rem; }
  .tcd-split-seg-num { font-size: 0.66rem; }
}

/* --- Mexico land-border deep-dive (country-file body) --- */
.tcd-mx-headline { margin-bottom: 0.25rem; }
.tcd-mx-footnote { font-size: 0.8rem; color: var(--text-secondary, #9aa); margin: 0 0 1rem; line-height: 1.4; }
.tcd-mx-lowerbound-link { color: var(--text-primary, #eee); text-decoration: underline; text-decoration-color: #E8A23D; text-underline-offset: 2px; }
.tcd-mx-toggle { display: inline-flex; gap: 0; border: 1px solid var(--border, #2a2a2a); border-radius: 999px; overflow: hidden; margin-bottom: 1rem; flex-wrap: wrap; }
.tcd-mx-tab { background: transparent; color: var(--text-primary, #eee); border: 0; padding: 0.4rem 0.9rem; font: inherit; font-size: 0.85rem; cursor: pointer; }
.tcd-mx-tab + .tcd-mx-tab { border-left: 1px solid var(--border, #2a2a2a); }
.tcd-mx-tab.active { background: #E8A23D; color: #1a1a1a; }
.tcd-mx-view { min-height: 120px; }
.tcd-mx-empty { color: var(--text-secondary, #9aa); font-style: italic; }
.tcd-mx-citations { margin-top: 1.5rem; border-top: 1px solid var(--border, #2a2a2a); padding-top: 0.75rem; }
.tcd-mx-citations-title { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-secondary, #9aa); margin: 0 0 0.4rem; }
.tcd-mx-citations-list { list-style: none; padding: 0; margin: 0; font-size: 0.78rem; line-height: 1.45; }
.tcd-mx-citations-list li { margin-bottom: 0.4rem; }
.tcd-mx-citations-list a { color: var(--text-primary, #eee); text-decoration: underline; text-decoration-color: #E8A23D; text-underline-offset: 2px; }

/* Scale view — unit-density flood (Task 3) */
.tcd-mx-scale-lead { font-size: 0.82rem; color: var(--text-secondary, #9aa); margin: 0 0 0.75rem; }
.tcd-mx-dotblock { margin-bottom: 1.25rem; }
.tcd-mx-blocklabel { margin: 0 0 0.4rem; font-size: 0.95rem; }
.tcd-mx-dots { display: flex; flex-wrap: wrap; gap: 2px; }
.tcd-mx-dot { width: 6px; height: 6px; border-radius: 50%; }
.tcd-mx-dot-flown { background: var(--text-secondary, #9aa); }
.tcd-mx-dot-mx { background: #E8A23D; }   /* amber — the established land-border color */
.tcd-mx-blocknum { margin: 0.4rem 0 0; font-weight: 600; }
.tcd-mx-scale-context { font-size: 0.78rem; color: var(--text-secondary, #9aa); line-height: 1.45; margin: 0.5rem 0 0; }

/* Journey view — chain-refoulement stages (Task 4) */
.tcd-mx-stage { position: relative; padding: 0 0 1rem 1.25rem; border-left: 2px solid #E8A23D; margin-left: 0.4rem; }
.tcd-mx-stage:last-child { border-left-color: transparent; }
.tcd-mx-stage-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; }
.tcd-mx-stage-num { display: inline-flex; align-items: center; justify-content: center; width: 1.4rem; height: 1.4rem; border-radius: 50%; background: #E8A23D; color: #1a1a1a; font-weight: 700; font-size: 0.8rem; margin-left: -1.95rem; }
.tcd-mx-stage-title { margin: 0; font-size: 0.95rem; }
.tcd-mx-corridor { display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; margin-bottom: 0.25rem; }
.tcd-mx-arrow { color: #E8A23D; }
.tcd-mx-sweep { font-size: 0.85rem; line-height: 1.5; margin: 0; }
.tcd-mx-qual { display: inline-block; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em; color: #1a1a1a; background: #E8A23D; padding: 0.1rem 0.4rem; border-radius: 3px; margin-bottom: 0.5rem; }
.tcd-mx-branch { margin-bottom: 0.5rem; }
.tcd-mx-branch-label { margin: 0 0 0.25rem; font-size: 0.85rem; font-weight: 600; }
.tcd-mx-branch-groups { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.tcd-mx-group { font-size: 0.75rem; border: 1px solid var(--border, #2a2a2a); border-radius: 999px; padding: 0.1rem 0.5rem; }

/* Near-daily cadence view (Task 5) */
.tcd-mx-cadence-lead { margin: 0 0 0.25rem; font-size: 0.95rem; }
.tcd-mx-cadence-note { margin: 0 0 0.75rem; font-size: 0.78rem; color: var(--text-secondary, #9aa); }
.tcd-mx-calgrid { display: grid; grid-template-columns: repeat(30, 1fr); gap: 3px; }
.tcd-mx-day { aspect-ratio: 1; background: #E8A23D; border-radius: 2px; opacity: 0.85; }
.tcd-mx-day-light { opacity: 0.25; }
.tcd-mx-day-story { background: #fff; outline: 2px solid #E8A23D; cursor: pointer; opacity: 1; }
.tcd-mx-day-story:hover, .tcd-mx-day-story:focus { outline-width: 3px; }
.tcd-mx-story-out { margin-top: 1rem; padding: 0.75rem; border: 1px solid #E8A23D; border-radius: 6px; background: rgba(232,162,61,0.08); }
.tcd-mx-story-label { margin: 0 0 0.4rem; font-size: 0.95rem; }
.tcd-mx-story-text { margin: 0 0 0.5rem; font-size: 0.85rem; line-height: 1.5; }
.tcd-mx-story-src { font-size: 0.78rem; color: var(--text-primary, #eee); text-decoration: underline; text-decoration-color: #E8A23D; }

/* --- Country-focused map: clickable country shapes (Phase 1) --- */
.tcd-country-dot {
  width: 13px; height: 13px; border-radius: 50%; padding: 0; cursor: pointer;
  background: #D9EF56; border: 1.5px solid rgba(0, 0, 0, 0.45);
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.25);
  transition: transform 0.12s ease;
}
.tcd-country-dot:hover { transform: scale(1.35); }
.tcd-country-dot:focus-visible { outline: none; transform: scale(1.35); box-shadow: 0 0 0 3px #D9EF56; }
@media (prefers-reduced-motion: reduce) { .tcd-country-dot { transition: none; } }
.tcd-country-cue {
  position: absolute; z-index: 6; pointer-events: none;
  transform: translate(-50%, calc(-100% - 10px));
  background: rgba(17, 19, 24, 0.94); color: #f4f6f8;
  font: 500 13px/1.3 Inter, system-ui, sans-serif;
  padding: 6px 10px; border-radius: 6px; max-width: 230px;
  border: 1px solid rgba(217, 239, 86, 0.4);
  opacity: 0; transition: opacity 0.14s ease;
}
.tcd-country-cue-show { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .tcd-country-cue { transition: none; } }

/* --- Country dossier (Phase 2) --- */
.tcd-cf-rank {
  display: inline-flex; align-items: baseline; gap: 0.45rem;
  margin: 0.15rem 0 0.7rem; padding: 0.3rem 0.7rem;
  background: color-mix(in srgb, #D9EF56 12%, transparent);
  border: 1px solid color-mix(in srgb, #D9EF56 32%, transparent);
  border-radius: 999px;
}
.tcd-cf-rank-n { font: 700 1.05rem/1 'Outfit', 'Inter', system-ui, sans-serif; color: #D9EF56; }
.tcd-cf-rank-lbl { font: 500 0.78rem/1.2 Inter, system-ui, sans-serif; color: var(--text-secondary, #9aa3b2); }
.tcd-cf-flights { margin: 0.5rem 0; border-top: 1px solid var(--border, #2a2f3a); padding-top: 0.5rem; }
.tcd-cf-flights > summary { cursor: pointer; font: 600 0.9rem/1.4 Inter, system-ui, sans-serif; list-style: none; }
.tcd-cf-flights > summary::-webkit-details-marker { display: none; }
.tcd-cf-flights-count::before { content: '▸ '; }
.tcd-cf-flights[open] .tcd-cf-flights-count::before { content: '▾ '; }
.tcd-cf-flights-sub { display: block; font-weight: 400; font-size: 0.78rem; color: var(--text-secondary, #9aa3b2); margin-top: 2px; }
.tcd-cf-flights-note { font-size: 0.74rem; color: var(--text-secondary, #9aa3b2); margin: 0.4rem 0; font-style: italic; }
.tcd-cf-flight-row { display: flex; flex-wrap: wrap; gap: 0.5rem; font-size: 0.8rem; padding: 0.3rem 0; border-top: 1px dotted var(--border, #2a2f3a); }
.tcd-cf-flight-date { font-variant-numeric: tabular-nums; min-width: 7rem; }
.tcd-cf-flight-carrier { color: var(--text-secondary, #9aa3b2); }
.tcd-cf-flight-src { margin-left: auto; color: var(--text-primary); text-decoration: underline; text-decoration-color: var(--accent, #D9EF56); }
.tcd-cf-coverage { margin: 0.5rem 0; border-top: 1px solid var(--border, #2a2f3a); padding-top: 0.5rem; }
.tcd-cf-coverage > summary { cursor: pointer; font: 600 0.9rem/1.4 Inter, system-ui, sans-serif; list-style: none; }
.tcd-cf-coverage > summary::-webkit-details-marker { display: none; }
.tcd-cf-coverage-count::before { content: '▸ '; }
.tcd-cf-coverage[open] .tcd-cf-coverage-count::before { content: '▾ '; }
.tcd-cf-coverage-link { display: block; font-size: 0.82rem; padding: 0.3rem 0; color: var(--text-primary); text-decoration: underline; text-decoration-color: var(--accent, #D9EF56); }
.tcd-cf-coverage-pub { display: block; font-size: 0.72rem; color: var(--text-secondary, #9aa3b2); text-decoration: none; }

/* ============================================================================
   Animated timeline-driven map — Features 1–5 (preview build)
   ============================================================================ */

/* Media markers: a single testimony point per place — photo for named on-record voices, silhouette
   for anonymized, plain dot otherwise. No pulsing ring, no count badge (per feedback). */
.tcd-person-pin-dot {
    position: absolute; inset: 6px; border-radius: 50%;
    background: var(--accent); border: 2px solid var(--tcd-bg, #1A1819);
    box-shadow: 0 2px 10px rgba(0,0,0,0.55); z-index: 2;
}
.tcd-person-pin--photo { width: 34px; height: 34px; }
.tcd-person-pin-photo {
    position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 50%;
    border: 2px solid #D9EF56; background: var(--tcd-surface, #222021);
    box-shadow: 0 2px 10px rgba(0,0,0,0.6); z-index: 2;
}

/* Feature 2 — size legend (overlay, bottom-left of the globe) */
.tcd-symbol-legend {
    position: absolute; left: 12px; bottom: 12px; z-index: 3; max-width: 250px;
    background: color-mix(in srgb, var(--tcd-surface, #222021) 90%, transparent);
    border: 1px solid var(--tcd-border, #3a3738); border-radius: 10px;
    padding: 9px 11px; color: var(--tcd-text, #F6F3EA); pointer-events: none;
    font-family: 'DM Sans', sans-serif;
}
/* Legend text bumped for on-map readability (was ~10px muted gray, hard to read over the basemap). */
.tcd-symbol-legend-title { font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: #c9c5bb; margin-bottom: 7px; }
/* concentric-ring (nested-circle) size legend */
.tcd-symbol-legend-rings { display: block; overflow: visible; }
.tcd-symbol-legend-ring-c { fill: none; stroke: color-mix(in srgb, #D9EF56 70%, transparent); stroke-width: 1; }
.tcd-symbol-legend-ring-lead { stroke: var(--tcd-textDim, #a09d94); stroke-width: 0.5; stroke-dasharray: 2 2; }
.tcd-symbol-legend-ring-lbl { fill: var(--tcd-text, #F6F3EA); font-family: 'DM Sans', sans-serif; font-size: 10px; dominant-baseline: middle; }
.tcd-symbol-legend-foot { margin-top: 8px; font-size: 0.66rem; color: #c9c5bb; line-height: 1.35; }

/* Feature 3 — light country card (side panel over the globe) */
.tcd-timeline-card {
    position: absolute; top: 12px; right: 12px; z-index: 4; width: 300px; max-width: calc(100% - 24px);
    max-height: calc(100% - 24px); overflow-y: auto;
    background: var(--tcd-surface, #222021); color: var(--tcd-text, #F6F3EA);
    border: 1px solid var(--tcd-border, #3a3738); border-radius: 12px;
    padding: 14px 15px; box-shadow: 0 14px 40px rgba(0,0,0,0.55);
    font-family: 'DM Sans', sans-serif;
    transform: translateX(8px); opacity: 0; transition: opacity 0.16s ease, transform 0.16s ease;
}
.tcd-timeline-card.tcd-tlcard-open { transform: translateX(0); opacity: 1; }
.tcd-timeline-card[hidden] { display: none; }
.tcd-tlcard-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.tcd-tlcard-name { margin: 0; font-family: 'Outfit', 'Century Gothic', sans-serif; font-size: 1.15rem; font-weight: 700; }
.tcd-tlcard-close { flex: none; border: none; background: transparent; color: var(--tcd-textDim, #a09d94); font-size: 1.4rem; line-height: 1; cursor: pointer; padding: 0 2px; }
.tcd-tlcard-close:hover { color: var(--tcd-text, #F6F3EA); }
.tcd-tlcard-facts { margin: 10px 0; }
.tcd-tlcard-facts dt { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--tcd-textDim, #a09d94); }
.tcd-tlcard-facts dd { margin: 0 0 8px; font-size: 0.92rem; font-weight: 600; }
.tcd-tlcard-section-label { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--tcd-textDim, #a09d94); margin-bottom: 5px; }
.tcd-tlcard-flights { margin: 6px 0 10px; }
.tcd-tlcard-flights-svg { width: 100%; height: auto; display: block; }
.tcd-tlcard-axis { stroke: var(--tcd-border, #3a3738); stroke-width: 1; }
.tcd-tlcard-plane { fill: #7d94f5; }
.tcd-tlcard-axis-row { display: flex; justify-content: space-between; font-size: 0.55rem; color: var(--tcd-textDim, #a09d94); }
.tcd-tlcard-natline { font-size: 0.84rem; line-height: 1.4; color: var(--tcd-text, #F6F3EA); margin: 4px 0 12px; }
.tcd-tlcard-natline-gap { font-style: italic; opacity: 0.75; }
.tcd-tlcard-media { margin: 6px 0; }
.tcd-tlcard-media-note { font-size: 0.8rem; color: var(--tcd-textDim, #a09d94); margin: 0; }
.tcd-tlcard-fullbtn {
    display: inline-block; margin: 4px 0 2px; padding: 7px 12px; border-radius: 8px;
    background: color-mix(in srgb, #D9EF56 16%, transparent); border: 1px solid color-mix(in srgb, #D9EF56 55%, var(--tcd-border, #3a3738));
    color: var(--tcd-text, #F6F3EA); font-family: 'DM Sans', sans-serif; font-weight: 600; font-size: 0.82rem; cursor: pointer;
}
.tcd-tlcard-fullbtn:hover { background: color-mix(in srgb, #D9EF56 28%, transparent); }
.tcd-tlcard-more { font-size: 0.7rem; color: var(--tcd-textDim, #a09d94); margin: 8px 0 0; font-style: italic; }
.tcd-tlcard-empty { font-size: 0.82rem; color: var(--tcd-textDim, #a09d94); }

/* New static-legend swatch (replaces the retired corridor-line legend item) */
.tcd-legend-swatch { display: inline-block; width: 13px; height: 13px; border-radius: 3px; background: color-mix(in srgb, #3F7E86 58%, transparent); border: 1px solid #3F7E86; vertical-align: middle; }
.tcd-legend-outline { display: inline-block; width: 14px; height: 10px; border: 1.5px dashed #EDE8DA; opacity: 0.75; border-radius: 2px; }

@media (prefers-reduced-motion: reduce) { .tcd-timeline-card { transition: none; } }
@media (max-width: 600px) {
    .tcd-timeline-card { position: static; width: auto; max-height: none; margin: 0.6rem 0 0; transform: none; opacity: 1; }
    .tcd-symbol-legend { left: 8px; bottom: 8px; max-width: 180px; padding: 7px 9px; }
}


/* ===== Round-3 feedback: date readout, layers, scrubber bands, back button, tip fix ===== */

/* status hover tooltip must respect [hidden] (CSS display was overriding it → empty box on load) */
.tcd-status-tip[hidden] { display: none !important; }

/* Month/year readout, top-LEFT of the map, auto-sized to its text (unique class so it doesn't
   inherit the core engine's .tcd-date-readout box styling). Steps with the animation. */
.tcd-tl-date {
    position: absolute; top: 10px; left: 12px; z-index: 6; pointer-events: none;
    width: auto; height: auto; display: inline-block;
    background: rgba(26, 24, 25, 0.55); border: 1px solid rgba(246, 243, 234, 0.12);
    border-radius: 8px; padding: 6px 11px 7px;
    text-shadow: 0 2px 12px rgba(0,0,0,0.85), 0 0 2px rgba(0,0,0,0.9);
}
.tcd-tl-date-month { display: block; font-family: 'Outfit', 'Century Gothic', sans-serif; font-weight: 700;
    font-size: clamp(1.05rem, 2.7vw, 1.6rem); line-height: 1; color: #F6F3EA; letter-spacing: -0.01em;
    margin-bottom: 5px; }
.tcd-tl-date-year { display: block; font-family: 'Outfit', 'Century Gothic', sans-serif; font-weight: 600;
    font-size: clamp(0.72rem, 1.8vw, 1rem); line-height: 1; color: #D9EF56; }

/* Layers control (Agreements / Voices / Detention centers) */
.tcd-layers { display: inline-flex; align-items: center; gap: 12px; margin-left: 10px; flex-wrap: wrap; }
.tcd-layers-title { font-family: 'DM Sans', sans-serif; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--tcd-textDim, #a09d94); }
.tcd-layer-toggle { display: inline-flex; align-items: center; gap: 5px; font-family: 'DM Sans', sans-serif; font-size: 0.82rem; color: var(--tcd-text, #F6F3EA); cursor: pointer; }
.tcd-layer-toggle input { accent-color: #D9EF56; cursor: pointer; }
/* Voices layer toggle hides the testimony markers */
#tcd-globe.tcd-hide-voices .tcd-person-marker,
#tcd-globe.tcd-hide-voices .tcd-voice-cue { display: none !important; }

/* Voice cues — the quiet human-presence layer (2026-07). ::after tooltip, not title= (mobile/delay). */
.tcd-voice-cue {
    width: 18px; height: 18px; border-radius: 50%; border: 1px solid rgba(237,232,218,0.5);
    background: rgba(26,24,25,0.72); color: #EDE8DA; cursor: pointer; padding: 0;
    display: inline-flex; align-items: center; justify-content: center; position: relative;
}
.tcd-voice-cue-glyph { font-size: 10px; line-height: 1; transform: translateY(-1px); }
.tcd-voice-cue:hover::after, .tcd-voice-cue:focus-visible::after {
    content: attr(data-tip); position: absolute; bottom: 130%; left: 50%; transform: translateX(-50%);
    width: max-content; max-width: 220px; padding: 0.3rem 0.55rem; border-radius: 4px;
    background: rgba(26,24,25,0.95); color: #EDE8DA; font: 11px/1.35 'Inter', sans-serif; z-index: 5;
}

/* "volume by country" stacked region bands in the scrubber timeline */
.tcd-scrubber-band { stroke: none; }

/* Back button on the full country-file profile */
.tcd-cf-back {
    display: inline-flex; align-items: center; gap: 5px; margin: 0 0 8px; padding: 6px 11px; border-radius: 8px;
    background: var(--tcd-surface, #222021); border: 1px solid var(--tcd-border, #3a3738);
    color: var(--tcd-text, #F6F3EA); font-family: 'DM Sans', sans-serif; font-weight: 600; font-size: 0.8rem; cursor: pointer;
}
.tcd-cf-back:hover { border-color: color-mix(in srgb, #D9EF56 55%, var(--tcd-border, #3a3738)); }

/* Round 4: remove the "Explore the system" / "Hear the voices" door links above the map
   (both masthead variants). Play-the-story is kept. */
#third-country .tcd-door,
#third-country .tcd-human-secondary { display: none !important; }

/* Round 5: hide the core engine's empty flight-counter overlay (renderFlights:false → empty box) */
#tcd-globe .tcd-counters { display: none !important; }
/* Narrower symbol legend (Mexico foot text shortened in JS too) */
#tcd-symbol-legend { max-width: 200px; }
.tcd-symbol-legend-foot { font-size: 0.62rem; }
/* Strange Routes: breathing room between the title/explainer and the left container edge */
#tcd-transit { padding: 4px 8px 8px 20px; }
#tcd-transit .tcd-view-title, #tcd-transit .tcd-view-sub, #tcd-transit > p, #tcd-transit > h2, #tcd-transit > h3 { padding-left: 6px; }

/* ============================================================
   Answer Map — 3rd Country tab hero (spec 2026-07-12, v3 composition)
   Quiet by default: destinations only at rest; selection flies the
   camera in, fades the uninvolved world, and reveals the network.
   ============================================================ */
/* L5 (T5.3): --tcd-am-border darkened #78746c→#8b8479 so the 0.9px country
   outline clears 3:1 non-text contrast on both fills — 4.00:1 vs land
   (--bg-card) and 4.77:1 vs ocean (--bg-primary), up from a thin 3.18/3.80. */
/* Round2 (2026-07-27): --tcd-am-target (blue, the SELECTED "deported to" country — the
   same muted-blue family as --tcd-am-dest's disc, so the shaded land visually belongs to
   the same actor) is new; --tcd-am-home (amber, the ORIGIN "home" countries) is the value
   --tcd-am-target inherits (both classes used to share one shade — indistinguishable). */
/* Round3 (2026-07-27): --tcd-am-home brightened ~30% (L 41.8%→54.3%, #a17b34→#c69d4f) so
   the shaded origin countries read as a vivid warm gold instead of a dull brown, while
   staying the same hue (39°) so it's still legible as "the amber one" vs. the blue target.
   --tcd-am-muted aliases --text-tertiary (an existing warm-neutral token, not a new hue) for
   the de-emphasized "other countries' dots" treatment below — it already carries a similar
   contrast weight against the land fill as --tcd-am-dest does, so muted dots read as
   present-but-quiet rather than invisible, and the alias flips for free under the light
   theme (--text-tertiary is redeclared there; .tcd-answer-map never shadows it). */
/* R4/P3a (2026-07-28), second brightening pass: --tcd-am-target gains L +21% (#4a5578→#495ea2).
   Its ceiling is real — clearing 3:1 vs land needs ~#6071a9, at which point the selected
   country's own border stops reading against its fill, so #495ea2 is the compromise (contrast
   vs land still improves 19%). --tcd-am-home gains S +37% (#c69d4f→#dda640), not lightness —
   the Round3 lesson holds a second time. White-label-on-amber contrast (already sub-3:1 at
   2.27:1) drops further to 1.97:1; pre-existing condition, reported not silently fixed. */
/* R4/P3c (2026-07-28): the *-ink pair is the TYPE half of the palette. The fill tokens above are
   tuned to be read as areas behind other things; as small type they fail — on paper
   --tcd-am-home (#e19209) is 2.14:1 against the land fill (#efece3) and 2.38:1 against the
   newsprint background (#faf8f3); --tcd-am-target (#7d93d4) is 2.54:1 and 2.83:1 on the same two
   surfaces. The inks are the same two hues at type weight, and they are used in exactly two
   places: the on-map role kickers and the US place label, so the word and the mark that explains
   it are literally the same colour. (A third — the header sentence — was deleted in R5 §5.1; the
   key box that replaced it keys the FILL tokens, not these.) Light overrides --tcd-am-home-ink
   further down to #806410, the deep gold this stylesheet already uses for status text.
   R4 fix wave (2026-07-28): the DARK theme needs its own amber ink after all. It used to alias
   --tcd-am-home, which IS the country fill it prints on — 1.00:1, with nothing but the 3px
   paint-order halo between word and country, and at 8px that halo closed the counters so the
   word read as a dark smudge (captured at deviceScaleFactor 1, not at 2x). No amber can clear
   3:1 against BOTH #dda640 and the near-black ground, so the fix is a lifted gold that is
   plainly brighter than the fill (#f3d18c, 1.49:1 vs the fill, 12.04:1 vs the ground — up from
   1.00:1 and 8.08:1) read through a thinner 2px halo at 9px — see .tcd-am-kicker below. */
.tcd-answer-map { --tcd-am-dest: #7d94f5; --tcd-am-border: #8b8479; --tcd-am-target: #495ea2; --tcd-am-home: #dda640; --tcd-am-corridor: #d9ef56; --tcd-am-layover: #40dd81; --tcd-am-muted: var(--text-tertiary); --tcd-am-target-ink: var(--tcd-am-dest); --tcd-am-home-ink: #f3d18c; padding: 0 0 12px; }
/* 2026-09-19 feedback (item 10): Forbidden Stories' own brand palette for their embed of this map
   (third-country/answer-map-embed.html, detected there via document.referrer / ?palette=), red
   for receiving countries and blue for countries of origin. Overrides ONLY the two fill tokens
   the roles are named for — --tcd-am-dest (the disc/key-ring colour, also "receiving") and
   --tcd-am-target (the shaded selected-country fill) go red; --tcd-am-home (the shaded origin
   countries) goes blue. Deliberately leaves --tcd-am-target-ink/--tcd-am-home-ink alone: those
   are the on-map TEXT colour for the role kickers and the US label, read against the general map
   background, not against these two fills, so this file's own hard-won contrast tuning for them
   (R4/P3c above) is untouched. Two classes on one element outweighs the base rule's one, so this
   wins regardless of source order; kept directly below it for the same reason .tcd-am-photo-pair
   sits below .tcd-am-media-track.is-multi .tcd-am-photo. */
.tcd-answer-map.tcd-am-palette-fs { --tcd-am-dest: #d62c43; --tcd-am-target: #d62c43; --tcd-am-home: #22305b;
  /* --tcd-am-target-ink is declared in the base rule as var(--tcd-am-dest) — an ALIAS, not its
     own value — so overriding --tcd-am-dest above would silently turn the on-map role-kicker
     TEXT red too (caught by tests/tcn-embed-palette.spec.cjs, not by inspection). Break the
     alias here, back to --tcd-am-dest's original literal, so the ink stays exactly as tuned. */
  --tcd-am-target-ink: #7d94f5; }
.tcd-am-head { display: flex; align-items: flex-end; justify-content: space-between;
  gap: 18px; flex-wrap: wrap; padding: 18px 18px 10px; }
.tcd-am-title { font-size: 1.5rem; margin: 0 0 4px; }
.tcd-am-standfirst { max-width: 60ch; color: var(--text-secondary); margin: 0; }
.tcd-am-standfirst strong { color: var(--text-primary); }
.tcd-am-searchwrap { position: relative; flex: 0 1 300px; }
.tcd-am-search { width: 100%; background: var(--bg-card); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: 6px; padding: 7px 12px; font-size: 0.9rem; font-family: inherit; }
.tcd-am-results { position: absolute; right: 0; z-index: 40; list-style: none; margin: 4px 0 0; padding: 4px;
  width: max(100%, 340px); background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 6px; box-shadow: 0 6px 18px rgba(0,0,0,0.3); }
.tcd-am-result { display: block; width: 100%; text-align: left; background: none; border: none;
  color: var(--text-secondary); cursor: pointer; padding: 6px 8px; border-radius: 4px; font-size: 0.85rem; font-family: inherit; }
.tcd-am-result:hover, .tcd-am-result:focus-visible { background: rgba(125, 148, 245, 0.14); }
.tcd-am-result strong { color: var(--text-primary); }

/* F2: the mapwrap is the OUTER positioning context only — it carries the horizontal inset
   (so the tooltip/dossier that hang off it line up with the framed map) but never clips, so
   those overlays can extend past the frame edge. The rounded, clipping frame is the inner
   .tcd-am-neatline. */
.tcd-am-mapwrap { position: relative; padding: 0 0 6px; margin: 0 12px; }
.tcd-am-svg { display: block; width: 100%; height: auto; cursor: grab; }
.tcd-am-svg:active { cursor: grabbing; }
/* C6: darker, warmer border so country outlines read at 375px (width set in answer-map.js) */
.tcd-am-country { fill: var(--bg-card); stroke: var(--tcd-am-border); }
/* Selected ("deported to") country vs. its origin ("home") countries shaded on selection
   (replaces relationship arcs) — different hues so the two roles read apart at a glance:
   target = blue (relates to the disc), home = amber. */
/* R4/P3b: stroke-width deliberately absent. These paths must inherit the counter-scaled
   value the zoom handler writes onto the parent gLand group (0.9 / k) — a declaration here
   would beat that inherited presentation attribute and leave shaded countries at a fixed
   0.9 while every other country thins out, which on a small island is most of its area. */
.tcd-am-country.target { fill: var(--tcd-am-target); stroke: var(--tcd-am-border); }
.tcd-am-country.home { fill: var(--tcd-am-home); stroke: var(--tcd-am-border); }
/* --- Disputed boundaries (2026-08-05 editorial round) ---------------------------------------
   Three of the four fixes in that round were SUBTRACTIONS made in the geometry itself: Somaliland
   folded into Somalia, Crimea moved from Russia to Ukraine, Western Sahara folded into Morocco.
   Absorbing a feature by polygon union leaves no seam, so there is nothing here to un-stroke —
   the lines are gone because the edges are gone. What remains are the two overlays below.
   Like .tcd-am-country, they carry NO stroke-width: the zoom handler writes the counter-scaled
   value onto the parent .tcd-am-disputed group, and a declaration here would beat it. */
.tcd-am-disputed { fill: none; }
/* Morocco / Western Sahara, at 27°40'N. The only border this round ADDS: the source data drew
   the Moroccan berm as Morocco's southern edge and had no line at the international boundary at
   all. Dotted, in the map's own border colour — a mid warm gray already tuned (L5) to read
   against BOTH the dark-theme --bg-card land and the light-theme paper land, and dark enough to
   hold when Morocco is shaded amber. Round caps so short dashes read as dots, not ticks; the
   dash rhythm itself is set in JS so it survives zoom. */
.tcd-am-disputed-line { stroke: var(--tcd-am-border); stroke-linecap: round; }
/* Areas of Ukraine under Russian control. Hatching over the country's own amber, never a
   separate fill: the reader should see one country, textured, rather than two countries.
   display:none in the rest state because SVG does not reliably honour the hidden attribute.
   pointer-events:none is load-bearing, not hygiene — this path sits ABOVE the country fills, and
   the delegated hover/pivot-click handlers read data-shade-country off evt.target. Without it,
   hovering occupied Ukraine would hit the hatch instead of the country and silently kill both
   the tooltip and the click-to-pivot on roughly a fifth of Ukraine's area. */
.tcd-am-occupied { stroke: none; pointer-events: none; display: none; }
.tcd-am-occupied.is-shown { display: inline; }
.tcd-am-hatch-line { stroke: rgba(30, 25, 14, 0.6); stroke-width: 1.15; }
/* Solid line on the assessed front line — the western limit of the hatch (2026-08-11 client
   request). The hatch's own ink, darker, so it reads as the edge of the texture rather than a
   third colour; it is only ever drawn over Ukraine's amber, where that ink is already proven
   legible in both themes. NO stroke-width — the zoom handler writes the counter-scaled value
   onto the parent .tcd-am-disputed group, same contract as .tcd-am-disputed-line. Round joins
   because a zigzag front line at a visible weight grows miter spikes without them. pointer-
   events:none for the same reason as the hatch: it sits above the country fills and must not
   eat the delegated hover/pivot-click. Shown/hidden with the hatch, by the same class. */
.tcd-am-frontline { fill: none; stroke: rgba(30, 25, 14, 0.8); stroke-linecap: round;
  stroke-linejoin: round; pointer-events: none; display: none; }
.tcd-am-frontline.is-shown { display: inline; }
/* Western Sahara (2026-09-16 feedback, reversing 09-15's "always visible"): the hatch now
   shows only while Morocco is the highlighted country — same shown/hidden contract as
   .tcd-am-occupied. When Morocco is not highlighted the territory reads exactly as it did
   before the hatch existed: the dotted boundary at 27°40'N (wsLine, drawn separately, always
   on) with no fill. No stroke of its own regardless of state, for the same reason as before. */
.tcd-am-wsahara-hatch { stroke: none; pointer-events: none; display: none; }
.tcd-am-wsahara-hatch.is-shown { display: inline; }
/* Kashmir's three administered zones (2026-09-16 feedback, splitting 09-15's single path):
   the dotted outline is now its OWN always-visible path (tcd-am-kashmir-line, styled exactly
   like .tcd-am-disputed-line above) and the hatch fill is a SEPARATE, selection-gated path
   (tcd-am-kashmir-hatch, same shown/hidden contract as .tcd-am-occupied) drawn on top of it —
   the desk asked to keep the line always-on while gating the hatch, which one path carrying
   both a permanent stroke and a toggled fill cannot do. Both are safe as separate elements
   because these zones are entirely inland, unlike Ukraine's coastline-adjacent occupied area,
   so there's no risk of the line's own stroke re-inking a border or coastline the base map
   already draws. pointer-events:none on the hatch only — the line has no fill to intercept a
   click through, but the hatch sits above the country fill and must not eat the delegated
   hover/pivot-click. */
.tcd-am-kashmir-line { stroke: var(--tcd-am-border); stroke-linecap: round; fill: none; }
.tcd-am-kashmir-hatch { stroke: none; pointer-events: none; display: none; }
.tcd-am-kashmir-hatch.is-shown { display: inline; }
.tcd-am-disc { fill: var(--tcd-am-dest); fill-opacity: 0.78; stroke: var(--tcd-am-dest); stroke-width: 1.2; }
.tcd-am-disc.hollow { fill: transparent; }
/* .tcd-am-disc-undated tags a declared total (total_TCN) with no per-flight ledger behind it —
   Guatemala, Ecuador, Bhutan. It paints exactly like any destination disc: round 2 (2026-09-12)
   gave it a dashed stroke and a faded fill, and the desk asked for the dashes gone on 2026-09-13.
   The card still says "documented total; no flight-by-flight record". Not .hollow either (that
   means no PUBLIC count; these have one). The tag stays for the hit-target split below. */
/* 2026-09-12 round 2 (found regression-testing the above): Guatemala's true-scale disc (r≈50,
   off 2,981 declared) is drawn at the SAME SIZE a genuine flight destination that large would
   be — and in this map's most geographically dense cluster (Central America), that swallowed
   Belize's country-polygon hover target and Panama's own disc underneath it. The decorative
   disc stops intercepting the pointer entirely (see the higher-specificity override paired
   with .tcd-am-mark circle below — a plain .tcd-am-disc-undated rule here loses to it
   silently, at equal source order); a small invisible circle at the ordinary small-mark
   footprint (hitR in the JS, not r) does the actual hit-testing, painted after it so it
   always wins at its own point. See the layover badge split above for the same idea run the
   other way (there the small shape is the extra target; here it's the whole target). */
.tcd-am-undated-hit { fill: transparent; pointer-events: all; }
/* R4/P1 (2026-07-28): "United States" is rest-state orientation — once a flight/land
   country is selected the dossier already answers "sent from US custody", so the place
   label used to be hidden on selection as redundant clutter next to the lit network.
   The rotated custody diamond and its "US CUSTODY" kicker that used to live here are
   gone; .tcd-am-usmark now wraps the single .tcd-am-country-label text node.
   2026-09-08 (spec §9): the US label no longer disappears under a selection. Two reasons.
   The package index has a UNITED STATES gutter row that highlights this mark on hover, and
   a display:none mark cannot be pointed at. And editorially the old rule said the opposite
   of the tab's position: the US is the party doing this, and it was the one element that
   vanished the moment a reader examined anything it did. Muted, not removed — present
   without competing with the lit network. */
.tcd-answer-map.has-selection .tcd-am-usmark { opacity: 0.45; }
/* Fix round 1 (2026-09-08, ruling): a lit US mark must escape the selection dim. The 0.45
   above is on the GROUP, and opacity composites through ancestors -- brightening the child
   label alone (see .tcd-am-usmark.is-lit .tcd-am-country-label below) cannot undo it, so the
   override has to land on .tcd-am-usmark itself. Specificity (0,4,0) beats the 0.45 rule's
   (0,3,0) regardless of source order. */
.tcd-answer-map.has-selection .tcd-am-usmark.is-lit { opacity: 1; }
/* R4/P2: Mexico now speaks the map's own two-colour grammar — blue = sent to. Its
   fill/stroke used to be hardcoded presentation attributes in JS, which is why it
   never flipped with the theme. (The US label's amber override rule lives further
   down, right after the base C7 label rule — deliberately, so it stays the second
   match for any lookup keyed on that base selector's opening brace.) */
/* 2026-09-12 — Mexico's land corridor. The 9x9 .tcd-am-land-marker square is retired: Mexico is
   drawn as the US–Mexico border (gCorridor in js/third-country-answer-map.js), which has no area and
   so never joins the flight-count size scale. Two rules carry over from the square:
   - the --bg-primary fallback stays literal (answer-map-embed.html links only this stylesheet, so
     on the dark embed var(--bg-primary) alone is invalid at computed-value time), now on the ticks;
   - one country, one mark: where a selection lights Mexico's own polygon, the line stands down,
     exactly as the square and every lit disc do. */
.tcd-am-corridor { cursor: pointer; transition: opacity 300ms ease; }
.tcd-am-corridor path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
/* The hit stroke sets its own pointer-events, which is why .dimmed must restate none on it below:
   a child's explicit value is never overridden by the group's inherited one. */
.tcd-am-corridor-hit { stroke: transparent; pointer-events: stroke; }
.tcd-am-corridor-halo { stroke: var(--tcd-am-corridor); stroke-opacity: 0.16; pointer-events: none; }
.tcd-am-corridor-line { stroke: var(--tcd-am-corridor); pointer-events: none; }
.tcd-am-corridor-tick circle { fill: var(--bg-primary, #1A1819); stroke: var(--tcd-am-corridor);
  stroke-width: 1.2; pointer-events: none; }
/* Hover and keyboard focus light the halo in the map's selection hue — the corridor's focus ring. */
.tcd-am-corridor.is-hover .tcd-am-corridor-halo,
.tcd-am-corridor.is-focus .tcd-am-corridor-halo { stroke: var(--tcd-am-dest); stroke-opacity: 0.55; }
.tcd-answer-map.has-selection .tcd-am-corridor.lit { display: none; }
.tcd-am-corridor.dimmed { opacity: 0.12; pointer-events: none; }
.tcd-am-corridor.dimmed .tcd-am-corridor-hit { pointer-events: none; }
.tcd-am-land-hit { fill: transparent; }
/* Mexico's mark paints nothing but that invisible hit circle, so its outline would be a small empty
   box beside the word "Mexico". The corridor halo above is the indicator instead. (0,3,0) so it beats
   .tcd-am-mark:focus-visible / :hover regardless of source order. */
.tcd-am-mark.tcd-am-landmark:focus, .tcd-am-mark.tcd-am-landmark:focus-visible,
.tcd-am-mark.tcd-am-landmark:hover, .tcd-am-mark.tcd-am-landmark.tcd-am-hover { outline: none; }
/* The key row: a plain line under the switches, not a control. */
.tcd-am-key-note { display: flex; align-items: flex-start; gap: 7px; margin: 10px 0 0; padding-top: 8px;
  border-top: 1px solid var(--border); font-size: 0.8rem; line-height: 1.3; color: var(--text-secondary); }
.tcd-am-panel-note { display: flex; align-items: flex-start; gap: 7px; font-size: 0.85rem; line-height: 1.35;
  color: var(--text-primary); }
.tcd-am-key-corridor-glyph { flex: 0 0 auto; overflow: visible; margin-top: 2px; }
.tcd-am-key-corridor-glyph path { fill: none; stroke: var(--tcd-am-corridor); stroke-linecap: round;
  stroke-linejoin: round; }
.tcd-am-mark { cursor: pointer; outline-offset: 3px; }
.tcd-am-mark circle { pointer-events: all; } /* hollow discs must catch clicks in their interior */
/* 2026-09-12 round 2: the rule above (0,2,0 specificity) otherwise beats a plain
   .tcd-am-disc-undated { pointer-events: none } (0,1,0) regardless of source order — found
   as a silent no-op when the fix above still failed the exact same hover/click regression it
   was meant to close. .tcd-am-mark circle.tcd-am-disc-undated (0,3,0) wins unambiguously. */
.tcd-am-mark circle.tcd-am-disc-undated { pointer-events: none; }
.tcd-am-mark:focus-visible { outline: 2px solid var(--tcd-am-dest); }
/* 2026-09-12 feedback: the hover tooltip now only names the country (tipShow() call
   sites), so hovering needs its own quiet "this is what you're about to click" signal —
   a small highlight around the point, mirroring the keyboard focus ring above.
   .tcd-am-hover is set from JS for the one path with no native hover target of its own:
   an ORIGIN LAYER shaded land polygon, at rest, is a different element than its point
   mark, so gLand's mousemove handler toggles the class directly. */
.tcd-am-mark:hover, .tcd-am-mark.tcd-am-hover { outline: 2px solid var(--tcd-am-dest); }
/* Round2 (2026-07-27): the selected mark already reads as "selected" via the thicker
   disc stroke below — the rectangular focus-ring bbox on top of a big disc just
   looked like a stray box. Suppress it on the selected mark only; every other mark
   (including the one keyboard focus lands on next) keeps the ring for a11y (T5.2).
   R4/P4 re-scoped along the INPUT MODALITY, not along the country:
   - pointer focus (`:focus:not(:focus-visible)`) is suppressed on every selected mark. This
     is what the Round2 rule was really for. Chromium paints its UA `outline: auto 5px
     -webkit-focus-ring-color` on plain :focus even when :focus-visible is false, so without
     this line a click on any of the 22 shape-having destinations (24 destinations, less Palau
     and St. Kitts and Nevis, which have no Natural Earth 110m polygon) leaves a light-blue rounded
     box around the country NAME until the user clicks elsewhere — the same "stray box" look,
     now boxing a label. (`auto` is NOT inert; measured on this branch.)
   - keyboard focus keeps the 2px ring from .tcd-am-mark:focus-visible above, because the
     selected mark now paints only its name — suppressing it would leave a tabindex="0" stop
     with no focus indicator at all (WCAG 2.4.7).
   - the disc-KEEPING microstates (.tcd-am-nopoly) still suppress even the keyboard ring:
     they have a big disc that already reads as "selected", which is the case the original
     Round2 note was describing. */
.tcd-am-mark.selected:focus:not(:focus-visible) { outline: none; }
.tcd-am-mark.selected.tcd-am-nopoly:focus-visible { outline: none; }
.tcd-am-mark, .tcd-am-arcs path { transition: opacity 300ms ease; }
.tcd-am-mark.dimmed { opacity: 0.12; pointer-events: none; }
/* Fix round 1 (2026-09-08, ruling): the identical trap already fixed for the US mark at
   :1792, unfixed here for the other 99 destinations. The 0.12 above is on the GROUP
   (.tcd-am-mark.dimmed) while .is-lit .tcd-am-disc (below) only raises fill-opacity on the
   CHILD disc — opacity composites through ancestors, so a child cannot escape a dim its own
   ancestor group carries. The override has to land on .tcd-am-mark itself, same as the US
   mark's. pointer-events is re-enabled too: .dimmed sets none, and a lit-but-dimmed mark
   must still be clickable/hoverable like any other live mark. */
.tcd-answer-map.has-selection .tcd-am-mark.dimmed.is-lit { opacity: 1; pointer-events: auto; }
/* 2026-09-15 feedback ("a dotted circle often showing up around Central America" / "on Ecuador
   and the Dominican Republic"): the standard 0.12 dimming above reads as near-invisible on an
   ordinary disc, but Guatemala's undated-total disc is r≈50 — by far the largest mark on the
   map (see .tcd-am-disc-undated's own comment) — so even at 12% opacity it still shows as a
   pale halo sprawled across whichever neighbours happen to be on screen. This is Central
   America's isthmus cluster (2026-09-13) opening because at least one of its OTHER members is
   a real, ledger-documented partner of the current selection (Paraguay's real partners include
   Costa Rica, El Salvador and Honduras) — the cluster correctly un-collapses, but Guatemala
   rides along dimmed and, because of its outsized area, is still visible where a normal-size
   dimmed disc would not be. Composites with the 0.12 above (opacity multiplies through
   ancestors), landing an irrelevant Guatemala under 1% — the shape is still technically present
   (never literally hidden, matching how every other dimmed mark degrades) but no longer reads
   as a circle "showing up" on top of unrelated countries. A LIT Guatemala (:not(.is-lit)
   excludes it) keeps its full, truthful, proportional size and opacity — this only mutes the
   irrelevant case. */
.tcd-am-mark.tcd-am-undatedmark.dimmed:not(.is-lit) circle.tcd-am-disc-undated { opacity: 0.08; }
/* C8: softer selection ring — a refined outline, not a heavy box */
.tcd-am-mark.selected .tcd-am-disc { stroke: var(--text-primary); stroke-width: 1.5; }
/* A mark lit from the package index's gutter (Task 7) — a highlight, not a selection. */
.tcd-am-mark.is-lit .tcd-am-disc { fill-opacity: 1; stroke-width: 2.4; }
.tcd-am-usmark.is-lit .tcd-am-country-label { opacity: 1; }
/* R4/P4: the selected country is identified by its blue COUNTRY FILL, not by a disc on top
   of it — one country, one signal. Hidden rather than never-drawn so the mark's radius (and
   therefore resetLabels()' at-rest label offset) is unchanged when the selection clears.
   The :not(.tcd-am-nopoly) guard is load-bearing: Palau and St. Kitts and Nevis have no
   Natural Earth 110m polygon, so they have no fill to inherit the job and would otherwise
   vanish entirely on selection. A country is marked ONCE — filled if it has a shape, disced
   if not. */
/* R4 fix wave: scoped to .lit, not .selected. A country that is BOTH a destination in its own
   right and a country of origin for the current selection kept its full disc painted on
   top of its amber fill — measured, 21 of them across the sweep, reading as a target reticle
   drawn over an origin (Ghana under an Equatorial Guinea selection; Cameroon, DR Congo,
   Uzbekistan, Guatemala and Honduras under Costa Rica). "A country is marked ONCE" is a rule
   about the country, not about which one you clicked. The :not(.tcd-am-nopoly) guard is
   unchanged and still load-bearing: Palau and St. Kitts and Nevis have no fill to inherit the
   job. Marks that are neither lit nor selected are unaffected (they are .dimmed to 0.12). */
.tcd-answer-map.has-selection .tcd-am-mark.lit:not(.tcd-am-nopoly) .tcd-am-disc { display: none; }
/* 2026-09-14 feedback round 2: the same rule, extended to the layover triangle. Egypt is both
   a standalone transit stop (Israel's layover) AND a real, documented origin for Central
   African Republic and Equatorial Guinea — selecting either of those lit Egypt amber via its
   country fill (correct) while its own green triangle stayed at full opacity on top of it
   (the .dimmed.is-lit override above does not distinguish disc from triangle), reading as an
   unwanted second marker. "A country is marked ONCE" applies here exactly as it does to the
   disc: the amber fill is the signal, the triangle is redundant on top of it. Does not affect
   Egypt selected DIRECTLY (its transit-view click) — that path never sets .lit at all (see
   state.transitView in renderSelection/placeSelectionLabels), only .selected, which this
   selector does not match. */
.tcd-answer-map.has-selection .tcd-am-mark.lit:not(.tcd-am-nopoly) .tcd-am-layover { display: none; }
/* Round3 (2026-07-27, feedback: "which country is blue?" reads ambiguous once every
   destination disc is the same blue): once a country is selected, every OTHER country's
   disc goes to the muted neutral so the SELECTED disc is the only blue left on
   the map — the amber .tcd-am-country.home shading (above) carries the origin story
   instead. Covers lit (origin) marks too, not just dimmed ones, so an origin country that
   also happens to be its own destination elsewhere doesn't compete with the selected blue. */
.tcd-answer-map.has-selection .tcd-am-mark:not(.selected) .tcd-am-disc {
  fill: var(--tcd-am-muted); stroke: var(--tcd-am-muted);
}
/* .hollow (count-not-public discs, e.g. Honduras/Liberia/Qatar) must stay transparent —
   only its ring stroke goes muted, never a solid grey fill. Higher specificity than the
   rule above so it wins without disturbing the shared stroke declaration. */
.tcd-answer-map.has-selection .tcd-am-mark:not(.selected) .tcd-am-disc.hollow {
  fill: transparent;
}

/* country names live inside the marks; disclosure by state and by scale.
   Round3 (2026-07-27, feedback: labels collide with dots and become unreadable —
   Costa Rica's "C" sat on a blue dot, Equatorial Guinea's black text sat on several):
   a real paint-order stroke halo (paper/dark-bg colored via --bg-primary, which is
   already theme-aware) so the glyphs read over any dot color, plus the existing soft
   text-shadow for a touch of extra lift over open land/ocean. */
/* R4/P3c fix round 1: the var() FALLBACK is load-bearing. answer-map-embed.html links only this
   stylesheet, and --bg-primary is declared in css/main.css :root — so on the DARK embed it
   resolves to nothing, `stroke` is invalid at computed-value time, and this halo silently
   disappears (measured: computed stroke `none`). Same fix on .tcd-am-kicker further down. */
.tcd-am-name { font-family: 'IBM Plex Mono', monospace; font-size: 10px; fill: var(--text-secondary);
  paint-order: stroke; stroke: var(--bg-primary, #1A1819); stroke-width: 3px; stroke-linejoin: round;
  text-shadow: 0 1px 2px rgba(0,0,0,0.85); opacity: 0; transition: opacity 200ms; pointer-events: none; }
.tcd-am-name.at-rest { opacity: 1; }
[data-zoom="deep"] .tcd-am-labelgroup:not(.is-fleck) .tcd-am-name { opacity: 1; }
.has-selection .tcd-am-labelgroup.lit .tcd-am-name { opacity: 1; fill: var(--text-primary); }
.has-selection .tcd-am-labelgroup:not(.lit) .tcd-am-name { opacity: 0; }
/* 2026-09-12 feedback: the SELECTED receiving country's own name should stand apart from
   the "Taken to"/"Origin" partner names lit alongside it — 30% larger (10px base * 1.3 =
   13px, rounded to the nearest px) and bold. `.selected` is mirrored onto the label group
   from its mark by mirrorState() (STATE_CLASSES), so this reaches only the one label, not
   every lit partner. */
.has-selection .tcd-am-labelgroup.selected .tcd-am-name { font-size: 13px; font-weight: 700; }
/* Round3 (2026-07-27, label-collision fix): placeLitLabels() in third-country-answer-map.js
   greedily repositions lit labels right/left/above/below their mark, then squelches whatever
   still collides on dense selections (e.g. Costa Rica's ~26 origins) rather than letting two
   labels' glyphs interleave. !important beats the .lit opacity:1 rule above on specificity. */
.tcd-am-name.squelched { opacity: 0 !important; }

/* origin countries exist only when a selection involves them */
.tcd-am-fleckmark { display: none; }
.has-selection .tcd-am-fleckmark.lit { display: block; }

.tcd-am-tooltip { position: absolute; z-index: 30; max-width: 220px; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: 4px; padding: 8px 10px; font-size: 0.8rem;
  color: var(--text-secondary); pointer-events: none; box-shadow: 0 4px 14px rgba(0,0,0,0.25); }
.tcd-am-tooltip .tip-head { color: var(--text-primary); font-weight: 600; margin-bottom: 2px; }

/* R5 points 4+5 — the map key. Upper-left is the one free corner: zoom controls sit
   bottom-left, the dossier top-right. Same box, two states (size legend at rest, colour
   caption on selection), so the reader learns one place to look. */
.tcd-am-key { position: absolute; top: 12px; left: 22px; z-index: 15; max-width: 236px;
  padding: 7px 9px; font-size: 0.75rem; line-height: 1.35; color: var(--text-secondary);
  background: color-mix(in srgb, var(--bg-card) 92%, transparent);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--border); border-radius: 8px; pointer-events: none; }
/* 104px was right when the legend was purely descriptive — narrow enough that the title
   wrapped and no dead space opened beside the tiny ring glyph. It now carries two switch rows
   with a label and a 24px info target each, and at 104px "Layover countries" wrapped to three
   lines under its own triangle. */
/* 2026-09-09: 0.6rem is 9.6px — rem here is the UNSTYLED root (main.css sets font-size on
   body, not html), so every number in this box was a quarter smaller than it read on paper.
   The whole box steps to 0.75rem/12px and the two max-widths grow with it, or the same
   labels that fitted at 172px re-wrap and the box gets taller instead of more legible. */
.tcd-am-key.is-legend { max-width: 212px; }

/* The box is pointer-events:none so the map stays draggable underneath it — it floats over
   the stage. Now that it holds controls rather than only words, the controls have to opt back
   in, or they render perfectly and cannot be clicked. (Caught by a probe, not by reading.) */
.tcd-am-layer-toggle, .tcd-am-info { pointer-events: auto; }
/* The ring key sits directly beneath this line with line-height:0, so this margin is most of
   what separates the title from the largest ring. It went 4 → 8px on 2026-09-08, when 4 put the
   title's descenders almost on the ring's stroke, and 8 → 25px on 2026-09-09 for UI ISSUES 3:
   "twice the margin between the label and the top of the largest circle."
   The reader sees ONE gap and it is built from two numbers — this margin, and renderLegend()'s
   TOP_PAD, the ascender room reserved above the largest ring so its leader label does not clip
   (ceil(RING_LBL_PX * 0.75) = 9px today). The gap measured 8 + 9 = 17px, so 25 + 9 = 34px
   doubles what is actually on screen rather than doubling one of its halves.
   tcd-ui-issues.spec.cjs measures the painted distance, because neither number is the contract. */
.tcd-am-key-title { margin: 0 0 25px; font-weight: 600; color: var(--text-primary); }
.tcd-am-key-row { display: flex; align-items: center; gap: 8px; margin-top: 3px; }
/* --text-tertiary is 5.5:1 on this box in BOTH themes — a pass for body copy and much too
   thin for 12px of it floating over a map. Secondary is 10.3:1. The title keeps
   --text-primary; what changes is that the rest is no longer a whole step below it. */
.tcd-am-key-label { color: var(--text-secondary); }

/* Nested overlapping circles sharing a baseline, the conventional cartographic size key,
   drawn 1:1 with the map's own discs (LEGEND_SCALE in answer-map.js) so a ring can be held
   against a disc on the map and read off directly. The <svg> is sized inline per render from
   the live scale factor; these rules only paint it. Rings are stroked rather than filled so
   the overlap reads as nested rather than as stacked blobs. */
.tcd-am-key-legend { line-height: 0; }
.tcd-am-key-rings { display: block; overflow: visible; }
.tcd-am-key-ring { fill: none; stroke: var(--tcd-am-dest); stroke-width: 1; stroke-opacity: 0.9; }
.tcd-am-key-ring-lead { stroke: var(--tcd-am-border); stroke-width: 0.5; stroke-dasharray: 2 2; }
/* 7px was the smallest type anywhere in the tab. These are numbers pinned to circles —
   still text, and still part of "the legend is too small to read" — so they take the same 12px
   floor as the prose rather than a concession one step below it. Pinned to RING_LBL_PX in
   js/third-country-answer-map.js (a static test asserts the two agree) because the leader-line
   spacing and the label baseline are both derived from it. */
.tcd-am-key-ring-lbl { fill: var(--text-secondary); font-family: 'Inter', sans-serif; font-size: 12px; }

/* R5 point 5 — the on-selection colour caption. Swatches deliberately reuse
   --tcd-am-home / --tcd-am-target, the same tokens shadeRoles() paints the
   countries with, so the key cannot drift from the map in either theme. */
.tcd-am-key-swatch { display: inline-block; width: 13px; height: 13px; flex: 0 0 13px;
  border-radius: 3px; border: 1px solid var(--tcd-am-border); }
.tcd-am-key-swatch.is-home { background: var(--tcd-am-home); }
.tcd-am-key-swatch.is-target { background: var(--tcd-am-target); }
/* Russian-control hatch. Amber under diagonal ink — the same two ingredients, in the same order,
   as the SVG overlay (country fill + .tcd-am-hatch-line over it), so the swatch reads as a sample
   of the map rather than a third colour. 45deg and the ~5px pitch approximate the counter-scaled
   7-unit tile at rest; an exact match is not possible across a viewBox that scales with the page,
   and the swatch only has to be recognisable. */
.tcd-am-key-swatch.is-occupied {
  background:
    repeating-linear-gradient(45deg, rgba(30, 25, 14, 0.6) 0 1.2px, transparent 1.2px 5px),
    var(--tcd-am-home);
  /* The map's solid front line, sampled on the swatch's west side — same ink as on the SVG,
     so the swatch keeps being a sample of the map rather than a diagram of it. */
  border-left: 2px solid rgba(30, 25, 14, 0.8);
}
/* Caption rows (on-selection colour swatches) wrap to two lines and need their swatch
   pinned to the first line, not centred against the full wrapped block. Legend rows
   (at-rest size discs) keep the base rule's align-items: center so each disc — including
   the large 300-person one — sits centred against its single-line number label instead
   of top-aligned, which visibly shoves the label toward the disc's upper edge. */
.tcd-am-key-row--caption { align-items: flex-start; }

/* 2026-08-05: the =<900px size key, in the strip below the map. Hidden on desktop, where the
   overlay key does this job as a true 1:1 sample of the discs. */
/* 2026-09-09: the desktop legend's legibility round applies here too — this IS the legend
   below 900px, and it had the same two problems (0.72rem is 11.5px, and --text-tertiary is
   5.5:1 on the chip in both themes). It grows less than the desktop box does: this one is an
   overlay on a phone-sized stage, so every point of type it gains is map the reader loses. */
.tcd-am-mobilekey { display: none; align-items: flex-end; gap: 8px; margin: 6px 12px 0;
  font-size: 0.78rem; color: var(--text-secondary); }
.tcd-am-mobilekey-rings { display: block; overflow: visible; flex: 0 0 auto; }
.tcd-am-mobilekey-ring { fill: none; stroke: var(--tcd-am-dest); stroke-width: 1; stroke-opacity: 0.9; }
.tcd-am-mobilekey-label { line-height: 1.25; }

/* ---------- =<900px layer controls (2026-09-09) ----------
   The desktop key carries its switch rows inline; below 900px that box is display:none, so
   until now a phone had no layer controls at all. The rows will not fit the chip — the R5
   suite holds it to the stage's top-left quadrant (177px at 375px) and a row measures 171px —
   so the chip gains a button and the panel it opens is anchored to it. Both are desktop-dead. */
.tcd-am-layersbtn, .tcd-am-layerpanel { display: none; }

/* 24px is the WCAG 2.5.8 floor; this is the only single-pointer way out of a zoom on touch, so
   it does not get shrunk below it. margin-left:auto pins it to the strip's right edge.
   The mobile dossier's position:fixed bottom sheet (z-index:60, see the @media (max-width: 900px)
   block below) covers this strip the instant a selection is active, so the button is hidden there
   (not z-index-stacked above the sheet) — the dossier already carries its own .tcd-am-close, which
   is the reachable way to clear a selection while the sheet is open. See has-selection rule below. */
.tcd-am-mobilekey-reset { margin-left: auto; flex: 0 0 auto;
  width: 28px; height: 28px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text-primary); cursor: pointer; font-size: 1rem; line-height: 1; }
.tcd-am-mobilekey-reset:hover, .tcd-am-mobilekey-reset:focus-visible { border-color: var(--tcd-am-dest); }

.tcd-am-zoomctl { position: absolute; left: 22px; bottom: 46px; display: flex; flex-direction: column; gap: 4px; }
.tcd-am-zoomctl .zbtn { width: 28px; height: 28px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text-primary); cursor: pointer; font-size: 1rem; line-height: 1; }
.tcd-am-zoomctl .zbtn:hover, .tcd-am-zoomctl .zbtn:focus-visible { border-color: var(--tcd-am-dest); }

/* 2026-09-18 feedback (item 4): publisher credit, bottom-right. 32px clears the in-flow
   .tcd-am-caption sitting right below it in the same neatline box on desktop (a single
   0.78rem line plus its 6px top margin is well under that); the reset control lives on the
   OPPOSITE corner (left) on desktop, so no clearance is needed against it there. Kept small
   and low-opacity so it reads as a credit mark, not a control. */
.tcd-am-watermark { position: absolute; right: 12px; bottom: 32px; display: block;
  opacity: 0.32; transition: opacity 120ms ease; }
.tcd-am-watermark img { display: block; height: 14px; width: auto; }
.tcd-am-watermark:hover, .tcd-am-watermark:focus-visible { opacity: 0.7; }
@media (prefers-reduced-motion: reduce) { .tcd-am-watermark { transition: none; } }

/* "Opens in a new tab" marker. currentColor so it tracks the meta line it sits in, and
   vertical-align keeps it on the text baseline rather than hanging below it. The Coverage
   round reuses this class for the consortium links, which are all new-tab too. */
.tcd-am-extlink { stroke: currentColor; fill: none; vertical-align: -1px; margin-left: 0.35em; opacity: 0.75; }
.tcd-am-doc:hover .tcd-am-extlink, .tcd-am-doc:focus-visible .tcd-am-extlink { opacity: 1; }
.tcd-am-doc-meta { display: inline-flex; align-items: center; }

/* Cooperative-gesture affordance (2026-09-08). Appears only when the reader wheels over a
   map that is not armed, and briefly on arming — a permanent chip would be one more thing
   competing with the legend, the caption and the dossier. Centred on the stage because that
   is where the cursor already is when the hint is earned. */
.tcd-am-zoomhint {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  padding: 0.5rem 0.85rem; border-radius: 999px;
  background: var(--bg-card); border: 1px solid var(--border);
  color: var(--text-primary); font-family: 'Inter', sans-serif; font-size: 0.82rem;
  white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity 160ms ease;
}
.tcd-am-zoomhint.is-on { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .tcd-am-zoomhint { transition: none; } }

/* An armed map says so quietly at its edge, so "why is the page not scrolling?" has an
   answer on screen even after the hint has faded. */
.tcd-answer-map.zoom-armed .tcd-am-neatline { outline: 1px solid var(--tcd-am-dest); outline-offset: -1px; }

/* 2026-08-06 user-feedback round — overflow edge fades. The "two fingers" hint chip is
   RETIRED: the horizontal drag it apologized for now simply pans the map (one-finger
   axis-locked pan in the touch resolver). What remains is the standing affordance: a soft
   gradient at any stage edge the land continues past, toggled from the zoom handler
   (.is-on only while content is actually cropped on that side — both vanish at
   whole-world zoom). display:none at base; the ≤900px block turns them on — the fades
   describe the mobile rest camera's crop, which desktop (full-world viewBox) never has. */
.tcd-am-edgefade { display: none; }

/* L5 (T5.3): caption bumped --text-caption→--text-tertiary (3.95:1→6.52:1 vs
   --bg-primary) to clear AA 4.5:1 for this small body text. */
.tcd-am-caption { margin: 6px 12px 0; font-size: 0.78rem; color: var(--text-tertiary); }
.tcd-am-caption a { color: inherit; }
/* 2026-09-19 feedback (round 2, item 2): the credits/"How we count" caption is redundant chrome
   once a country card is open -- unscoped (not just the ≤900px mobile block below), because the
   card floats over the map on DESKTOP too and the caption sits in-flow at the very bottom of the
   whole component, spanning underneath both the map and the open card either way. Confirmed via
   a live desktop screenshot: the first pass only hid it on mobile and left it showing at the
   bottom of the page with a card open. */
.tcd-answer-map.has-selection .tcd-am-caption { visibility: hidden; }
/* 2026-09-19 feedback (items 4-5): a <button> now opens the shared methodology modal (it used to
   be a <details><summary> that expanded an inline note in place) — reset the button chrome so it
   reads as the same inline underlined link the summary used to be. */
.tcd-am-how { display: inline; font: inherit; color: inherit; background: none; border: none;
  padding: 0; margin: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }

/* The shared "How we count" / "Methodology & Sources" modal (js/third-country-methodology-modal.js).
   A native <dialog> — showModal() gives a real focus trap and Escape-to-close with no bespoke JS.
   Sits outside #third-country in the DOM (appended to <body>), so it uses the SAME theme-aware
   tokens .tcd-am-dossier does (--bg-card/--border/--text-*), not the dark-only --tcd-* set, and
   keeps reading correctly whichever theme is active when it opens. */
/* padding on the DIALOG itself (not just the panel) matters: it leaves a strip of the dialog's
   own box, outside .tcd-methodology-modal-panel, that a click can still land on — which is what
   makes `e.target === dialog` in the backdrop-click handler reachable at all. A 0-padding dialog
   with a full-bleed panel has no such strip, and a real click can only ever hit the panel. */
.tcd-methodology-modal { padding: 10px; border: none; border-radius: 12px; max-width: 560px;
  width: calc(100vw - 32px); max-height: calc(100vh - 64px); background: transparent;
  color: var(--text-secondary);
  /* dialog:modal's UA stylesheet centers via `inset: 0; margin: auto;` -- this site's global
     reset (css/main.css, `* { margin: 0; }`) wins that cascade (author beats UA regardless of
     specificity) and silently pins the dialog to the top of the viewport instead. Reclaiming
     margin:auto here (a class selector already outweighs the reset's universal one) is enough;
     the `inset: 0` half of the centering algorithm is untouched by the reset and still applies. */
  margin: auto; }
.tcd-methodology-modal::backdrop { background: rgba(0,0,0,0.55); }
.tcd-methodology-modal-panel { position: relative; padding: 28px 24px 22px; overflow-y: auto;
  max-height: calc(100vh - 84px); box-sizing: border-box; background: var(--bg-card);
  border-radius: 8px; box-shadow: 0 20px 60px rgba(0,0,0,0.45); }
.tcd-methodology-modal-title { margin: 0 32px 12px 0; font-size: 1.25rem; color: var(--text-primary); }
.tcd-methodology-modal-body p { max-width: 62ch; margin: 0 0 12px; font-size: 0.92rem; line-height: 1.5; }
.tcd-methodology-modal-body p:last-child { margin-bottom: 0; }
.tcd-methodology-modal-body a { color: var(--text-primary); text-decoration: underline;
  text-decoration-color: var(--accent); text-underline-offset: 2px; }
.tcd-methodology-modal-close { position: absolute; top: 14px; right: 14px; width: 32px; height: 32px;
  border-radius: 50%; border: 1px solid var(--border); background: transparent; color: var(--text-secondary);
  font-size: 1.3rem; line-height: 1; cursor: pointer; }
.tcd-methodology-modal-close:hover { color: var(--text-primary); border-color: var(--text-secondary); }
@media (max-width: 480px) {
  .tcd-methodology-modal { width: calc(100vw - 24px); }
  .tcd-methodology-modal-panel { padding: 24px 16px 18px; }
}

/* dossier floats over the map on desktop; bottom sheet on mobile */
.tcd-am-dossier { position: absolute; top: 12px; right: 22px; z-index: 20; width: 340px;
  max-height: calc(100% - 60px); overflow-y: auto; padding: 14px 16px;
  background: color-mix(in srgb, var(--bg-card) 92%, transparent);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.35); }
.tcd-am-dossier-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.tcd-am-dossier-title { font-size: 1.15rem; margin: 0 0 8px; }
/* R5 mobile fix (2026-07-29): the colour caption's mobile-only mount inside the bottom sheet
   (renderSelection appends it right after .tcd-am-dossier-head; see the @media (max-width: 900px)
   block above, which hides the floating .tcd-am-key box under a selection at this width instead).
   Reuses .tcd-am-key-row--caption / .tcd-am-key-swatch / .tcd-am-key-label as-is — those rules
   are not scoped to .tcd-am-key, so the same swatch colours and row layout apply here for free.
   The min-width guard is a belt-and-braces desktop safety net: renderSelection only appends this
   node when narrowViewport() is true at selection time, so it should never exist above 900px, but
   resizing an already-open sheet from narrow to wide must not leave a stale copy on screen. */
.tcd-am-dossier-key { margin: 0 0 12px; padding-bottom: 10px; border-bottom: 1px solid var(--border); }
.tcd-am-dossier-key .tcd-am-key-row--caption { margin-top: 5px; }
.tcd-am-dossier-key .tcd-am-key-row--caption:first-child { margin-top: 0; }
/* MAP DESIGN 1, option A: no longer mobile-only. The colour caption is the card's at every
   width and the floating box stands down beneath, which is the whole of the change — one
   place explains the colours instead of two. Desktop wants it tighter than the phone sheet
   does: in the sheet it is the first thing under a 1.15rem title with the whole viewport
   width to breathe into; here it sits above a 340px card that already scrolls. */
@media (min-width: 901px) {
  .tcd-am-dossier-key { margin-bottom: 10px; padding-bottom: 9px; font-size: 0.82rem; }
  .tcd-am-dossier-key .tcd-am-key-row--caption { margin-top: 4px; }
  .tcd-am-dossier-key .tcd-am-key-row--caption:first-child { margin-top: 0; }
  .tcd-am-dossier-key .tcd-am-key-label { color: var(--text-secondary); }
  /* The box's second job is gone, so under a selection it has nothing to say that the card is
     not already saying. This is the line that gives the top-left corner back to the map.
     Gated on :has() rather than on .has-selection alone: an EXCLUDED country produces no
     colour caption, so nothing mounts in the card, and standing the box down for it would
     leave that selection with no key at all. The box retires exactly when the card has
     taken its job — never on the assumption that it has. */
  .tcd-answer-map.has-selection:has(.tcd-am-dossier-key) .tcd-am-key { display: none; }
}
.tcd-am-close { background: none; border: 1px solid var(--border); border-radius: 4px;
  color: var(--text-secondary); cursor: pointer; padding: 2px 8px; }
.tcd-am-corr-meta { font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; color: var(--text-tertiary); margin: 0 0 10px; }
.tcd-am-block { margin: 14px 0 0; }
.tcd-am-block h5 { margin: 0 0 8px; font-size: 0.92rem; }
.tcd-am-quiet { color: var(--text-tertiary); font-size: 0.78rem; margin: 6px 0 0; }
.tcd-am-excluded-note { font-weight: 600; color: var(--text-primary); }
.tcd-am-agreement { margin: 0 0 6px; font-size: 0.9rem; font-weight: 600; color: var(--text-primary); }
.tcd-am-agreement.none { font-weight: 500; color: var(--text-tertiary); font-style: italic; }
/* ---------- country-card media (2026-09-03) ----------
   Most of this map's media is a removal agreement: a page somebody signed and mostly did
   not publish. It reaches the reader as what it is — page one, TOP-cropped, because the
   letterhead, the diplomatic note number and the title all sit in the first third of a
   page and they are what identify the document. The scan's white paper is the one bright
   rectangle in the dossier; that is where this component spends its boldness, and every
   other surface here stays in the card's existing quiet register.
   The whole plate is the link. One target, and on a phone a thumb-sized one. */
.tcd-am-media { margin: 12px 0 0; }
/* align-items: start, not the grid default of stretch. Cameroon pairs a 360x640 video
   with a document cover: stretched, the document plate grew to the video's height and left
   a dead block of card under its caption. Each plate now keeps its own intrinsic height. */
.tcd-am-media-track { display: grid; gap: 8px; align-items: start; }

/* 2026-09-08: one object at a time. The single-asset case — 24 of the 29 cards with media —
   never reaches .is-multi, so it stays exactly the full-width plate it has always been.
   Only a card with somewhere to go becomes a track.

   92%, not 100%: the sliver of the next panel showing past the right edge is what tells a
   reader there IS a next panel. The arrows and the counter confirm that; the peek is what
   carries it, and it carries it without a word of instruction. */
.tcd-am-media-track.is-multi {
  grid-auto-flow: column;
  grid-auto-columns: 92%;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  /* start, not centre. A panel now carries its own caption, so the row's height varies with
     the copy as well as the picture — and centring made the media itself rise and fall as
     the reader moved between panels. Top-aligning keeps the picture's top edge fixed; the
     slack collects below the shorter panel, where it reads as space rather than as motion. */
  align-items: start;
}
.tcd-am-media-track.is-multi::-webkit-scrollbar { display: none; }
.tcd-am-media-track.is-multi > * { scroll-snap-align: start; }
.tcd-am-media-track.is-multi:focus-visible {
  outline: 2px solid var(--tcd-am-dest); outline-offset: 3px; border-radius: 8px;
}

/* Directly under the track, above the caption — see renderMedia for why. */
.tcd-am-media-nav { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin: 8px 0 0; }
.tcd-am-media-steps { display: flex; gap: 6px; }
/* 28px, over the 24px floor in WCAG 2.5.8 — these are thumb targets inside a bottom sheet
   on a phone, and the map's other controls already settled on this size. */
.tcd-am-media-step { width: 28px; height: 28px; display: grid; place-items: center;
  padding: 0; cursor: pointer; font-size: 0.95rem; line-height: 1;
  background: var(--bg-secondary); color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: 6px;
  transition: border-color 0.15s ease, color 0.15s ease; }
.tcd-am-media-step:hover:not(:disabled) { border-color: var(--tcd-am-dest); color: var(--text-primary); }
.tcd-am-media-step:focus-visible { outline: 2px solid var(--tcd-am-dest); outline-offset: 2px; }
/* Dimmed rather than hidden. A control that disappears at the end of the run makes the row
   reflow under the thumb that is using it. */
.tcd-am-media-step:disabled { opacity: 0.35; cursor: default; }
.tcd-am-media-count { font-family: 'IBM Plex Mono', monospace; font-size: 0.66rem;
  color: var(--text-tertiary); font-variant-numeric: tabular-nums; }

/* A grid row is as tall as its tallest member, so panels of different heights leave dead card
   under the shorter ones — 130px of it beneath Sierra Leone's fifth leaflet, which reads as a
   hole rather than as spacing. Every media box is therefore the same height, near the document
   plate's own 5:4 (about 226px at this column width), and the picture is CONTAINED in it.

   The letterbox is transparent, not black. Bars are only ugly when you can see them: against
   the card's own ground the slack around a wider or narrower picture is indistinguishable from
   margin, so panels line up without a single crop. */
.tcd-am-media-track.is-multi .tcd-am-video,
.tcd-am-media-track.is-multi .tcd-am-photo {
  height: 230px; width: 100%; aspect-ratio: auto;
  object-fit: contain; background: transparent;
}
/* The crop pair keeps its OWN sizing even inside a multi-panel track (2026-09-18: Mexico
   picked up a sibling asset, the government's response, which makes the track .is-multi
   for the first time). Same specificity as the rule above, so source order decides — this
   comes after it on purpose. Without it, the six-faces photo would shrink into the fixed
   230px box meant for a stack of clips or document leaflets, undoing the "never cropped,
   sized by height, finds its own width" rule this photo was specifically given below. */
.tcd-am-media-track.is-multi .tcd-am-photo-pair { height: auto; width: 100%; }

.tcd-am-doc { display: block; text-decoration: none; color: inherit;
  background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px;
  overflow: hidden; transition: border-color 0.15s ease; }
.tcd-am-doc:hover, .tcd-am-doc:focus-visible { border-color: var(--tcd-am-dest); }
.tcd-am-doc:focus-visible { outline: 2px solid var(--tcd-am-dest); outline-offset: 2px; }
.tcd-am-doc-page { display: block; position: relative; aspect-ratio: 5 / 4; overflow: hidden; }
.tcd-am-doc-img { display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: top center; }
/* The crop has to read as deliberate rather than as a truncated image, so the page fades
   into the plate's own ground at the cut. Bottom third only — the letterhead stays clean. */
.tcd-am-doc-page::after { content: ''; position: absolute; inset: auto 0 0; height: 34%;
  background: linear-gradient(to bottom, transparent, var(--bg-secondary));
  pointer-events: none; }
.tcd-am-doc-cap { display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; padding: 7px 9px; border-top: 1px solid var(--border); }
.tcd-am-doc-label { font-size: 0.78rem; color: var(--text-primary); }
.tcd-am-doc-meta { flex: 0 0 auto; font-family: 'IBM Plex Mono', monospace;
  font-size: 0.62rem; color: var(--text-tertiary); }

/* The photo plate is a link, like the document plate beside it. position:relative carries
   the corner badge; the block display keeps the anchor the size of its picture rather than
   an inline box with a descender gap under it. */
.tcd-am-photolink { position: relative; display: block; text-decoration: none;
  border-radius: 8px; }
.tcd-am-photolink:focus-visible { outline: 2px solid var(--tcd-am-dest); outline-offset: 2px; }
.tcd-am-photolink:hover .tcd-am-photo, .tcd-am-photolink:focus-visible .tcd-am-photo {
  border-color: var(--tcd-am-dest); }
.tcd-am-photozoom { position: absolute; right: 6px; bottom: 6px; display: grid;
  place-items: center; width: 22px; height: 22px; border-radius: 5px;
  background: color-mix(in srgb, var(--bg-card) 82%, transparent);
  border: 1px solid var(--border); color: var(--text-secondary);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }

/* A panel is the object AND the words for that object (2026-09-08). The caption follows its
   own picture, so nothing has to be re-attributed as the reader swipes. */
.tcd-am-media-item { display: flex; flex-direction: column; min-width: 0; }
.tcd-am-video, .tcd-am-photo { display: block; width: 100%; height: auto;
  border: 1px solid var(--border); border-radius: 8px; }
/* A <video> letterboxes inside its own box rather than shrinking to fit, so a portrait
   clip in a full-width slot paints black bars down both sides and pays for the height
   anyway. Sizing by max-height with width:auto lets the element take the shape of its
   own frame — a portrait clip narrows, a landscape one still fills the column. */
/* --tcd-am-ar is set inline from the manifest's real dimensions (videoPlate); the
   fallback only applies to a clip whose size was never recorded.

   The width has to be DEFINITE. `width: auto` on a replaced element resolves against its
   intrinsic size, and a preload="none" video has none — measured 2x2 until the poster
   decoded and supplied one, which is a visible jump and a permanent 2px box if the poster
   ever fails. So the cap is expressed as a width instead: --tcd-am-cap is how tall the clip
   may be, and multiplying it by the ratio (`360 / 640` divides cleanly inside calc) gives
   the widest it may be at that height. min() then lets a landscape clip fill the column
   while a portrait one narrows to its own shape — no black bars either way. */
.tcd-am-video { background: #000; height: auto; margin-inline: auto;
  aspect-ratio: var(--tcd-am-ar, 16 / 9);
  width: min(100%, calc(var(--tcd-am-cap, 300px) * var(--tcd-am-ar, 1.7778))); }
.tcd-am-media-item picture { display: block; }

/* Left-aligned, not centred: the one long caption here (six names, in reading order) is
   two sentences of prose, and centred prose is unreadable at this size. */
.tcd-am-media-cap { margin: 7px 0 0; font-size: 0.72rem; line-height: 1.45;
  color: var(--text-tertiary); text-align: left; }
/* The peek is for the next PICTURE. A caption inside a panel that is 8% visible wraps to the
   panel's full width and prints two letters of each line into the sliver, which reads as a
   glitch. Faded rather than hidden: the words keep their box, so the track's height is the
   same whichever panel is in view and nothing reflows on a swipe. */
.tcd-am-media-track.is-multi .tcd-am-media-cap { transition: opacity 0.18s ease; }
.tcd-am-media-track.is-multi > *:not(.is-active) .tcd-am-media-cap { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .tcd-am-media-track.is-multi .tcd-am-media-cap { transition: none; }
}

/* An agreement on record that this flight list cannot document: a hollow ring, never a
   filled disc. Filled area on this map means people counted, and these are exactly the
   countries where the count is what we do not have. */
/* ---------- layer switches (2026-09-08) ----------
   DC2 retired the hollow "agreement on record, no flights in this list" ring and every rule
   that painted it. What stood in its place in the legend is now a switch per layer: the box
   already had to name each layer and draw its glyph, so the rows it was drawing anyway became
   the control. One box rather than a legend plus a second strip repeating it. */

/* A layover is a different KIND of place, not a smaller destination, so it differs in SHAPE
   rather than in size — and in a third, neutral tone, because the map's two colours already
   mean "taken to" and "came from" and a layover is neither. */
/* Green, at the amber's own saturation and lightness — derived, not eyeballed. --tcd-am-home
   is hsl(39 69.8% 55.9%) in the dark palette and hsl(38 92.3% 45.9%) on paper; the layover
   green holds both of those and moves only the hue, to 145°. That sits 106° off the amber and
   84° off the destination blue, so the three layers separate by hue alone rather than by
   anyone remembering which is which. */
.tcd-am-layover { fill: var(--tcd-am-layover); stroke: var(--bg-primary, #1A1819);
  stroke-width: 0.5; stroke-linejoin: round; }
.tcd-am-mark.selected .tcd-am-layover { fill: var(--tcd-am-layover); filter: brightness(1.25); }
.tcd-answer-map.has-selection .tcd-am-mark:not(.selected) .tcd-am-layover { fill-opacity: 0.35; }

/* Each layer answers to its switch. The mark and the name go together: a triangle with no
   word beside it is the "colour without a word" failure R4/P3c exists to prevent. */
.tcd-answer-map:not(.layers-layover) .tcd-am-layovermark,
.tcd-answer-map:not(.layers-layover) .tcd-am-labelgroup.is-layover { display: none; }
/* Israel's badge lives on its DISC's mark group (not a standalone .tcd-am-layovermark, so
   the rule above never reaches it — the disc, a receiving-country fact, must stay visible
   regardless of this layer). Hide the badge shape itself instead. */
.tcd-answer-map:not(.layers-layover) .tcd-am-layover-badge { display: none; }

/* 2026-09-12 feedback: "agreement on record, no documented flights" as a toggleable dashed
   ring — DC2 (2026-09-09) had this always-on, then retired it outright. Muted, not a new
   hue: filled area on this map means people counted, and a dashed hollow ring is where the
   count is what is lacking, not a fourth category alongside destination/origin/transit. */
.tcd-am-pact { fill: none; stroke: var(--tcd-am-muted); stroke-width: 1.3; stroke-dasharray: 2.2 2; }
.tcd-am-mark.selected .tcd-am-pact { stroke-width: 1.8; }
/* 2026-09-15 feedback: Jamaica (a pact ring) is ALSO named on Equatorial Guinea's ledger as an
   origin, so selecting Equatorial Guinea lights Jamaica's country shape amber (the ordinary
   origin-highlight fill, on the base map layer under this ring) while this dashed ring keeps
   drawing on top of it at full opacity — a solid amber island with a hollow dashed circle
   stamped over it, reading as visual clutter for a country the ring itself is not about ("Taken
   to Equatorial Guinea" said nothing about Jamaica's own no-transfers agreement). The origin
   fill already speaks for a lit pact ring the same way .tcd-am-mark.lit already hides a normal
   disc/layover badge above (R4 fix wave) — same principle, applied to the one shape those two
   rules do not cover. */
.tcd-answer-map.has-selection .tcd-am-mark.lit .tcd-am-pact { display: none; }
/* 2026-09-12 round 2: Guatemala and Ecuador are ALSO .tcd-am-undatedmark — a documented total
   (total_TCN) with no per-flight ledger draws its own disc, an always-on fact independent of
   this layer. Hiding the whole .tcd-am-pactmark group (as the six pact-only countries still
   need, so an off-layer never leaves an invisible-but-tabbable button on the map) would take
   that disc down with it. Same split as the layover badge above: exempt the group, hide the
   ring shape itself instead — this still toggles for Guatemala/Ecuador, just without erasing
   their disc along with it. */
.tcd-answer-map:not(.layers-pact) .tcd-am-pactmark:not(.tcd-am-undatedmark) { display: none; }
.tcd-answer-map:not(.layers-pact) .tcd-am-pact { display: none; }
/* A pact ring that is ALSO an origin country (five of the nine) keeps its origin label
   under the ORIGINS layer's own rule regardless of this one — :not(.is-origin) so turning
   the pact layer off never hides a name the origins layer still needs to show. */
.tcd-answer-map:not(.layers-pact) .tcd-am-labelgroup.is-pact:not(.is-origin) { display: none; }

/* Origins at rest, when switched on, are painted exactly as a selection paints them — same
   amber fill, same name — because the brief asks for the same design and colour scheme, and
   because two different origin treatments would be two things to keep in step. */
.tcd-answer-map.layers-origins:not(.has-selection) .tcd-am-labelgroup.is-origin .tcd-am-name {
  opacity: 1; fill: var(--tcd-am-home-ink); }

/* 2026-09-14 feedback: "the blue circles should disappear [when origins is switched on] to
   make clear that the nature of the information has changed." Destination discs (ordinary and
   undated-total alike — both are the same blue circle to a reader) hide at rest under this
   layer; a circle is also each mark's only hit-testable shape, so this doubles as making those
   destinations unselectable while the layer reads as origins-only, which matches the ask.
   Gated on :not(.has-selection), same as shadeOriginLayer() in the JS: once a reader picks a
   country the ordinary selection view owns the map again and discs return. Also excludes any
   mark inside an OPEN Central America spiderfy fan (.tcd-am-fanned) — opening the badge is a
   distinct stage from selecting a destination (state.selected stays null there), and hiding
   the fanned discs would silently break the fan's own tap targets while this layer is on. */
.tcd-answer-map.layers-origins:not(.has-selection) .tcd-am-mark:not(.tcd-am-fanned) .tcd-am-disc {
  display: none; }
/* 2026-09-14 feedback round 3: "the labels for Mexico, Paraguay, and CAR stay [when Origin
   countries is switched on]. They should disappear too." The rule above hides the SHAPE under
   a plain destination's mark, but its NAME is a sibling element in a different SVG group
   (.tcd-am-labelgroup in gLabels, not nested inside .tcd-am-mark — see the labelgroup comment
   in third-country-answer-map.js) that nothing here reached, so a reader saw a floating word
   with no disc under it: Mexico's ALWAYS-at-rest isLand label, plus whichever destinations
   happen to be biggest-by-size (topDests.slice(0,6) — CAR and Paraguay among them at the time
   of this report). Scoped exactly like the disc rule (:not(.has-selection),
   :not(.tcd-am-fanned) so an open Central America spiderfy fan is untouched) and
   :not(.is-origin) so a country whose name this layer exists to reveal — origin-only or
   dual-role alike — is never hidden by this one.
   2026-09-20 feedback (DRC): a dual-role country (both a destination and an origin, e.g.
   Ghana) used to never carry .is-origin (third-country-answer-map.js required !isDest), so
   this rule hid its label with nothing put in its place — real origin data (Ghana sent people
   onward to Panama) went invisible the moment this layer switched on. third-country-answer-
   map.js now grants .is-origin to any real origin regardless of isDest, so a dual-role
   country's label is lit by the rule above instead of hidden by this one — same one-claim
   treatment a pure-origin country gets, just origin instead of none. */
.tcd-answer-map.layers-origins:not(.has-selection) .tcd-am-labelgroup:not(.is-origin):not(.tcd-am-fanned) .tcd-am-name.at-rest {
  opacity: 0; }

/* 2026-09-16 feedback: the Central America spiderfy badge (.tcd-am-cluster) is its OWN element
   in gMarks, a sibling of .tcd-am-mark rather than a shape inside one — so the "blue circles
   disappear under Origins" rule two blocks up, scoped to `.tcd-am-mark .tcd-am-disc`, never
   reached it, and it kept showing its blue segmented ring even with every real destination disc
   hidden. Same gating as that rule (:not(.has-selection)) plus :not(.has-cluster-open) so an
   already-open fan is untouched — the badge is still each fanned member's way back into the
   cluster, and closing this rule over it mid-interaction would strand those tap targets the
   same way :not(.tcd-am-fanned) protects them above. */
.tcd-answer-map.layers-origins:not(.has-selection):not(.has-cluster-open) .tcd-am-cluster {
  display: none; }

.tcd-am-key-layer { display: flex; align-items: center; gap: 6px; margin: 8px 0 0; }
.tcd-am-layer-toggle { flex: 1 1 auto; display: flex; align-items: center; gap: 7px;
  min-height: 24px; padding: 2px 4px; margin-left: -4px; cursor: pointer;
  background: none; border: 1px solid transparent; border-radius: 5px;
  font: inherit; font-size: 0.8rem; color: var(--text-secondary); text-align: left; }
.tcd-am-layer-toggle:hover { color: var(--text-primary); }
.tcd-am-layer-toggle:focus-visible { outline: 2px solid var(--tcd-am-dest); outline-offset: 1px; }
/* Off is stated by the glyph draining, not by the row greying out: a greyed row reads as
   "unavailable" rather than "not currently shown".
   2026-09-09: the label used to dim to 0.62 alongside it, which contradicted the line above
   and was the single faintest thing in the box — 3.04:1 dark and 2.56:1 light, the latter a
   flat WCAG AA failure. Origins ship OFF, so that was the state the reader met first. The
   glyph carries "off" on its own now; aria-checked carries it for everyone else. */
.tcd-am-layer-toggle[aria-checked="false"] .tcd-am-key-glyph { opacity: 0.28; }
.tcd-am-key-glyph { flex: 0 0 auto; overflow: visible; transition: opacity 0.15s ease; }
.tcd-am-key-origin-dot { fill: var(--tcd-am-home); }

/* 2026-09-12 feedback: the desktop row above stated "toggle" only by draining an icon,
   which does not read as a control until a reader has already found out it is one. The
   =<900px panel already drew a real switch (track + knob) for the same buttons — this
   is that same drawing, un-scoped from the mobile-only media query so BOTH renderings of
   LAYER_DEFS (see the "ONE definition" comment above renderLegend()) share one switch
   look. role="switch" promises a switch; colour is decorative, the knob's POSITION is
   what states on/off. */
.tcd-am-panel-track { flex: 0 0 auto; margin-left: auto; position: relative;
  width: 32px; height: 18px; border-radius: 999px;
  background: var(--border-strong); transition: background 0.15s ease; }
.tcd-am-panel-track::after { content: ''; position: absolute; top: 2px; left: 2px;
  width: 14px; height: 14px; border-radius: 50%; background: var(--bg-primary);
  transition: transform 0.15s ease; }
.tcd-am-layer-toggle[aria-checked="true"] .tcd-am-panel-track {
  background: var(--tcd-am-dest); }
.tcd-am-layer-toggle[aria-checked="true"] .tcd-am-panel-track::after {
  transform: translateX(14px); }
@media (prefers-reduced-motion: reduce) {
  .tcd-am-panel-track, .tcd-am-panel-track::after { transition: none; }
}

/* 24px, the WCAG 2.5.8 floor — this is a hit target on a phone, not decoration. */
/* The BUTTON stays 24x24 — that is the WCAG 2.5.8 floor and it is a thumb target on a phone.
   What shrinks is the drawn ring, which is now a pseudo-element sized to hug the glyph instead
   of being the button's own border. Decoupling the two is the only way to close the gap
   without taking the hit area down with it: at 24px with a 0.6rem 'i' the ring sat ~8.5px off
   the letter on every side, which read as a letter lost in a circle. */
.tcd-am-info { flex: 0 0 auto; width: 24px; height: 24px; display: grid; place-items: center;
  padding: 0; cursor: help; background: none; border: none;
  color: var(--text-secondary);
  font-family: 'IBM Plex Mono', monospace; font-size: 0.8rem; line-height: 1; position: relative; }
.tcd-am-info::before { content: ''; position: absolute; left: 50%; top: 50%;
  width: 13px; height: 13px; transform: translate(-50%, -50%);
  /* currentColor, not --border: that token is a hairline meant to separate two surfaces
     (1.27:1 on this box in dark, 1.47:1 in light) and it failed WCAG 1.4.11's 3:1 floor for
     a UI component by a wide margin — "you can barely see the circle" was literal. Bound to
     the letter instead, the ring reads as one mark with it and brightens with it on hover. */
  border: 1px solid currentColor; border-radius: 50%; }
.tcd-am-info > * , .tcd-am-info { z-index: 0; }
/* 2026-09-12 feedback: the hint bubble rendered UNDER the toggle switches (and their
   tracks/knobs) belonging to the layer rows below it in the same key box, and under the map's
   own country labels — readable in a diff but not on screen, since z-index:3 on ::after only
   wins WITHIN this button's own stacking context (against its ::before ring), not against a
   SIBLING row's content. `.tcd-am-key-layer` rows and `.tcd-am-panel-track` are all
   position:relative with no z-index of their own, so every one of them (this button included)
   paints in the SAME z:auto/0 layer of the key box's stacking context, ordered by plain DOM
   position — a later row's switch/track sits after this row's tooltip in that order and so
   painted on top of it, string-of-pearls fashion, regardless of the ::after's own z-index.
   Raising the whole button (not just the pseudo-element) above that shared layer only while its
   hint is actually showing fixes it without giving the button a permanently elevated stacking
   level that would fight its neighbors' own hover states. */
.tcd-am-info:hover, .tcd-am-info:focus-visible { color: var(--text-primary); z-index: 50; }
.tcd-am-info:hover::before, .tcd-am-info:focus-visible::before { border-color: var(--tcd-am-dest); }
.tcd-am-info:focus-visible { outline: 2px solid var(--tcd-am-dest); outline-offset: 2px; }
/* Built rather than borrowed from native title=: that has a ~1s delay and never opens on a
   phone, and this hint is the only place the layer's meaning is written. Opens on hover AND
   on focus, so a tap reaches it too. */
.tcd-am-info::after { content: attr(data-hint); position: absolute; left: 50%; top: calc(100% + 7px);
  transform: translateX(-50%); width: max-content; max-width: 230px; padding: 7px 9px;
  background: var(--bg-card); color: var(--text-primary); border: 1px solid var(--border);
  border-radius: 6px; box-shadow: 0 6px 18px rgba(0,0,0,0.4);
  font-family: 'Inter', system-ui, sans-serif; font-size: 0.78rem; line-height: 1.4;
  text-align: left; white-space: normal; opacity: 0; visibility: hidden;
  transition: opacity 0.12s ease; pointer-events: none; z-index: 3; }
.tcd-am-info:hover::after, .tcd-am-info:focus-visible::after { opacity: 1; visibility: visible; }
@media (prefers-reduced-motion: reduce) {
  .tcd-am-info::after, .tcd-am-key-glyph { transition: none; }
}
/* Two mirror lines, one per selection role: "Countries of origin" for a country people were taken
   TO, "Taken to" for a country people were taken FROM. Both are the written guarantee that lets
   the map suppress a crowded label, so neither is ever capped — the sheet scrolls instead. */
/* CONSORTIUM COVERAGE 1 — this country's partner stories, high on the card. Set as an
   editorial block, not a chrome panel: a kicker naming the investigation, then the stories
   themselves at reading size. It sits between the summary line and the media, so it is bounded
   above and below by rules rather than a box — a card this small cannot afford another border. */
.tcd-am-stories { margin: 0 0 12px; padding: 9px 0 10px;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.tcd-am-story-kicker { margin: 0 0 7px; font-family: 'DM Sans', 'Inter', sans-serif;
  font-size: 0.68rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-tertiary); }
/* The one branded mark on the card, and the same red the index below the map uses. */
.tcd-am-story-fs { color: #E4002B; }
.tcd-am-story-list { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 7px; }
/* The line-height belongs on the BLOCK, not on the inline title. An inline element cannot
   shrink the line box below its containing block's strut, and the dossier's is 1.7 at 18px —
   so a wrapped headline opened a 30px gap between its own two lines while reporting a tidy
   computed line-height of 18.8px on the span itself. */
.tcd-am-story { display: block; font-size: 0.84rem; line-height: 1.4; }
.tcd-am-story-title { color: var(--text-primary); }
/* A placeholder with no URL yet is a span, not an anchor — so only the anchor gets link
   affordances. Site-wide dark-mode link rule: readable ink, accent underline. */
a.tcd-am-story-link { display: inline; text-decoration: underline;
  text-decoration-color: var(--accent); text-underline-offset: 2px; color: var(--text-primary); }
a.tcd-am-story-link:hover .tcd-am-story-title,
a.tcd-am-story-link:focus-visible .tcd-am-story-title { text-decoration-color: var(--text-primary); }
a.tcd-am-story-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
.tcd-am-story-pub { display: block; margin-top: 2px;
  font-family: 'IBM Plex Mono', monospace; font-size: 0.7rem; color: var(--text-tertiary); }

.tcd-am-origins, .tcd-am-taken-to { margin-top: 10px; }
.tcd-am-origins h5, .tcd-am-taken-to h5 { margin: 0 0 3px; font-size: 0.78rem; color: var(--text-secondary); }
.tcd-am-origins p, .tcd-am-taken-to p { margin: 0; font-size: 0.82rem; line-height: 1.45; color: var(--text-primary); }

/* 2026-09-14 feedback: Mexico's crossings legend, moved into the card (attachMexicoCorridors
   in js/third-country-answer-map.js) from the bus-view HUD — see the retirement note near
   .tcd-busflow-cnum. Leads the card (margin-top: 0), the slot the photo carousel used to
   occupy, in the dossier's own h5/list styling rather than the diorama's dark chip. */
.tcd-am-corridors { margin: 0 0 10px; }
.tcd-am-corridors h5 { margin: 0 0 3px; font-size: 0.78rem; color: var(--text-secondary); }
.tcd-am-corridors-list { list-style: none; margin: 0; padding: 0;
  font-size: 0.82rem; line-height: 1.45; color: var(--text-primary); }
.tcd-am-corridors-list li { display: flex; align-items: baseline; gap: 6px; margin-top: 2px; }
.tcd-am-corridors-list li:first-child { margin-top: 0; }
.tcd-am-corridors-num { font-family: 'IBM Plex Mono', monospace; font-size: 0.7rem;
  color: var(--text-tertiary); min-width: 1em; }
/* 2026-09-12 feedback: restored alongside the ledger's return to the card (js/third-country-
   answer-map.js). R5 (points 1 + 2): Nationalities and Source columns dropped -> 3 columns:
   date / flight / people. 2026-09-19 feedback (round 2, item 5): the Aircraft/Avion column
   itself dropped too (security) -> 2 columns: date / people. Header + rows share the grid. */
.tcd-am-ledger .ledger-head { display: grid; grid-template-columns: 82px 1fr;
  gap: 7px; align-items: baseline; font-family: 'IBM Plex Mono', monospace; font-size: 0.6rem;
  text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-tertiary);
  padding: 2px 0 5px; border-bottom: 1px solid var(--border-strong); }
.tcd-am-ledger .ledger-row { display: grid; grid-template-columns: 82px 1fr;
  gap: 7px; align-items: baseline; font-family: 'IBM Plex Mono', monospace; font-size: 0.7rem;
  color: var(--text-secondary); padding: 5px 0; border-top: 1px solid var(--border); }
.tcd-am-ledger a { color: var(--text-primary); text-decoration: underline; text-decoration-color: var(--tcd-am-dest); text-underline-offset: 2px; }

/* ============================================================
   R4/P3c (2026-07-28) — "no colour without a word"
   ------------------------------------------------------------
   Clicking a country fills it blue (deported TO) and fills its origins amber (came FROM);
   nothing on screen said so. Two pieces, both below, both additive:
     1. .tcd-am-kicker   — the two role words over the lit marks, in the same two inks, so the
        graphic teaches itself when the embed pipeline sends it out without this page.
     2. .tcd-am-leader   — a hairline rule for shapes too small to find by adjacency.
   A third piece lived here until R5 (spec §5.1): .tcd-am-sentence and its .tcd-am-s-* parts, the
   colour key written as prose under the headline. Deleted with the element — the key box
   (.tcd-am-key, above) states the same two roles, the dossier names every origin, and the size
   legend carries the at-rest cue.
   Deliberately placed AFTER every rule tests/tcd-fb-css.spec.cjs resolves by substring, and no
   selector here ends in one of those selectors' text, so none of its lookups can be shadowed.
   ============================================================ */

/* --- 1. the on-map role kickers --- */
/* Same small-caps monospace idiom as .tcd-am-country-label, one step smaller so the country
   name stays the dominant line. The paint-order halo is load-bearing here in a way it is not for
   the US label: an amber kicker sits ON its own amber country fill in the West-Africa case, and
   the ground-coloured outline is the only thing separating the two. */
/* The var() FALLBACK is load-bearing, not decoration. third-country/answer-map-embed.html links
   ONLY this stylesheet; --bg-primary is declared in css/main.css :root and in
   #third-country.tcd-theme-light, so on the DARK embed it resolves to nothing, `stroke` is
   invalid at computed-value time, and the halo silently disappears. --tcd-am-home-ink IS the
   country fill (#dda640), so an unhaloed amber kicker on an amber country is 1.00:1 — invisible,
   on the exact page the kickers exist for. Measured 2026-07-28: computed stroke was `none` there.
   (The dark embed has a separate, pre-existing --bg-card problem that blacks out every country
   path; that is escalated elsewhere and deliberately NOT fixed here.) */
/* R4 fix wave (2026-07-28): 8px/3px halo was measured at deviceScaleFactor 1 (what a reader
   actually sees, not the 2x captures the round was reviewed on) and the word collapsed into a row
   of dark smudges — a 3px paint-order stroke puts 1.5px of ground colour on each side of a ~1px
   stem, which closes every counter and every inter-letter gap at that size. 9px type with a 2px
   halo keeps the same small-caps mono idiom while leaving the amber core legible; the ink itself
   is lifted off the country fill it prints on (see --tcd-am-home-ink above). */
.tcd-am-kicker {
  font-family: 'IBM Plex Mono', 'DM Sans', monospace;
  /* 2026-09-09: 9 → 11.7px, +30%, at the desk's request — these two words were getting lost
     in the colour and the fix is to make them carry. Pinned to KICK_PX in
     third-country-answer-map.js, which derives the leading and the glyph advance from it.
     The halo scales with the type (2 → 2.6px): it is a fixed fraction of the stem it protects,
     and holding it at 2px while the type grew would thin it relative to the letterform. */
  font-size: 11.7px; font-weight: 600; letter-spacing: 0.12em;
  paint-order: stroke; stroke: var(--bg-primary, #1A1819); stroke-width: 2.6px; stroke-linejoin: round;
  pointer-events: none; }
.tcd-am-kicker.role-to { fill: var(--tcd-am-target-ink); }
.tcd-am-kicker.role-from { fill: var(--tcd-am-home-ink); }
/* A squelched label takes its kicker down with it — a role word floating beside a name that is
   not there would be worse than the crowding it avoids. The colour is still explained in words:
   R5 (spec §5.1) deleted the header sentence that used to carry that guarantee and moved it into
   the dossier, whose .tcd-am-origins ("Countries of origin") and .tcd-am-taken-to ("Taken to")
   lines name every partner of the selection and are NEVER capped — the sheet scrolls instead.
   That is what licenses squelching a crowded label at all.
   R4 fix wave: this rule used to be unreachable — pass 1 of the placer REMOVED the kicker node
   before the squelch flag could ever be true, so the class was never applied to anything. That
   pass is gone (dropping the role word was itself a defect: colour with a name and no role), so
   the block now squelches whole and this rule does the work its comment always claimed. */
.tcd-am-kicker.squelched { opacity: 0 !important; }

/* --- 2. the sliver leader --- */
/* A rule and nothing else: no terminal dot, which would reintroduce the per-country marker
   Task 7 removed. Drawn inside the counter-scaled mark group, so stroke-width 1 is 1 screen px
   at every zoom; the JS re-derives its far end from map units on each zoom tick. */
.tcd-am-leader { stroke-width: 1; fill: none; pointer-events: none; opacity: 0.9;
  stroke-linecap: round; }
.tcd-am-leader.role-to { stroke: var(--tcd-am-target-ink); }
.tcd-am-leader.role-from { stroke: var(--tcd-am-home-ink); }

@media (max-width: 900px) {
  /* WIDTH. #tcd-container has overflow:hidden and spans 24..351 at a 375px viewport, so it — not
     main's padding — is the real boundary. An earlier revision gave .tcd-am-mapwrap a negative
     margin to escape main's padding; the layout box did widen to 355px, which is what
     getBoundingClientRect reports, but #tcd-container simply CLIPPED it. Nothing got wider, the
     world map lost ~23px off its left edge to the clip, and the header text bled under the same
     clip and had its first letter cut. Do not reintroduce a negative margin here without moving
     or unclipping #tcd-container.
     What actually buys width is dropping the wrapper's own 12px side margins so the map fills the
     container exactly: 299px -> 327px of painted canvas, +9.4% linear / +20% area. */
  .tcd-am-mapwrap { margin: 0; }

  /* FULL-BLEED STAGE (2026-08-06 full-screen round, spec A1). The container itself goes edge
     to edge: calc(50% − 50vw) is inset-independent of main's site-wide 24px padding, and the
     container's own side borders/radius go with it so the map reads as a full-bleed plate
     between two horizontal rules, not a card. #tcd-container's overflow:hidden stays — nothing
     escapes the container any more, so the clipping trap above never fires. */
  #tcd-container { margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw);
    border-left: none; border-right: none; border-radius: 0; }
  /* F3 guard (adversarial review 2026-08-06): 100vw includes the scrollbar on
     classic-scrollbar platforms (a ≤900px desktop window on Windows/Linux with a long
     page), so the full-bleed margins above overshoot by ~half the scrollbar width per
     side and the whole page grows a permanent horizontal scrollbar the moment this tab
     renders. Clip stray horizontal overflow at the page level — body's overflow-x
     propagates to the viewport — scoped with :has() to pages that actually render the
     full-bleed container. Progressive: engines without :has() simply keep today's
     behavior. Vertical scrolling is untouched; in-page horizontal scrollers
     (.table-container etc.) scroll on their own boxes, not the body. */
  body:has(#tcd-container) { overflow-x: clip; }
  .tcd-am-neatline { border-left: none; border-right: none; border-radius: 0; }
  /* STAGE HEIGHT (spec A2). 64px = the sticky tab chrome the scroll rescue already assumes —
     the same 64 as TOP_CLEAR in js/third-country-answer-map.js (renderSelection's scrollBy
     rescue); if the real chrome height ever changes, change both together. svh per repo iOS
     lore (vh resolves against the LARGE viewport under Safari's collapsed toolbars); the vh
     line above it is the fallback for engines without svh. 340px floor = the busflow floor
     (the ≤600px has-busflow rule below) so short viewports and embed iframes degrade to the
     old proportions instead of a sliver. */
  .tcd-answer-map .tcd-am-neatline { height: calc(100vh - 64px); height: calc(100svh - 64px);
    min-height: 340px; }
  /* Desktop keeps height:auto (aspect-slaved); on the fixed-height stage the svg fills it.
     touch-action: pan-y is load-bearing for the Task 5 gesture split (spec B1): the d3
     zoom filter rejects one-finger touches on ≤900px, so d3 never preventDefaults a
     one-finger touchmove and the browser owns vertical scrolling natively. Pinches and
     two-finger drags still reach d3 (the filter passes touches.length >= 2). Taps select
     via the svg-level pointer resolver in third-country-answer-map.js. */
  .tcd-am-svg { height: 100%; touch-action: pan-y; }
  /* Overflow edge fades (2026-08-06 round): the standing "more map this way" signal for the
     rest camera's horizontal crop. Below the key chip / zoom stack (z 15) and above the
     svg; pointer-events:none so they can never eat a pan or a tap. Hidden with the rest of
     the map chrome while the bus diorama covers the stage. */
  .tcd-am-edgefade { display: block; position: absolute; top: 0; bottom: 0; width: 34px;
    opacity: 0; transition: opacity 300ms ease; pointer-events: none; z-index: 12; }
  .tcd-am-edgefade.is-left { left: 0;
    background: linear-gradient(90deg, var(--bg-primary), transparent); }
  .tcd-am-edgefade.is-right { right: 0;
    background: linear-gradient(270deg, var(--bg-primary), transparent); }
  .tcd-am-edgefade.is-on { opacity: 0.85; }
  .tcd-answer-map.has-busflow .tcd-am-edgefade { display: none; }

  /* The header outweighed the map it introduces: 193px of title+search against the map, and 78px
     of that was padding and gaps. Tightened so the map is the largest thing in the tab. The key
     and caption keep their 12px margins, which lands every line — title, search, key, caption —
     on the same 36px vertical. */
  /* 16px sides (was 12px): with the container full-bleed these are now measured from the
     true screen edge — the headline shouldn't kiss the bezel. */
  .tcd-am-head { padding: 10px 16px 8px; gap: 8px; }
  /* .section h3 in main.css (font-size:1rem; margin:1.25rem 0 .75rem) is (0,1,1) and outranks
     .tcd-am-title (0,1,0), so this title never used its own declared size or margins — it carried
     32px of inherited vertical margin, a fifth of the whole header. .tcd-answer-map .tcd-am-title
     is (0,2,0) and wins. Scoped to =<900px: the same bug applies on desktop, out of scope here. */
  .tcd-answer-map .tcd-am-title { font-size: 1rem; line-height: 1.28; margin: 0 0 6px; }
  .tcd-am-search { padding: 5px 10px; font-size: 0.85rem; }
  /* keeps "How we count" on one line in the ~300px column instead of orphaning "count" */
  .tcd-am-caption { font-size: 0.72rem; }

  .tcd-am-head { align-items: stretch; }
  .tcd-am-searchwrap { flex-basis: 100%; }
  .tcd-am-results { right: auto; left: 0; }

  /* R5 mobile fix (2026-07-29): two problems with the map key on a 375px map, confirmed by
     screenshot. (1) At rest, the box sized for a wide desktop map was tall enough to smother a
     ~180px-tall mobile map and overlap .tcd-am-zoomctl (bottom-left, 22px/46px) below it — R5
     round 2 first tried shrinking it (padding/font/max-width), superseded 2026-08-05 below by
     moving it off the canvas entirely. (2) On selection the dossier becomes the fixed bottom
     sheet below, which covers this box entirely — so the box is hidden outright here, and
     renderSelection() mounts the same colour-caption rows (built by the one shared captionRows()
     function) at the top of the sheet instead, via .tcd-am-dossier-key below. */
  /* The overlay key is gone from the canvas here in BOTH its states: at rest the size key now
     lives below the map (.tcd-am-mobilekey), and on selection the colour caption already moves
     into the dossier sheet as .tcd-am-dossier-key. */
  .tcd-am-key { display: none; }
  /* 2026-08-06 full-screen round, Tasks 1+6: the below-map strip becomes an ON-canvas
     overlay chip, top-left of the stage (a strip below a 100svh stage would be off-screen
     while the map is on screen), with the same pill treatment as the desktop .tcd-am-key.
     pointer-events:none — taps fall through to the map; the chip is data, not a control.
     Ratio-preserving rings unchanged (2026-08-05 D2 is NOT reversed). It stays up during a
     selection — the sheet carries the colour key, the chip carries size; they never meet. */
  .tcd-am-mobilekey { display: flex; position: absolute; top: 10px; left: 10px; z-index: 15;
    /* The chip is contracted to the stage's top-left QUADRANT (asserted in
       tcd-r5-editorial.spec.cjs), so its width cap is half the stage minus its own offset —
       not a pixel constant tuned to one phone. A flat 178px, which is what growing the type
       first suggested, clears 375px by a single pixel and fails the quadrant. */
    margin: 0; padding: 5px 8px; pointer-events: none;
    max-width: min(178px, calc(50% - 12px));
    background: color-mix(in srgb, var(--bg-card) 92%, transparent);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
    border: 1px solid var(--border); border-radius: 8px; }
  /* The strip's duplicate reset dies (Task 6): one reset, in the zoom stack, always
     reachable. The element stays in the DOM for desktop-suite indifference. */
  .tcd-am-mobilekey-reset { display: none; }

  /* The chip wraps so the Layers row lands under the size key rather than beside it; a
     100% basis is what puts it there without wrapping the DOM in a second element and
     re-teaching the rings/label rules where they live. */
  .tcd-am-mobilekey { flex-wrap: wrap; }
  /* French edition (I1): the EN/Français switch mirrored into the chip, because .tcd-am-key
     — its only other mount — is display:none at this width. Same full-row basis as
     .tcd-am-layersbtn above, so it stacks under the Layers row rather than crowding it, and
     the same opt-back-in to pointer events (the chip itself is pointer-events:none). The
     type steps down a touch from the desktop 0.85em: the chip's width cap is
     min(178px, 50% - 12px) and "EN / Français" has to clear it on a 375px stage. */
  /* The chip stays pointer-events:none so taps fall through to the map — the control opts
     back in, exactly as the desktop key's controls do. */
  .tcd-am-layersbtn { display: flex; flex: 0 0 100%; align-items: center; gap: 7px;
    box-sizing: border-box;
    min-height: 32px; margin: 6px 0 0; padding: 4px 2px 0; pointer-events: auto;
    background: none; border: none; border-top: 1px solid var(--border);
    font: inherit; font-size: 0.78rem; color: var(--text-secondary);
    text-align: left; cursor: pointer; }
  .tcd-am-layersbtn-label { flex: 1 1 auto; }
  .tcd-am-layersbtn-chev { font-size: 0.9rem; line-height: 1;
    transition: transform 0.15s ease; }
  .tcd-am-layersbtn[aria-expanded="true"] .tcd-am-layersbtn-chev { transform: rotate(180deg); }
  .tcd-am-layersbtn:focus-visible { outline: 2px solid var(--tcd-am-dest); outline-offset: 2px; }
  /* A closed chip still reports which layers are on. applyLayers() already writes layers-<key>
     on the host, so this needs no second piece of state — and it drains the same 0.28 the
     desktop key's off rows drain, so the two readings of "off" are one value. */
  .tcd-answer-map:not(.layers-layover) .tcd-am-layersbtn [data-layer="layover"],
  .tcd-answer-map:not(.layers-origins) .tcd-am-layersbtn [data-layer="origins"] { opacity: 0.28; }

  /* Anchored to the STAGE and capped by it. Hanging under the chip read fine on a phone and
     broke in the embed, where a partner gets a 375x177 stage: the panel wanted ~200px, the
     neatline clips, and the second layer was unreachable. Bounded by the stage instead, with
     its own scroll, the rule holds at every size a partner can hand it.

     box-sizing is declared here rather than inherited: the embed pages load embed-tokens.css
     and this file but NOT main.css, so the `* { box-sizing: border-box }` reset that makes
     width:300px mean 300px on the tab is simply absent there — it measured 330px. A component
     that ships into both contexts states its own box model.

     Free of the chip's quadrant cap because it is transient, which is what buys full-size
     labels AND each hint as a line of prose instead of a tap-to-open bubble. */
  .tcd-am-layerpanel:not([hidden]) { display: flex; flex-direction: column;
    position: absolute; top: 10px; left: 10px; z-index: 17; box-sizing: border-box;
    width: min(300px, calc(100% - 20px)); max-height: calc(100% - 20px);
    overflow-y: auto; overscroll-behavior: contain;
    padding: 12px 14px; pointer-events: auto;
    background: color-mix(in srgb, var(--bg-card) 97%, transparent);
    backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
    border: 1px solid var(--border-strong); border-radius: 10px;
    box-shadow: 0 12px 34px var(--shadow-strong); }
  /* The panel covers the chip, so the chip stands down: the reader sees one box expand, not
     two boxes stacked.
     opacity, NOT visibility, and the difference cost an afternoon. This component sets
     `transition: all`, so a visibility change is a TRANSITION — and a transitioning property
     reports its old value until a frame advances it. focus() on the Layers button therefore
     kept being refused after the panel closed, no matter how far it was deferred: neither a
     rAF, a double rAF, nor a synchronous layout read gets past a property that is mid-
     transition. opacity cannot affect focusability at all, so the question does not arise.
     The a11y half of "stood down" is the inert attribute, set from JS — an attribute, applied
     synchronously, with no style pipeline to wait for. */
  .tcd-answer-map.layers-open .tcd-am-mobilekey { opacity: 0; }
  .tcd-am-panel-head { display: flex; align-items: center; gap: 8px;
    margin: 0 0 10px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
  .tcd-am-panel-title { flex: 1 1 auto; font-size: 0.8rem; font-weight: 600;
    letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-tertiary); }
  .tcd-am-panel-close { flex: 0 0 auto; width: 28px; height: 28px; display: grid;
    place-items: center; padding: 0; background: none; border: 1px solid var(--border);
    border-radius: 6px; font: inherit; font-size: 0.8rem; line-height: 1;
    color: var(--text-secondary); cursor: pointer; }
  .tcd-am-panel-close:hover, .tcd-am-panel-close:focus-visible {
    color: var(--text-primary); border-color: var(--tcd-am-dest); }
  .tcd-am-panel-close:focus-visible { outline: 2px solid var(--tcd-am-dest); outline-offset: 2px; }
  .tcd-am-panel-row + .tcd-am-panel-row { margin-top: 12px; padding-top: 12px;
    border-top: 1px solid var(--border); }
  /* Full-width so the whole row is the target, not just the words. */
  .tcd-am-layerpanel .tcd-am-panel-toggle { width: 100%; font-size: 0.85rem;
    color: var(--text-primary); }
  .tcd-am-panel-hint { margin: 4px 0 0; padding-left: 19px; font-size: 0.78rem;
    line-height: 1.45; color: var(--text-secondary); }
  /* The track/knob itself is shared with the desktop legend row now (un-scoped rules
     above .tcd-am-key-layer) — only the reduced-motion exemption for the chip's own
     chevron is mobile-only. */
  @media (prefers-reduced-motion: reduce) {
    .tcd-am-layersbtn-chev { transition: none; }
  }
  /* the opaque bus diorama replaces the map — its chrome stands down with it */
  .tcd-answer-map.has-busflow .tcd-am-mobilekey { display: none; }

  /* Task 1: on narrow viewports the caption is re-parented OUT of the fixed-height neatline
     (placeCaption() in third-country-answer-map.js) so it isn't clipped by the stage frame.
     Under the opaque bus overlay it would dangle below the stage announcing stale methodology —
     coverMap() already aria-hides it; this is the visual half. */
  .tcd-answer-map.has-busflow .tcd-am-caption { visibility: hidden; }

  /* 2026-08-06 full-screen round, Task 6 (reverses 2026-08-05 D3): the three-button zoom
     stack RETURNS on mobile — the one-button reduction was justified by a 160px canvas
     that no longer exists, and +/− restore a single-pointer zoom path in BOTH directions
     (WCAG 2.5.1) without relying on double-tap synthesis. Bottom-right (desktop keeps its
     bottom-left), 34px targets (≥ the WCAG 2.5.8 24px floor). During a selection the
     stack rides ABOVE the 38svh bottom sheet instead of dying under it — one reset,
     always reachable, including while the sheet is up. Hidden under the opaque bus
     diorama (coverMap() also makes it inert there). */
  .tcd-am-zoomctl { left: auto; right: 10px; bottom: 14px; }
  .tcd-am-zoomctl .zbtn { width: 34px; height: 34px; }
  /* The reset control moves to this same bottom-right corner on mobile (34px target,
     bottom:14px — its box tops out at 48px from the bottom). The watermark below is not a
     control, so it stacks ABOVE it instead of sharing the corner, with an 8px gap. The
     caption is re-parented OUT of the neatline on this breakpoint (see the Task 1 comment
     above), so there is nothing below the reset button here for it to clear. */
  .tcd-am-watermark { bottom: 56px; }
  /* F4 (adversarial review 2026-08-06): position: FIXED while the sheet is up, not
     absolute — the absolute stack measured its bottom from the NEATLINE bottom, which on
     short landscape viewports (340px min-height floor > viewport − 64) sits below the
     fold, so the stack cleared the fixed sheet only when the scroll rescue happened to
     land the stage top at exactly 64px and sank under it at any other scroll position.
     The sheet is viewport-fixed; the stack that must ride above it is now measured from
     the same box. No transformed/filtered ancestor exists between here and the viewport
     (a transform would re-anchor fixed positioning; verified in the landscape tests). */
  .tcd-answer-map.has-selection .tcd-am-zoomctl { position: fixed; right: 10px;
    bottom: calc(42vh + 14px); bottom: calc(38svh + 14px); }
  .tcd-answer-map.has-busflow .tcd-am-zoomctl { display: none; }
  /* Appended after .tcd-am-busflow-host in the DOM, so with no rule here it would paint on
     top of the opaque 3D bus scene — same treatment as the reset control just above. */
  .tcd-answer-map.has-busflow .tcd-am-watermark { display: none; }
  /* Same reasoning as .has-selection's zoomctl fix just above: ride above the fixed bottom
     sheet rather than being measured from a neatline bottom that can sit below the fold. */
  .tcd-answer-map.has-selection .tcd-am-watermark { position: fixed; right: 10px;
    bottom: calc(42vh + 56px); bottom: calc(38svh + 56px); }

  /* selection opens as a bottom sheet.
     HEIGHT IS IN svh, NOT vh, and the cap is 38, not 55 — measured on an iPhone (IMG_0843,
     2026-08-06), the 55vh sheet covered the entire map. Two causes: iOS resolves vh against the
     LARGE viewport (Safari's toolbars collapsed), so 55vh of that is ~70% of what is actually on
     screen when the bars are up; and 55% of even the correct viewport leaves less than half the
     screen for the map the sheet is annotating. svh is the small-viewport unit — 38svh is
     guaranteed to leave ~62% of the VISIBLE screen for the map; the vh line above it is the
     fallback for engines without svh. The sheet's content scrolls internally (overflow-y on the
     base rule), and renderSelection() scrolls the map card into the band this leaves free.
     COMPANION CONSTANT: FREE_BAND = 0.58 in js/third-country-answer-map.js is this same fact
     from the map's side (58% ≈ 1 − 38% − drag-handle/breathing) — fitPoints() frames every
     selection into that band and placeLitLabels() refuses to place labels below it. If this
     38svh ever changes, change FREE_BAND with it. */
  .tcd-answer-map.has-selection .tcd-am-dossier { position: fixed; top: auto; left: 0; right: 0; bottom: 0;
    z-index: 60; width: auto; max-height: 42vh; max-height: 38svh; background: var(--bg-card); border: none;
    border-top: 2px solid var(--border); border-radius: 12px 12px 0 0;
    box-shadow: 0 -8px 24px rgba(0,0,0,0.35); padding-top: 10px; }
  /* 2026-09-03: the media block used to be `display: none` here, because it WAS a
     placeholder — a play glyph and the words "Media to come", 225px of empty box in a
     38svh sheet. It now carries the real document, so hiding it would be hiding the
     evidence. What changes on a phone is the SHAPE, not the presence.

     A document becomes a compact row: a small page thumbnail beside its label, ~76px
     tall instead of ~300px. The reader still sees the paper, and the summary, the
     origins list and the flight ledger stay above the fold in the same sheet. This is
     a different layout for a different surface, not the desktop plate shrunk. */
  .tcd-am-media { margin: 10px 0 0; }
  /* The sheet is 38svh and the text is the point of it. A long caption (Eswatini's names
     both clips) is clamped here rather than allowed to push the dossier's own words off
     the bottom; the full text is still in the DOM for assistive tech, and the desktop
     card — which has the room — shows all of it. */
  .tcd-am-media-cap {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
    line-clamp: 2; overflow: hidden;
  }
  /* 2026-09-08: the desk attached two clips AND the agreement to Eswatini, and one of the
     clips is portrait (1080×1920). Stacked at sheet width that made the media block 1.8×
     the 38svh sheet — the card became a media reel with the text pushed off the bottom.
     A sideways row bounded the height at one item, but at 68% of sheet width with three
     items competing for the same cap, each object was a stamp. Panels take that further:
     92% of the width for the one you are looking at, and the cap now buys a clip you can
     actually watch rather than three you cannot.

     align-items: stretch, against the desktop default of start. A grid row is as tall as
     its tallest member either way, so a top-aligned document panel next to a portrait clip
     leaves a block of dead sheet under it — and the document is panel one, the first thing
     the reader sees. Stretching lets the page thumbnail grow into the height the row
     already costs. */
  .tcd-am-media-track.is-multi .tcd-am-doc { height: 100%; }
  /* 2026-09-15 feedback: "make it such that the videos are easier to see" — at the original
     9svh (~76px on a 844px-tall phone), the native <video> control bar alone is ~32-40px,
     leaving barely 40px of actual picture above it. Raised to 16svh (~135px): still well
     inside the sheet's own budget (the sheet's content SCROLLS internally — see the
     overflow-y note on .tcd-am-dossier above — so growing this pushes the agreement/stats
     line further down the scroll, it does not clip or hide it, unlike a fixed-height
     overflow:hidden container would). The sheet is 38svh total; the figure and its caption +
     nav row together still leave comfortable room above the fold for the "to <Country> /
     third country where they were sent" header that precedes them. The phone's win here was
     already WIDTH (68% of the sheet to 92%, +82% of area) and knowing how many objects there
     are, not height — this keeps that and adds height back where the desk asked for it. A
     clip that needs a closer look still goes fullscreen from the native player in one tap. */
  /* The desktop rule lets a clip find its own width so it never paints black bars. At sheet
     scale that backfires: a 1080×1920 clip bounded to a few svh of height resolves narrower
     than the native control bar that has to lay out inside it, so the reader gets a video
     they cannot start. Here the element takes the full panel and the picture is letterboxed
     inside it, which is the one place bars are the lesser cost. */
  .tcd-am-media-track.is-multi .tcd-am-video,
  .tcd-am-media-track.is-multi .tcd-am-photo {
    width: 100%; height: 16svh; aspect-ratio: auto; object-fit: contain; background: transparent;
  }
  /* contain, not the cover this sheet uses elsewhere: Sierra Leone's four panels are
     leaflets — pages of text — and a cropped page is an unreadable one. */
  /* Same override as the desktop rule above, and for the same reason: Mexico's crop pair
     must keep the height-driven, never-cropped sizing the comment below explains, even
     now that a sibling asset makes the track .is-multi. Three classes beat the .is-multi
     rule's tie (source order) and the plain .tcd-am-photo rule below's lower specificity
     either way. */
  .tcd-am-media-track.is-multi .tcd-am-photo-pair {
    width: auto; height: 22svh; max-width: 100%; margin-inline: auto;
  }

  .tcd-am-doc { display: grid; grid-template-columns: 58px 1fr; align-items: stretch; }
  .tcd-am-doc-page { aspect-ratio: auto; height: 100%; min-height: 68px;
    border-right: 1px solid var(--border); }
  /* The fade is a vertical device for a vertical crop. In the row it would sit across the
     thumbnail's short edge and just read as dirt, so it comes off. */
  .tcd-am-doc-page::after { display: none; }
  .tcd-am-doc-cap { flex-direction: column; align-items: flex-start; justify-content: center;
    gap: 2px; border-top: none; padding: 9px 11px; }

  /* 2026-09-08. This used to read `max-height: 30svh; object-fit: cover`, on the reasoning
     that "a photo can be cropped to that cap". It cannot. Mexico's plate is a 2x3 grid of six
     people and its caption names all six in reading order — "José Alejandro, Lorenzo, Anabela,
     Ignacio, Manuel & Haydn" — so cropping to 54% of the frame's height cut the bottom row
     away while the words below still named them. A crop that removes a named person is not a
     layout choice.

     So: contained, never cropped, and sized by height so the plate finds its own width. At
     30svh it was also taking 91% of the sheet — a card that was a photograph with a headline
     on top. 22svh leaves the picture legible and the card readable, and the plate now opens
     the full-size file for anyone who wants to look properly. */
  .tcd-am-photo { height: 22svh; width: auto; max-width: 100%; margin-inline: auto;
    object-fit: contain; }
  .tcd-am-video { --tcd-am-cap: 26svh; }
  .tcd-answer-map.has-selection .tcd-am-dossier::before { content: ''; display: block; width: 44px;
    height: 4px; border-radius: 2px; background: var(--border); margin: 0 auto 8px; }
}
@media (prefers-reduced-motion: reduce) {
  .tcd-am-mark, .tcd-am-name { transition: none !important; }
  .tcd-am-corridor { transition: none; }
  .tcd-am-edgefade { transition: none !important; }
}

/* ============================================================
   Feedback round (2026-07-27) — L3/CSS additions
   Consumes L1 contract selectors: .tcd-am-neatline (C1),
   .tcd-am-country-label (C7), .tcd-am-busflow-host (C3);
   L2 embed-button placement (C2).
   ============================================================ */

/* C1 — Neatline: a clean cartographic frame around the map graphic (SVG + zoom control +
   caption) and the Buses host. F2: this is now the INNER wrapper (nested in .tcd-am-mapwrap),
   so overflow:hidden clips ONLY the map graphic + Buses scene to the radius — the tooltip and
   dossier live on the outer wrapper and are no longer cut off at the frame edge. It fills the
   outer wrapper flush (no margin of its own; the outer carries the horizontal inset). */
.tcd-am-neatline {
  position: relative;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-primary);
}

/* C2 — Embed button: pinned to the top-right corner of #tcd-container, clear of the
   neatline frame and the map marks. L2 makes #tcd-container a positioning context and
   appends the auto-generated .embed-viz-btn as a descendant. Scoped so it never touches
   the inline header/section-heading embed buttons elsewhere. */
#tcd-container { position: relative; }
#tcd-container .embed-viz-btn {
  position: absolute;
  top: 12px;
  right: 14px;
  z-index: 30;
  margin: 0;
}
/* reserve the top-right corner on desktop so the header search never slides under the button.
   F4: widened 116px→140px — the rendered "EMBED THIS" pill (uppercase, icon + text + padding)
   measures ~120–130px, so 116px left it overlapping the header/search. */
@media (min-width: 901px) {
  .tcd-answer-map .tcd-am-head { padding-right: 140px; }
}
/* on narrow screens the header stacks and the title is long — give the button its own
   band above the header so it can't overlap the title text (L5 refines mobile fit) */
@media (max-width: 900px) {
  #tcd-container { padding-top: 40px; }
  #tcd-container .embed-viz-btn { top: 8px; right: 10px; }
}

/* Place-label typography, shared by the map's SVG country labels and the package index's
   HTML gutter. Extracted so the two cannot drift apart: the gutter's whole argument is that
   it is the SAME object the reader just saw on the map, not a lookalike.
   Two sizes deliberately. 9px is right for a label floating on a graphic; in a text column
   next to body copy it is too small to read comfortably, so the UI size steps up while
   family, weight and tracking stay identical — the family is what carries the recognition. */
#third-country {
  --tcd-place-font: 'IBM Plex Mono', 'DM Sans', monospace;
  --tcd-place-weight: 600;
  --tcd-place-tracking: 0.14em;
  --tcd-place-size-map: 9px;
  --tcd-place-size-ui: 11px;
}

/* C7 — Persistent "United States" label over the US landmass. Quiet but legible; a
   subtle ocean-colored halo separates it from the land fill. Non-interactive. */
.tcd-am-country-label {
  font-family: var(--tcd-place-font);
  font-size: var(--tcd-place-size-map); font-weight: var(--tcd-place-weight);
  letter-spacing: var(--tcd-place-tracking); text-transform: uppercase;
  fill: var(--text-tertiary);
  paint-order: stroke; stroke: var(--bg-primary, #1A1819); stroke-width: 2px; stroke-linejoin: round;
  opacity: 0.9; pointer-events: none;
}
/* R4/P2: the US label speaks the map's amber "sent from" hue, overriding the muted
   default above. Scoped to .tcd-am-usmark so it touches only the US instance.
   R4 fix wave: it takes the INK, not the area fill. --tcd-am-home is #e19209 in the light theme,
   which after this rule's own opacity:0.9 blend is 1.99:1 on the land — the faintest label on the
   map, at 9px, well under WCAG 1.4.3 even as large text (which 9px is not). The comment block
   introducing --tcd-am-home-ink says in so many words that the fill tokens fail as small type;
   this label is small type. The ink is #806410 on paper (3.92:1 after the same blend, up from
   1.99:1) and the lifted gold on dark. */
.tcd-am-usmark .tcd-am-country-label { fill: var(--tcd-am-home-ink); }

/* C3 — Buses view host: fills the neatline when Mexico is selected. L1 hides it by
   default and mounts busflow.js (which appends .tcd-busflow-stage / -fallback into it).
   The ported .tcd-busflow-* block below styles that content. */
.tcd-am-busflow-host { position: absolute; inset: 0; z-index: 22; overflow: hidden; }
/* Mexico shows its country card over the bus diorama (select(), 2026-09-03). The dossier's
   base z-index is 20 and the diorama's is 22, and neither the neatline nor the outer wrapper
   opens a stacking context between them, so without this the card renders underneath a
   full-bleed opaque scene and is invisible. Scoped to the bus state so the resting map's
   stacking order is untouched. */
.tcd-answer-map.has-busflow .tcd-am-dossier { z-index: 24; }
.tcd-am-busflow-host[hidden] { display: none; }
.tcd-am-busflow-host > .tcd-busflow-stage { height: 100%; min-height: 0; max-height: none; }

/* F8 — "Back to map": the only pointer/keyboard exit from the opaque bus overlay (the overlay
   hides the map's own zoom/reset controls, and touch devices have no Escape key). Focus lands
   here when the overlay opens (F5). Pinned top-left, above the WebGL stage + its HUD. */
.tcd-am-busflow-back {
  position: absolute; top: 0.9rem; left: 1.1rem; z-index: 6;
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-family: 'Outfit', sans-serif; font-size: 0.76rem; font-weight: 600;
  color: var(--tcd-text, #F6F3EA); background: rgba(20, 17, 17, 0.78);
  border: 1px solid var(--tcd-border, #3a3738); border-radius: 999px;
  padding: 0.36rem 0.9rem; cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.tcd-am-busflow-back:hover { border-color: #D9EF56; background: rgba(30, 27, 25, 0.92); }
.tcd-am-busflow-back:focus-visible { outline: 2px solid var(--accent, #4460D8); outline-offset: 2px; }
.tcd-am-busflow-back[hidden] { display: none; }
/* the ported HUD sits top-left too; drop it below the back-to-map pill in THIS context only */
.tcd-am-busflow-host .tcd-busflow-hud { top: 3.4rem; }

/* F3 — mobile height floor. The host is position:absolute; inset:0, so its height tracks the
   neatline, which at rest is only as tall as the (short) mobile map. Give the neatline a floor
   while the bus view is active so the 3D stage doesn't collapse on phones. The floor mirrors the
   ported mobile stage size — max(60vh, 340px) — so the HUD, caption and corridor legend have the
   same room they were tuned for. (Desktop maps are already tall enough, so this is scoped to
   ≤600px.) */
@media (max-width: 600px) {
  .tcd-answer-map.has-busflow .tcd-am-neatline { min-height: max(60vh, 340px); }
  .tcd-am-busflow-host { min-height: max(60vh, 340px); }
  /* 2026-09-15 feedback: "the label for the Pacific Ocean shows through the pictures
     container ... especially prominent in light mode." Repositioning the label (see its
     lon/lat in third-country-busflow.js) clears .tcd-busflow-hud at every width down to
     600px with a comfortable margin, but .tcd-busflow-hud's own clamp(150px, 21%, 330px)
     floors at a fixed 150px below that — a floor the label's proportional lon/lat anchor
     has no matching floor to track — so a phone-width stage still lands the two close
     enough to touch at the corner. Hiding the label below the floor's own breakpoint is
     simpler and more robust than chasing a second coordinate that clears every width purely
     by geometry: the establishing "which ocean is this" cue is far less useful on a phone
     where the HUD already covers most of the frame the reader would use it to orient. The
     Gulf of Mexico label is untouched — it sits on the opposite side of the frame and has
     never collided with the HUD at any width tested. */
  .tcd-busflow-label-pacific-ocean { display: none; }
}


/* --- Ported verbatim from the busflow worktree css/third-country.css:1512-1647 (C3, T3.7) --- */
/* ================= The Buses — illustrative US–Mexico bus-flow view (#tcd-busflow) =================
   A dark situation-table diorama: the WebGL stage fills the card like the globe does; all copy is
   real HTML positioned over the canvas. Lime = people (counter, roof stripes); red is spent only
   on the border. */
.tcd-busflow { padding: 0; }
.tcd-busflow-stage {
    position: relative; width: 100%;
    height: 70vh; min-height: 420px; max-height: 640px;
    overflow: hidden;
    background: radial-gradient(120% 90% at 50% 18%, #23201f 0%, #191616 58%, #121010 100%);
}
.tcd-busflow-stage canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* HUD column width tracks the scene, not a fixed pixel cap. The WebGL stage scales with its
   own width, so the US slab's left edge sits at a CONSTANT share of the stage — measured at
   388/558/758/878/944px wide, the clear margin before the slab is always 21-23% of stage width.
   The old fixed caps (330px, or 240px under 600px) were wider than that clear zone at every
   stage below ~1400px, so the count's supporting lines printed onto the country (reported
   2026-08-18: 32% of the "third-country nationals bused..." line and 46% of the bus tally sat on
   the slab at 560/390px). Tracking the zone keeps the copy off the slab wherever it can fit; the
   150px floor keeps it readable on a phone, where the clear zone is only ~80px and no wrapping
   would help — there the halo below carries legibility, exactly as it already does for
   .tcd-busflow-srcline. */
.tcd-busflow-hud {
    position: absolute; top: 1rem; left: 1.15rem; z-index: 3; pointer-events: none;
    max-width: clamp(150px, 21%, 330px);
    /* round 2: `bottom` anchors the HUD's bottom edge to the stage's own bottom edge (the
       stage — .tcd-busflow-stage, position:relative — is the containing block, and its height
       is definite: 70vh/420-640px desktop, 60vh/340px floor mobile), so top+bottom together
       give the HUD a real computed height instead of open-ended auto. Needed for the flex
       column below: a flex child can only be made internally scrollable against a height its
       container actually has. Harmless when content is short — unused flex space below the
       content is empty, unpainted space, identical to the old auto-height look.
       2026-09-14 feedback round 3: `bottom: 1rem` put the HUD's own bottom edge UNDER
       .tcd-busflow-srcline (the "Illustrative animation. Data via..." credit line below,
       position:absolute; bottom: 0.55rem; left/right: 1.15rem — the SAME left edge as this
       HUD) instead of above it, so the credit's text sat on top of the HUD's own bottom
       content (a photo, the last line of "Countries of origin"). Reserve room for the
       credit's own height instead: up to two lines at 0.64rem/1.4 line-height (~1.79rem) plus
       its own 0.55rem bottom offset plus a small gap — 2.7rem clears it at every stage width
       this HUD's clamp() spans, with unused space below the HUD's content staying empty and
       unpainted exactly as bottom: 1rem did before. */
    bottom: 2.7rem;
    display: flex; flex-direction: column;
}
/* 2026-09-14 feedback, widened in round 2: the country card's body (container.__tcdSetMedia in
   third-country-busflow.js — photos, the agreement line, the summary, partner stories,
   "Countries of origin", all wrapped in mexicoExtras/.tcd-am-mexico-extras by
   third-country-answer-map.js) lands inside this HUD, which the rule above makes
   pointer-events:none for everything else — restore it on the WHOLE wrapper, or every link in
   it (the carousel's nav/full-size-photo links, the partner-story links) goes dead, not just
   the carousel's own. pointer-events is inherited, so this one declaration covers .tcd-am-media
   nested inside it too; the margin-top that used to sit on .tcd-am-media directly now sits on
   the wrapper, same visual gap since the photos are still the first thing in it. The bundle is
   already sized for the dossier's ~340px width; the HUD's 330px clamp cap is close enough not
   to need its own override.
   `flex: 1 1 auto` + `min-height: 0` make the wrapper the ONE scrollable flex child under the
   HUD's now-definite height (kicker/count/countsub stay fixed above it, full size) — without
   min-height:0 a flex child never shrinks below its content's natural height, which is exactly
   what silently defeated `overflow-y` here and let the origins block (the last, lowest item)
   run past the bottom of .tcd-am-busflow-host's `overflow:hidden` with no way to reach it — a
   real mobile-reachability bug (tests/tcd-r5-editorial.spec.cjs, "375px: Mexico's list is
   inside a sheet the reader can reach"), not just a card layout preference. */
.tcd-busflow-hud .tcd-am-mexico-extras {
    pointer-events: auto; margin-top: 0.9rem;
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
    -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
    /* 2026-09-15 feedback: "the label for the Pacific Ocean shows through the pictures
       container ... especially prominent in light mode." The whole HUD is a transparent
       overlay over the diorama by design (no chrome box over the map — see the comment
       above .tcd-busflow-hud), and only the kicker/count/countsub below got the halo that
       makes that survivable; this block never did. It scrolls (flex/overflow-y above), so
       as the reader scrolls, ANY of its text — not just the media caption that was
       reported — can pass behind a fixed-position diorama label (Pacific Ocean, Gulf of
       Mexico). text-shadow inherits, so setting it once here covers every line. Harder to
       notice in the dark theme, where the diorama's own background is always a hardcoded
       dark gradient (not theme-aware) and this text is already fairly light; in the light
       theme --text-tertiary/--text-primary go dark, so the collision with the label's own
       hardcoded light-beige colour (also not theme-aware) reads at much higher contrast —
       matching "especially prominent in light mode". */
    text-shadow: 0 1px 6px rgba(10, 8, 8, 0.85);
}
.tcd-busflow-kicker {
    font-family: 'Outfit', sans-serif; font-size: 0.68rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.2em; color: var(--tcd-textDim, #a09d94); margin: 0;
}
.tcd-busflow-count {
    font-family: 'Playfair Display', Georgia, serif; font-weight: 700;
    font-size: clamp(2.1rem, 5vw, 3.3rem); line-height: 1; color: #D9EF56;
    font-variant-numeric: tabular-nums; margin: 0.15rem 0 0;
}
.tcd-busflow-countsub {
    font-family: 'Source Serif 4', Georgia, serif; font-size: 0.86rem; line-height: 1.4;
    color: var(--tcd-textDim, #a09d94); margin: 0.3rem 0 0; max-width: 30ch;
}

/* Halo, matching .tcd-busflow-srcline. On a phone the HUD cannot clear the slab by wrapping, so
   these lines have to stay readable where they cross it. Harmless at widths where nothing
   overlaps. */
.tcd-busflow-kicker,
.tcd-busflow-count,
.tcd-busflow-countsub {
    text-shadow: 0 1px 6px rgba(10, 8, 8, 0.85);
}

/* The source credit runs the full width of the stage, and Mexico's south-east corner reaches it —
   so part of this line always prints on the slab. That was survivable while the slab was a
   near-black brown; on the R4 round 2 blue it measured 2.3:1 in the dark theme and 1.75:1 in the
   light one. A step of contrast plus a halo in the stage's own colour keeps the credit readable
   over both the backdrop and the fill without putting a chrome box over the map. */
/* MEXICO 2 (2026-09-09): the footer carries its sources as links now, not as a prose citation
   list. pointer-events on the LINE stays none — it lies across the diorama and must not eat
   drags aimed at the map — so the anchors have to opt back in individually, or the credit is
   visibly a link and does nothing when clicked. On this dark plate the link is marked by an
   underline in the map's own blue rather than a brighter ink: a louder colour would make the
   credit compete with the count above it. */
.tcd-busflow-srclink {
    pointer-events: auto;
    color: inherit; text-decoration: underline;
    text-decoration-color: var(--tcd-am-dest, #6f86e0); text-underline-offset: 2px;
}
.tcd-busflow-srclink:hover, .tcd-busflow-srclink:focus-visible { color: var(--text-primary); }

.tcd-busflow-srcline {
    position: absolute; left: 1.15rem; right: 1.15rem; bottom: 0.55rem; z-index: 3; pointer-events: none;
    font-family: 'DM Sans', 'Inter', sans-serif; font-size: 0.64rem; line-height: 1.4;
    color: var(--tcd-textDim, #c9c5bc); opacity: 0.9; margin: 0;
    text-shadow: 0 1px 3px rgba(10, 8, 8, 0.85);
}

/* Map-annotation type scales WITH the viewport (vw-clamped): the scene scales with width,
   so a fixed-px label that fits at one screen size collides with lots/routes at another.
   With vw type + lon/lat anchors, label layout is the same at every viewport. */
.tcd-busflow-label {
    position: absolute; z-index: 2; transform: translate(-50%, -100%); pointer-events: none;
    font-family: 'DM Sans', 'Inter', sans-serif; letter-spacing: 0.02em;
    font-size: clamp(0.42rem, 0.92vw, 0.7rem);
    white-space: nowrap; color: #cfcabd; text-shadow: 0 1px 4px rgba(10, 8, 8, 0.9);
}
.tcd-busflow-label-onward { font-style: italic; color: #b99a90; }
/* Numbered crossing badges — a single digit in a small circle collides with nothing at
   any viewport; the corridor legend panel maps numbers to city names. */
.tcd-busflow-cnum {
    transform: translate(-50%, -50%);
    display: inline-flex; align-items: center; justify-content: center;
    width: clamp(12px, 1.5vw, 17px); height: clamp(12px, 1.5vw, 17px);
    border-radius: 50%; box-sizing: border-box;
    background: rgba(20, 17, 17, 0.85); border: 1px solid #9a9186;
    font-family: 'Outfit', sans-serif; font-weight: 600;
    font-size: clamp(0.42rem, 0.8vw, 0.6rem); color: #cfcabd;
    letter-spacing: 0; text-shadow: none;
}
/* .tcd-busflow-corridors* retired 2026-09-14: the crossings legend now renders inside the
   country card as .tcd-am-corridors (see css rules near .tcd-am-origins) instead of a HUD
   panel. .tcd-busflow-cnum (the numbered map badges) is unchanged. */
/* The two country names print ON the slabs, so they follow whatever the slabs are painted. R4
   round 2 moved those to the answer map's amber (US) and blue (Mexico) — measured, the old
   #6d655e washed out on both (1.6:1 on the amber, 1.1:1 on the blue: the word "MEXICO" was
   effectively gone). Each label now contrasts against ITS OWN fill, the way an atlas does, rather
   than one ink trying to serve two: dark ink on the amber (9.0:1) and on the light theme's paler
   blue (6.5:1), light ink on the dark theme's deeper blue (4.3:1, where the same dark ink managed
   only 2.8:1). The halo carries the opposite value, so the stem is separated from the fill as
   well as differing from it. */
.tcd-busflow-label-geo {
    font-size: clamp(0.38rem, 0.84vw, 0.64rem); font-weight: 600; letter-spacing: 0.26em;
    text-transform: uppercase; color: #14120f;
    text-shadow: 0 0 3px rgba(255, 255, 255, 0.45);
}
/* Dark theme only: --tcd-am-target is #495ea2 here, deep enough that the label reads better in
   paper-white. The light theme's #7d93d4 does not need it — the geo rule above wins there on
   specificity (the ID selector), which is why there is no light override for this one. */
.tcd-busflow-label-mexico {
    color: #f4f1e8; text-shadow: 0 1px 3px rgba(10, 8, 8, 0.75);
}
.tcd-busflow-label-water {
    font-style: italic; font-size: clamp(0.4rem, 0.87vw, 0.66rem);
    letter-spacing: 0.1em; color: #5f6d74;
}

.tcd-busflow-replay {
    position: absolute; top: 1rem; right: 1.1rem; z-index: 4; cursor: pointer;
    font-family: 'Outfit', sans-serif; font-size: 0.76rem; font-weight: 600;
    color: var(--tcd-text, #F6F3EA); background: rgba(20, 17, 17, 0.72);
    border: 1px solid var(--tcd-border, #3a3738); border-radius: 999px; padding: 0.34rem 0.85rem;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.tcd-busflow-replay:hover { border-color: #D9EF56; background: rgba(30, 27, 25, 0.9); }
.tcd-busflow-replay:focus-visible { outline: 2px solid var(--accent, #4460D8); outline-offset: 2px; }
.tcd-busflow-replay[hidden] { display: none; }

.tcd-busflow-fallback { padding: 2.2rem 1.4rem; max-width: 62ch; }
.tcd-busflow-fallback .tcd-busflow-count { font-size: 2.4rem; }
.tcd-busflow-fallback-body {
    font-family: 'Source Serif 4', Georgia, serif; font-size: 0.95rem; line-height: 1.5;
    color: var(--tcd-text, #F6F3EA); margin: 0.6rem 0 0;
}
.tcd-busflow-fallback-list {
    font-family: 'Outfit', sans-serif; font-size: 0.85rem; color: var(--tcd-textDim, #a09d94);
    margin: 0.7rem 0 0; padding-left: 1.2rem;
}
.tcd-busflow-fallback .tcd-busflow-srcline { position: static; margin-top: 1rem; }

/* Fallback backdrop. renderFallback() (js/third-country-busflow.js) appends its box DIRECTLY to
   .tcd-am-busflow-host and never creates a .tcd-busflow-stage — but the diorama backdrop belongs
   to the stage, and the host itself paints nothing. So whenever three.js is unavailable (no WebGL,
   or the module fails to load) the copy sat bare on top of the answer map, unreadable and with no
   container (reported 2026-08-18). Paint the host only in that case, so the stage path is
   untouched and the fallback keeps its 62ch measure. :has() is already used elsewhere in this
   sheet. Both themes mirror their own .tcd-busflow-stage gradient. */
.tcd-am-busflow-host:has(> .tcd-busflow-fallback) {
    background: radial-gradient(120% 90% at 50% 18%, #23201f 0%, #191616 58%, #121010 100%);
}
/* Clear the absolutely-positioned "Back to map" control. It sits at top:0.9rem and is ~1.8rem
   tall, so it occupies the first ~43px of the host — more than the fallback's own 2.2rem
   padding, and it landed on top of the "THE BUSES" kicker. Only applies inside the host, where
   that button exists; the standalone busflow page keeps the tighter padding. */
.tcd-am-busflow-host > .tcd-busflow-fallback {
    padding-top: 3.6rem;
}
#third-country.tcd-theme-light .tcd-am-busflow-host:has(> .tcd-busflow-fallback) {
    background: radial-gradient(120% 90% at 50% 18%, #f7f3e8 0%, #efe9da 58%, #e3dac7 100%);
}

@media (max-width: 600px) {
    .tcd-busflow-stage { height: 60vh; min-height: 340px; }
    /* HUD width is handled by the clamp() above, which tracks the slab's clear zone. */
    .tcd-busflow-countsub { font-size: 0.78rem; }
    /* MEXICO 4 (2026-09-09): on a phone the country card is a fixed bottom sheet covering the
       lower ~41% of the stage, and it was hiding 100% of the source credits (and, until the
       epilogue caption was removed outright on 2026-09-12, 100% of that too). Attribution is
       not optional, so the credits ride just above the sheet — the offset comes from
       --tcd-sheet-h, published by busflow.js, rather than a guessed constant, because the
       sheet's height changes with its content. The fallback is the pre-measurement value, so a
       stage that never runs the measure still lays out. */
    .tcd-busflow-srcline { font-size: 0.56rem; }
    .tcd-answer-map.has-busflow .tcd-busflow-srcline {
        bottom: calc(var(--tcd-sheet-h, 0px) + 0.3rem);
    }
}
@media (prefers-reduced-motion: reduce) {
    .tcd-busflow-replay { transition: none; }
}

/* ============================================================
   Lane L5 · Mobile + a11y-visual (feedback round, 2026-07-27) — CSS ONLY
   Phase-1 shipped all ARIA/roles/keyboard/inert/focus-management. This block
   is the visual a11y layer: (T5.2) focus-visible rings, (T5.4) 24px minimum
   target sizes, (T5.1) mobile-fit tightening. Contrast (T5.3) is tuned in
   place above (text-caption→text-tertiary; --tcd-am-border darkened).
   ============================================================ */

/* T5.2 — Unified :focus-visible ring for every interactive answer-map control.
   The periwinkle focus token --tcd-am-dest (#7d94f5) clears WCAG 3:1 non-text
   contrast against every surface a control can sit on: 6.25:1 on the map
   (--bg-primary), 5.23:1 on control fills (--bg-card), and 6.35:1 on the Buses
   stage. A 2px width + 2px offset keeps the ring ≥3:1 against BOTH the gap
   (element background) and the surface beyond it. The map marks already carry
   this exact ring (.tcd-am-mark:focus-visible above); these bring the chrome
   controls — zoom, close, chips, search + results, breadcrumb, "how we count",
   and the embed button — up to the same standard (several previously showed
   only a subtle border-color/background shift on focus). */
/* NOTE the var() fallback: the embed button is appended to #tcd-container as a
   SIBLING of .tcd-answer-map, so --tcd-am-dest (declared on .tcd-answer-map) does
   not cascade to it — an unresolved var would invalidate the whole `outline`
   shorthand (→ outline-style:none, no ring). The literal fallback #7d94f5 keeps
   the ring for the embed button while the token drives every in-map control. */
.tcd-am-zoomctl .zbtn:focus-visible,
.tcd-am-mobilekey-reset:focus-visible,
.tcd-am-close:focus-visible,
.tcd-am-result:focus-visible,
/* The map itself takes focus since 2026-09-08 — keyboard +/−/0 replaced the removed zoom
   buttons, and a keyboard reader who cannot see where focus landed cannot use them. */
.tcd-am-svg:focus-visible,
.tcd-am-how:focus-visible,
#tcd-container .embed-viz-btn:focus-visible {
  outline: 2px solid var(--tcd-am-dest, #7d94f5);
  outline-offset: 2px;
}
/* the search field sits flush in the header; a 1px offset hugs its rounded box */
.tcd-am-search:focus-visible {
  outline: 2px solid var(--tcd-am-dest, #7d94f5);
  outline-offset: 1px;
}
/* Upgrade the ported Buses back/replay rings from the low-contrast --accent
   fallback (#4460D8 ≈ 3.2:1 on the dark stage) to the periwinkle focus token
   (≥6:1), so the two exits from the opaque bus overlay show a clearly visible
   ring. (Focus lands on "← Back to map" when the overlay opens — Phase-1 F5.) */
.tcd-am-busflow-back:focus-visible,
.tcd-busflow-replay:focus-visible {
  outline: 2px solid var(--tcd-am-dest, #7d94f5);
  outline-offset: 2px;
}

/* T5.4 — Minimum 24×24px target for the dossier close button (was 28×22px:
   1px under the WCAG 2.2 2.5.8 / EN 301 549 minimum on the short axis). The ✕
   glyph is centred so the larger hit box stays visually tidy.
   Other controls already clear 24px: zoom 28×28, embed 110×26, search ×35,
   chips ×26, Back/Replay ×29. Map data-marks and the inline ledger source
   links are covered by the 2.5.8 exceptions (see completion report). */
.tcd-am-close {
  min-width: 24px; min-height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 2px 6px; line-height: 1;
}

/* T5.1 — Mobile fit (≤600px). The page already has no horizontal overflow at
   375px (the appendix flight table scrolls inside its own container). The one
   internal overrun was the ledger header row inside the bottom-sheet dossier:
   the fixed columns + gaps ran past the sheet's content box. Tighten the fixed
   columns and gap (header + rows share the grid, so both shrink together and
   stay aligned). R5 (points 1 + 2): three columns now, not five. Restored
   2026-09-12 alongside the ledger's return — briefly moot 2026-09-09 to
   2026-09-12 while the ledger itself was gone. 2026-09-19 feedback (round 2,
   item 5): two columns now, not three — the Aircraft/Avion column is gone. */
@media (max-width: 600px) {
  .tcd-am-ledger .ledger-head,
  .tcd-am-ledger .ledger-row {
    grid-template-columns: 68px 1fr;
    gap: 6px;
  }
}

/* ============================================================
   Dark / Light theme toggle — 3rd Country tab only (Task 5)
   ------------------------------------------------------------
   Dark is the site-wide default and is unchanged. Light adds
   .tcd-theme-light to #third-country and swaps in a warm
   "newsprint" palette: warm off-white paper, near-black ink,
   the tab's accent blue deepened for AA on paper, and a single
   dark-gold "data" ink that replaces the dark-mode acid lime.
   Every light-mode rule is scoped under #third-country.tcd-theme-light
   so it never bleeds to other tabs.
   ============================================================ */

/* --- Segmented Dark|Light control (styled for both themes) --- */
.tcd-theme-toggle {
  display: inline-flex; gap: 0; align-items: stretch;
  border: 1px solid var(--border); border-radius: 999px; overflow: hidden;
  margin: 0 0 12px;
}
.tcd-theme-btn {
  appearance: none; -webkit-appearance: none; border: 0; background: transparent;
  cursor: pointer; font: inherit; font-family: 'DM Sans', 'Inter', sans-serif;
  font-size: 0.82rem; letter-spacing: 0.02em; padding: 4px 15px;
  color: var(--text-tertiary); min-height: 32px;
  transition: background 0.15s ease, color 0.15s ease;
}
.tcd-theme-btn + .tcd-theme-btn { border-left: 1px solid var(--border); }
.tcd-theme-btn[aria-pressed="true"] { background: var(--accent); color: #fff; }
.tcd-theme-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .tcd-theme-btn { transition: none; } }

/* --- Light ("newsprint") palette, scoped to the tab only --- */
#third-country.tcd-theme-light {
  /* surfaces — warm paper */
  --bg-primary: #faf8f3;
  --bg-secondary: #f1ede3;
  --bg-card: #ffffff;
  --bg-card-hover: #f4f1e8;
  --bg-accent: #ece7db;
  --bg-tertiary: #f1ede3;
  /* ink */
  --text-primary: #1a1819;
  --text-secondary: #40403c;
  --text-tertiary: #6b6862;
  --text-caption: #6b6862;
  --text-muted: #6b6862;
  /* accent — the tab's blue, deepened for AA text/UI on paper */
  --accent: #3550c8;
  --accent-hover: #2540b0;
  --accent-2: #2f57bd;
  /* rules / borders */
  --border: #d9d4c8;
  --border-strong: #b8b2a4;
  --rule: #1a1819;
  --rule-light: #d9d4c8;
  /* shadows — soft on paper, not the dark-mode near-black */
  --shadow: rgba(40, 36, 30, 0.12);
  --shadow-strong: rgba(40, 36, 30, 0.20);
  /* alias tokens some components read with dark literal fallbacks
     (--tcd-* were never declared; light values below beat the fallback) */
  --tcd-text: #1a1819;
  --tcd-textDim: #6b6862;
  --tcd-surface: #ffffff;
  --tcd-border: #d9d4c8;
  --tcd-bg: #faf8f3;
  --tcd-accent: #3550c8;
  /* answer-map tokens (defaults; also re-set on .tcd-answer-map below).
     Round3 (2026-07-27): --tcd-am-home brightened from a washed-out tan (#d9c39b, S45%)
     to a genuinely vivid mustard-orange (#dda43c, S70%) — on paper, "brighter" means more
     saturated, not lighter; pushing lightness up instead would have driven it toward the
     near-white land fill (#efece3) and made it read as duller, not brighter. Contrast vs.
     land actually improves (1.45:1 → 1.88:1), edging past --tcd-am-target's own 1.86:1 so
     the two shaded-country hues now read as equally present. */
  /* R4/P3a (2026-07-28), second pass: both tokens gain on the saturation axis, not lightness —
     the land here is near-white (#efece3), so any lightness gain reduces presence; these
     deepen as they saturate instead. --tcd-am-target: S +28% (#a1aed6→#7d93d4, contrast vs
     land 1.86→2.54). --tcd-am-home: S +31% (#dda43c→#e19209, contrast vs land 1.88→2.14). */
  --tcd-am-dest: #3550c8;
  --tcd-am-border: #b8b2a4;
  --tcd-am-target: #7d93d4;
  --tcd-am-home: #e19209;
  --tcd-am-layover: #09e163;
  --tcd-am-corridor: #6b7a00;

  background: var(--bg-primary);
  color: var(--text-primary);
}

/* Answer-map hero — the map redeclares --tcd-am-* on .tcd-answer-map itself, so a
   value set only on the section (an ancestor) is overridden by that own declaration.
   Re-set the tokens directly on .tcd-answer-map so the discs / home shading /
   focus rings / ledger link actually flip to the newsprint values. */
#third-country.tcd-theme-light .tcd-answer-map {
  --tcd-am-dest: #3550c8;
  --tcd-am-border: #b8b2a4;
  --tcd-am-target: #7d93d4;
  --tcd-am-home: #e19209;
  --tcd-am-layover: #09e163;
  /* 2026-09-12 Mexico corridor: the dark lime #d9ef56 (11.58:1 on dark land #2a2728) washes out on
     newsprint, so paper takes a deep olive in the same hue family — #6b7a00, 4.03:1 on the light
     land fill #efece3, clear of the 3:1 WCAG 1.4.11 floor for graphics. Measured with
     .claude/tools/wcag_contrast.py. */
  --tcd-am-corridor: #6b7a00;
  /* R4/P3c: --tcd-am-target-ink inherits its var(--tcd-am-dest) definition and resolves to the
     deepened #3550c8 above (7.05:1 on paper), so it needs no override. The amber does: #e19209
     as type is 2.29:1 on newsprint. #806410 is the deep gold this stylesheet already uses for
     "confirmed" status text — same hue family, 5.28:1, and it still reads as "the amber one"
     against the #e19209 country fill it labels. */
  --tcd-am-home-ink: #806410;
}
/* Package index, light theme. --tcd-surface / --tcd-border already flip; only the two brand-red
   uses and the amber gutter need restating, because --tcd-am-home-ink is #806410 on paper — the
   same hex the pipeline's "Signed" band uses. That collision is tolerable HERE and only here:
   a 11px mono label in a text column cannot be confused with a 3px status rule over a block
   of country chips. An earlier draft proposed a full-width amber BAND and was dropped for
   exactly this reason. */
#third-country.tcd-theme-light .tcd-pkg-row.is-origin .tcd-pkg-gutter { color: #806410; }
#third-country.tcd-theme-light .tcd-pkg-gutter { color: var(--tcd-am-dest); }
/* Fix round 1 (2026-09-08, ruling): light-theme mirror of the .is-lit pair at ~line 488/~493.
   Both rules above are ID-scoped (1,2,0 / 1,4,0), which already out-ranks the dark-theme
   .is-lit rules (0,2,0 / 0,4,0) -- so without these, the gutter never lit at all in light
   theme, for either row type. Re-declare .is-lit at matching ID-scoped specificity
   (1,3,0 / 1,5,0) so it wins here too. */
#third-country.tcd-theme-light .tcd-pkg-gutter.is-lit { color: var(--text-primary); }
#third-country.tcd-theme-light .tcd-pkg-row.is-origin .tcd-pkg-gutter.is-lit { color: var(--text-primary); }
/* Land fill: a warm paper-gray, one step off the white cards, so country outlines
   and the ink-filled US landmass read against it. */
#third-country.tcd-theme-light .tcd-am-country { fill: #efece3; }
/* The flat land-fill above (specificity 1,2,0, via the #third-country ID) would
   out-rank the class-only .target/.home rules (0,2,0) at line ~1567 and kill the
   selected/origin-country shading. Re-apply at 1,3,0 so those polygons take their tokens. */
#third-country.tcd-theme-light .tcd-am-country.target { fill: var(--tcd-am-target); }
#third-country.tcd-theme-light .tcd-am-country.home { fill: var(--tcd-am-home); }
/* Country-name labels: swap the dark halo for a paper halo so dark ink labels
   separate from the land instead of muddying against a dark shadow. */
#third-country.tcd-theme-light .tcd-am-name { text-shadow: 0 1px 2px rgba(255, 255, 255, 0.9); }
/* Floating tooltip + dossier ride on the white card surface. */
#third-country.tcd-theme-light .tcd-am-tooltip,
#third-country.tcd-theme-light .tcd-am-dossier { background: var(--bg-card); }
/* Search-result hover: accent tint instead of the dark-mode periwinkle wash. */
#third-country.tcd-theme-light .tcd-am-result:hover,
#third-country.tcd-theme-light .tcd-am-result:focus-visible {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

/* Negotiation pipeline (#tcd-status) — the per-status hues are dark-mode values
   that fail contrast as text / thin bars on paper. Darken them once via --st (drives
   the band's left rule, dot and count) and directly for the badge / tooltip text. */
#third-country.tcd-theme-light .tcd-status-band-confirmed { --st: #806410; }
#third-country.tcd-theme-light .tcd-status-band-negotiating { --st: #2f57bd; }
#third-country.tcd-theme-light .tcd-status-band-implied { --st: #6a45b0; }
#third-country.tcd-theme-light .tcd-status-band-declined { --st: #b23a34; }
#third-country.tcd-theme-light .tcd-status-band-unknown { --st: #6b6862; }
#third-country.tcd-theme-light .tcd-cf-status-confirmed,
#third-country.tcd-theme-light .tcd-status-tip-confirmed { color: #806410; }
#third-country.tcd-theme-light .tcd-cf-status-negotiating,
#third-country.tcd-theme-light .tcd-status-tip-negotiating { color: #2f57bd; }
#third-country.tcd-theme-light .tcd-cf-status-implied,
#third-country.tcd-theme-light .tcd-status-tip-implied { color: #6a45b0; }
#third-country.tcd-theme-light .tcd-cf-status-declined,
#third-country.tcd-theme-light .tcd-status-tip-declined { color: #b23a34; }
#third-country.tcd-theme-light .tcd-cf-status-unknown { color: #6b6862; }
/* Status hover tooltip: paper card surface (its default mixes --tcd-bg 94% + black
   → near-black); text/borders flip via the alias tokens above. */
#third-country.tcd-theme-light .tcd-status-tip { background: var(--bg-card); }

/* Round2 (2026-07-27) — Mexico bus diorama gets a real light mode. Previously this
   subtree re-pinned --tcd-text/--tcd-textDim/--tcd-border back to their dark literals
   so the whole scene stayed dark under the light toggle; the user asked for Mexico to
   actually go light. The alias tokens now carry newsprint-ink values instead, which
   flips every TEXT rule that already reads them (kicker/countsub/tally/srcline, the
   Back/Replay buttons' text+border) for free. The renderer draws with alpha:true and
   never sets scene.background (js/third-country-busflow.js), so the WebGL canvas is
   transparent — the "sky" the map sits on IS this stage background, no JS needed for
   it. Selectors below cover the handful of rules that use hardcoded dark hex literals
   instead of the alias tokens (the headline count, caption, map labels, crossing
   badges, corridor-legend panel). Dark mode is untouched — this block only fires under
   #third-country.tcd-theme-light. */
#third-country.tcd-theme-light .tcd-am-busflow-host {
  --tcd-text: #1a1819;
  --tcd-textDim: #6b6862;
  --tcd-border: #b8b2a4;
}
/* Stage backdrop: warm parchment in place of the near-black radial gradient. The dark
   country slabs/routes/bus fleet the WebGL scene draws (js/third-country-busflow.js)
   are unchanged — against paper they read as a lit tabletop model, not a night scene. */
#third-country.tcd-theme-light .tcd-busflow-stage {
  background: radial-gradient(120% 90% at 50% 18%, #f7f3e8 0%, #efe9da 58%, #e3dac7 100%);
}
/* Headline counter: the dark-mode acid lime fails badly on paper — swap to the same
   dark-gold "data ink" the negotiation-pipeline panel already uses for this theme. */
#third-country.tcd-theme-light .tcd-busflow-count { color: #806410; }
/* Map labels: dark ink with a paper halo (was pale ink + a black halo, built for the
   near-black stage). */
/* Same paper halo for the HUD column — the dark halo above is built for the near-black stage. */
#third-country.tcd-theme-light .tcd-busflow-kicker,
#third-country.tcd-theme-light .tcd-busflow-count,
#third-country.tcd-theme-light .tcd-busflow-countsub,
#third-country.tcd-theme-light #third-country.tcd-theme-light .tcd-busflow-label {
  color: #40403c; text-shadow: 0 1px 3px rgba(255, 255, 255, 0.9);
}
#third-country.tcd-theme-light .tcd-busflow-label-onward { color: #8a4a3a; }
/* Paper halo + a deeper ink for the same overlap problem (see .tcd-busflow-srcline): 1.75:1 on
   the light theme's blue was the worst reading on the stage. */
#third-country.tcd-theme-light .tcd-busflow-srcline {
  color: #4a4740; text-shadow: 0 1px 3px rgba(255, 255, 255, 0.85);
}
/* Same ink as the dark theme: the two fills it prints on are the SAME tokens the flat map uses,
   and both of the light theme's are bright enough that dark ink is the readable choice. Only the
   halo needs restating, because .tcd-busflow-label above hands it a paper one. */
#third-country.tcd-theme-light .tcd-busflow-label-geo {
  color: #14120f; text-shadow: 0 0 3px rgba(255, 255, 255, 0.5);
}
#third-country.tcd-theme-light .tcd-busflow-label-water { color: #4d6a76; }
/* Numbered crossing badges (map-face chips): paper chip instead of a dark pill. The legend
   panel these used to pair with is gone — see the .tcd-busflow-corridors* retirement note. */
#third-country.tcd-theme-light .tcd-busflow-cnum {
  background: rgba(255, 255, 255, 0.88); border-color: #b8b2a4; color: #40403c;
}
/* Back/Replay pills: paper chip with ink text (color/border already flip via the alias
   tokens above); only the translucent dark fill + hover state need a direct override. */
#third-country.tcd-theme-light .tcd-am-busflow-back,
#third-country.tcd-theme-light .tcd-busflow-replay {
  background: rgba(255, 255, 255, 0.82);
}
#third-country.tcd-theme-light .tcd-am-busflow-back:hover,
#third-country.tcd-theme-light .tcd-busflow-replay:hover {
  border-color: #806410; background: rgba(255, 255, 255, 0.95);
}
/* No-WebGL fallback panel shares the same alias tokens for its body/list text, so it
   already flips; only its (inherited-transparent) card needs no extra rule. */

@media (prefers-reduced-motion: reduce) {
  #third-country.tcd-theme-light, #third-country.tcd-theme-light * { transition: none; }
}

/* ---------- Central America spiderfy (2026-09-13) ----------
   spec: docs/superpowers/specs/2026-09-13-tcn-isthmus-spiderfy-design.md
   At rest the six isthmus destinations hide behind one count badge. The badge is NOT a
   .tcd-am-mark, so every "country mark" rule and suite selector stays untouched. */
.tcd-am-cluster { cursor: pointer; outline-offset: 3px; }
.tcd-am-cluster.is-hidden { display: none; }
.tcd-am-cluster-hit { fill: transparent; pointer-events: all; }
.tcd-am-cluster-segs { fill: var(--bg-primary, #1A1819); fill-opacity: 0.85; stroke: var(--tcd-am-dest); stroke-width: 2; }
.tcd-am-cluster-count { font-family: 'IBM Plex Mono', monospace; font-size: 11px; font-weight: 600;
  fill: var(--text-primary); pointer-events: none; }
.tcd-am-cluster:hover, .tcd-am-cluster:focus-visible { outline: 2px solid var(--tcd-am-dest); }
.tcd-am-cluster:focus:not(:focus-visible) { outline: none; }
.tcd-am-cluster.is-lit .tcd-am-cluster-segs { fill: var(--tcd-am-dest); fill-opacity: 0.35; stroke-width: 2.6; }
.tcd-am-mark.tcd-am-clustered, .tcd-am-labelgroup.tcd-am-clustered { display: none; }

/* Opened: every member's disc fans around the badge, each tied home by a hairline, and the rest of
   the map steps back. A new class, not .dimmed, so selection CSS never sees this state. */
.tcd-am-tether, .tcd-am-tether-home { display: none; pointer-events: none; }
/* .tcd-am-mark circle { pointer-events: all } is (0,1,1); this must out-rank it. */
.tcd-am-mark circle.tcd-am-tether-home { pointer-events: none; }
.tcd-am-mark.tcd-am-fanned .tcd-am-tether { display: inline; stroke: var(--tcd-am-dest); stroke-width: 1; stroke-opacity: 0.8; }
.tcd-am-mark.tcd-am-fanned .tcd-am-tether-home { display: inline; fill: var(--text-primary); }
.tcd-answer-map.has-cluster-open .tcd-am-mark:not(.tcd-am-fanned),
.tcd-answer-map.has-cluster-open .tcd-am-labelgroup:not(.tcd-am-fanned),
.tcd-answer-map.has-cluster-open .tcd-am-corridor,
.tcd-answer-map.has-cluster-open .tcd-am-usmark { opacity: 0.25; pointer-events: none; }
.tcd-answer-map.has-cluster-open .tcd-am-corridor .tcd-am-corridor-hit { pointer-events: none; }
/* .tcd-am-mark circle { pointer-events: all } (0,1,1) wins over the dimming rule above on the
   <g> itself — a child's own explicit pointer-events is not overridden by an ancestor's value
   regardless of the ancestor rule's specificity. Restate it on the circle descendant so a
   dimmed disc/hit-target (Ecuador's or Bhutan's undated hit, Mexico's land hit, any ordinary
   flight disc not part of this cluster) truly stops taking clicks while the fan is open. (0,4,1),
   verified live: without this a dimmed Ecuador disc still opened its card through the fan.
   .tcd-am-layover triangles and .tcd-am-name text set no pointer-events of their own, so they
   already inherit "none" from the dimmed ancestor and need no restatement here. */
.tcd-answer-map.has-cluster-open .tcd-am-mark:not(.tcd-am-fanned) circle { pointer-events: none; }
/* A declared total's drawn disc ignores the pointer at its true position, where the small
   .tcd-am-undated-hit circle keeps Guatemala's r≈50 disc from swallowing Belize. Fanned, it sits
   clear of every neighbour, so the whole disc takes the click (2026-09-13 desk feedback: "no place
   to click"). (0,3,1) out-ranks .tcd-am-mark circle.tcd-am-disc-undated (0,2,1). */
.tcd-am-mark.tcd-am-fanned circle.tcd-am-disc-undated { pointer-events: all; }
.tcd-answer-map.has-cluster-open .tcd-am-labelgroup.tcd-am-fanned .tcd-am-name { opacity: 1; fill: var(--text-primary); }
/* A fanned member's box includes its tether, so a group outline draws a rectangle out to the hub.
   Mouse focus shows nothing; keyboard focus rings the disc itself. (0,4,0)/(0,3,0) out-rank
   .tcd-am-mark:focus-visible (0,2,0); the disc rule (0,4,0) out-ranks .tcd-am-mark.selected and
   .tcd-am-mark.is-lit .tcd-am-disc (0,3,0). */
.tcd-am-mark.tcd-am-fanned:focus:not(:focus-visible),
.tcd-am-mark.tcd-am-fanned:focus-visible { outline: none; }
.tcd-am-mark.tcd-am-fanned:focus-visible .tcd-am-disc { stroke: var(--text-primary); stroke-width: 2.5; }
/* Shaded origin land under the open fan belongs to the dimmed map: a click falls through to the
   <svg>, whose empty-click closes the fan. No other rule sets pointer-events on .tcd-am-country. */
.tcd-answer-map.has-cluster-open .tcd-am-country { pointer-events: none; }
/* While open only the painted ring (r 13) closes by mouse — the invisible r 17 hit ring would take
   the inner rim of the fanned discs nearest the hub. Touch is unaffected: the resolver uses distance. */
.tcd-answer-map.has-cluster-open .tcd-am-cluster-hit { pointer-events: none; }
/* Hover, for the same reason as focus above: a group outline boxes the tether out to the hub, so a
   fanned member lights its disc instead. (0,3,0) beats .tcd-am-mark:hover and .tcd-am-mark.tcd-am-hover
   (0,2,0); the disc rule (0,4,0) beats .tcd-am-mark.selected / .is-lit .tcd-am-disc (0,3,0). */
.tcd-am-mark.tcd-am-fanned:hover, .tcd-am-mark.tcd-am-fanned.tcd-am-hover { outline: none; }
.tcd-am-mark.tcd-am-fanned:hover .tcd-am-disc,
.tcd-am-mark.tcd-am-fanned.tcd-am-hover .tcd-am-disc { stroke: var(--text-primary); stroke-width: 2.5; }
/* While the fan is open the key panel steps back like the rest of the map: at desktop widths the
   fanned and ring names run under it. (0,3,0) beats .tcd-am-key (0,1,0), which carries no transition
   and is already pointer-events:none at rest (its switches opt back in on their own). */
.tcd-answer-map.has-cluster-open .tcd-am-key { opacity: 0.15; pointer-events: none; }
/* M3 (final review 2026-09-17) — specificity trap, the same one this repo's memory already
   documents. */
