/* ============================================================================
 * Vantage 瞭望台 — global strategic infrastructure & activity map
 * Palette per docs/prompts/vantage.md §2 and memory brand-specenvoy:
 *   navy/blue base · gold-amber for detail · orange #f37021 is the FIELD colour and
 *   never sits beside gold in one visual unit (so: live layer only)
 *   NO artificial green or teal anywhere (owner rule)
 * ========================================================================== */

#vantage {
  --v-sea: #0a1222;
  --v-sea-deep: #060d1a;
  --v-land: #141d31;
  --v-land-hi: #1b263e;
  --v-border: #2c3a57;
  --v-grat: #17203a;
  --v-gold: #e8b04b;
  --v-gold-dim: #8a6a2c;          /* BORDERS + focus rings only — non-text, 3:1 applies */
  /* Gold as TEXT. --v-gold-dim is 3.34:1 worst case, which fails AA for the 10–11.5px
     labels it was used on (incl. the official-vs-estimate distinction on range rings,
     where the colour carries meaning). 4.50:1 worst case. */
  --v-gold-txt: #a98237;
  --v-live: #f37021;
  --v-panel: rgba(9, 15, 28, 0.94);
  --v-panel-solid: #0b1120;
  --v-edge: #223050;
  --v-ink: #e6edf8;
  --v-mute: #8d9cb8;
  /* ⚠ AA: this renders 10–11.5px body text — the ◇ weak/approx caveats, the fact-list
     labels, the range-ring scope note. Small text needs 4.5:1, not 3:1. #64738d gave
     3.50:1 on --v-land. Measured worst case now 4.52:1. Do not darken it back. */
  --v-mute2: #7485a4;
  position: relative;
  border: 1px solid var(--v-edge);
  border-radius: 12px;
  overflow: hidden;
  background: var(--v-sea-deep);
  color: var(--v-ink);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------ canvas */

.v-stage { position: relative; width: 100%; height: 70vh; min-height: 460px; touch-action: none; }
#vantage.v-full .v-stage { height: 100vh; }
.v-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; cursor: grab; }
.v-canvas.v-drag { cursor: grabbing; }

/* ------------------------------------------------------------------ panels */

.v-panel {
  position: absolute; z-index: 4;
  background: var(--v-panel);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  border: 1px solid var(--v-edge);
  border-radius: 10px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.5);
}

/* Left rail — layers. Deliberately NOT full height: the language switcher lives in
 * the page top bar, and a fixed full-height panel over it is the trap recorded in
 * memory reference-deeplink-language-carry. */
.v-layers { top: 12px; left: 12px; width: 236px; max-height: calc(100% - 84px); overflow-y: auto; overscroll-behavior: contain; }
.v-layers h3 { margin: 0; padding: 11px 13px 8px; font-size: 11px; letter-spacing: .13em; text-transform: uppercase; color: var(--v-mute2); font-weight: 600;
  display: flex; align-items: center; gap: 8px; position: sticky; top: 0; background: var(--v-panel-solid); z-index: 1; }
.v-layers h3 .v-lt { flex: 1 1 auto; }
.v-railtoggle { flex: 0 0 auto; width: 22px; height: 22px; border: 1px solid var(--v-edge); background: rgba(0,0,0,.3);
  color: var(--v-mute); border-radius: 5px; cursor: pointer; font-size: 12px; line-height: 1; padding: 0; }
.v-railtoggle:hover { color: var(--v-ink); border-color: var(--v-gold-dim); }
/* Collapsed state: the rail goes away and a compact pill brings it back. */
#vantage.v-railhidden .v-layers { display: none; }
.v-railshow { position: absolute; z-index: 5; top: 12px; left: 12px; }
.v-railshow[hidden] { display: none; }
.v-grp { padding: 0 8px 6px; }
.v-grp-t { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--v-gold-txt); padding: 7px 5px 4px; font-weight: 700; }
.v-lyr { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 6px; border: 0; background: none; color: var(--v-ink); font: inherit; font-size: 12.5px; text-align: left; border-radius: 6px; cursor: pointer; }
.v-lyr:hover { background: rgba(232, 176, 75, 0.09); }
.v-lyr[aria-pressed="true"] { background: rgba(232, 176, 75, 0.13); }
.v-lyr .v-sw { width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto; border: 1px solid rgba(255, 255, 255, .28); background: transparent; }
.v-lyr[aria-pressed="true"] .v-sw { background: var(--dot); border-color: var(--dot); }
.v-lyr .v-nm { flex: 1 1 auto; line-height: 1.3; }
.v-lyr .v-ct { font-size: 10.5px; color: var(--v-mute2); flex: 0 0 auto; }

/* --------------------------------------------- filters + key, inside the rail */

.v-filters { padding: 4px 13px 10px; display: grid; gap: 7px; border-top: 1px solid var(--v-edge); margin-top: 4px; }
.v-fl { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--v-mute2); }
.v-fl .v-fl-t { flex: 0 0 auto; letter-spacing: .06em; text-transform: uppercase; font-weight: 600; }
.v-fl select {
  flex: 1 1 auto; min-width: 0; font: inherit; font-size: 11.5px;
  background: rgba(0,0,0,.34); color: var(--v-ink);
  border: 1px solid var(--v-edge); border-radius: 6px; padding: 3.5px 5px; cursor: pointer;
}
.v-fl select:hover { border-color: var(--v-gold-dim); }
.v-fl select:focus-visible { outline: 2px solid var(--v-gold-dim); outline-offset: 1px; }

.v-legend { border-top: 1px solid var(--v-edge); }
.v-legt {
  width: 100%; text-align: left; border: 0; background: none; cursor: pointer;
  color: var(--v-gold-txt); font: inherit; font-size: 10.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; padding: 9px 13px;
}
.v-legt:hover { color: var(--v-gold); }
.v-legt::after { content: " ▾"; }
.v-legt[aria-expanded="true"]::after { content: " ▴"; }
.v-legbody { padding: 0 13px 11px; }
.v-legbody[hidden] { display: none; }
.v-leg-h { font-size: 10px; letter-spacing: .09em; text-transform: uppercase; color: var(--v-mute2); margin: 8px 0 4px; font-weight: 600; }
.v-leg-r { display: flex; align-items: center; gap: 7px; padding: 1.5px 0; font-size: 11.5px; color: var(--v-mute); line-height: 1.25; }
.v-leg-r canvas { flex: 0 0 auto; }

/* Measure mode: a crosshair says "this click places a point", not "selects a site". */
#vantage.v-measuring .v-canvas { cursor: crosshair; }
.v-meas[aria-pressed="true"] { color: #f37021; border-color: #7a3a12; }
.v-stat.v-culled { color: var(--v-mute2); border-style: dashed; }
.v-stat.v-ccon { color: var(--v-gold); border-color: var(--v-gold-dim); }
.v-stat.v-meason { color: #f2a06a; border-color: #7a3a12; }
.v-lyr.v-loading .v-ct::after { content: "…"; }
.v-lyr .v-livedot { width: 6px; height: 6px; border-radius: 50%; background: var(--v-live); flex: 0 0 auto; animation: v-pulse 1.8s infinite; }
/* ◇ = this layer has a known coverage gap; the title attribute says which. */
.v-lyr .v-gap { color: #e0b070; font-size: 10px; }
@keyframes v-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .25 } }

/* Right rail — the dossier */
.v-dossier { top: 12px; right: 12px; width: 330px; max-height: calc(100% - 84px); overflow-y: auto; overscroll-behavior: contain; display: none; }
.v-dossier.v-open { display: block; }
/* The header is sticky AND the drag handle, so the close control is always on screen
   however far you have scrolled. It used to be absolutely positioned in the scrolling
   panel, which meant it slid out of view as soon as you read past the first fold. */
.v-dh { padding: 12px 44px 10px 14px; border-bottom: 1px solid var(--v-edge); position: sticky; top: 0;
  background: var(--v-panel-solid); z-index: 2; cursor: grab; touch-action: pan-x; user-select: none; }
.v-dh:active { cursor: grabbing; }
.v-dh .v-kicker { font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--v-gold); margin-bottom: 5px; }
.v-dh h4 { margin: 0; font-size: 16.5px; line-height: 1.28; font-weight: 650; }
.v-dh .v-zn { margin: 3px 0 0; font-size: 13px; color: var(--v-mute); }
.v-dclose { position: absolute; top: 10px; right: 10px; width: 30px; height: 30px;
  border: 1px solid var(--v-edge); background: rgba(0, 0, 0, .45); color: var(--v-mute);
  border-radius: 8px; cursor: pointer; font-size: 17px; line-height: 1; z-index: 3; }
.v-dclose:hover { color: var(--v-ink); border-color: var(--v-gold-dim); background: rgba(232,176,75,.14); }
.v-dossier { transition: transform .16s ease, opacity .16s ease; }
.v-db { padding: 12px 14px 16px; font-size: 13px; line-height: 1.6; }
.v-db p { margin: 0 0 10px; color: var(--v-ink); }
.v-db .v-auto { color: var(--v-mute); }
.v-facts { display: grid; grid-template-columns: auto 1fr; gap: 5px 11px; margin: 0 0 12px; font-size: 12.5px; }
.v-facts dt { color: var(--v-mute2); }
.v-facts dd { margin: 0; color: var(--v-ink); }
.v-src { margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--v-edge); font-size: 11.5px; color: var(--v-mute); }
.v-src a { color: var(--v-gold); }
.v-src li { margin-bottom: 4px; }
.v-src ul { margin: 5px 0 0; padding-left: 16px; }

/* Chips */
.v-chips { display: flex; flex-wrap: wrap; gap: 5px; margin: 8px 0 12px; }
.v-chip { font-size: 10.5px; padding: 2.5px 7px; border-radius: 20px; border: 1px solid var(--v-edge); color: var(--v-mute); white-space: nowrap; }
.v-chip.v-p-exact { border-color: #4e7d4a00; color: var(--v-gold); border-color: var(--v-gold-dim); }
.v-chip.v-p-site { color: #9db8dd; border-color: #3a4d70; }
.v-chip.v-p-area { color: #c0a882; border-color: #4d4130; }
.v-chip.v-p-approx { color: var(--v-mute2); border-color: var(--v-edge); border-style: dashed; }
.v-chip.v-tierA { color: var(--v-gold); border-color: var(--v-gold-dim); }
.v-chip.v-inactive { color: var(--v-mute2); text-decoration: line-through; }
/* Under construction is the OPPOSITE of not-in-service and must not look like it —
 * amber and dashed, matching the dashed glyph the map draws for the same record. */
.v-chip.v-pending { color: #e0b070; border-color: #4d3a20; border-style: dashed; }
.v-chip.v-weak { border-style: dashed; }

/* ------------------------------------------------------------- top controls */

/* Stacking order, from the back: panels (4) · presets (5) · tooltip (6) · search row (8).
   The search row must outrank the preset row, or the results dropdown falls BEHIND the
   presets and every click on a result is swallowed by a preset button. */
/* The top cluster occupies the space BESIDE the rail rather than the full width. It
   used to be centred on the whole stage, so at a narrow or zoomed viewport the preset
   row wrapped and laid itself straight across the layer list, swallowing its clicks. */
.v-top { position: absolute; z-index: 8; top: 12px; left: 264px; right: 58px; transform: none;
  /* nowrap: when this row wrapped, the Live button dropped onto the preset row below
     and sat on top of a preset. The search field shrinks instead. */
  display: flex; gap: 6px; align-items: center; justify-content: center; flex-wrap: nowrap;
  /* The bar spans a wide strip so its contents stay centred in the space beside the
     rail — but an empty strip that eats clicks is worse than the overlap it replaced.
     Only the actual controls take pointer events. */
  pointer-events: none; }
.v-top > * { pointer-events: auto; }
#vantage.v-railhidden .v-top { left: 128px; }
/* …and clear of the dossier on the right when it is open. */
#vantage.v-dossier-open .v-top { right: 356px; }
.v-search { position: relative; flex: 0 1 300px; min-width: 0; }
.v-search input {
  width: 100%; padding: 7px 11px; font: inherit; font-size: 13px;
  background: var(--v-panel); border: 1px solid var(--v-edge); border-radius: 8px; color: var(--v-ink);
  backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px);
}
.v-search input::placeholder { color: var(--v-mute2); }
.v-search input:focus { outline: none; border-color: var(--v-gold-dim); }
.v-results { position: absolute; top: 100%; left: 0; right: 0; margin-top: 5px; background: var(--v-panel-solid); border: 1px solid var(--v-edge); border-radius: 8px; max-height: 300px; overflow-y: auto; display: none; box-shadow: 0 10px 30px rgba(0, 0, 0, .55); }
.v-results.v-open { display: block; }
.v-results button { display: block; width: 100%; text-align: left; padding: 7px 11px; border: 0; background: none; color: var(--v-ink); font: inherit; font-size: 12.5px; cursor: pointer; border-bottom: 1px solid rgba(34, 48, 80, .5); }
.v-results button:hover, .v-results button.v-cur { background: rgba(232, 176, 75, .12); }
.v-results .v-r2 { font-size: 11px; color: var(--v-mute2); margin-top: 1px; }

.v-btn { padding: 7px 10px; font: inherit; font-size: 12px; background: var(--v-panel); border: 1px solid var(--v-edge); border-radius: 8px; color: var(--v-ink); cursor: pointer; backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px); white-space: nowrap; }
.v-btn:hover { border-color: var(--v-gold-dim); }
.v-btn[aria-pressed="true"] { background: rgba(232, 176, 75, .16); border-color: var(--v-gold-dim); color: var(--v-gold); }
.v-btn.v-live[aria-pressed="true"] { background: rgba(243, 112, 33, .18); border-color: #7d4318; color: var(--v-live); }

/* region presets — sits under the search row, centred with it */
.v-presets { position: absolute; z-index: 5; top: 56px; left: 264px; right: 58px; transform: none;
  display: flex; gap: 5px; flex-wrap: wrap; justify-content: center; pointer-events: none; }
.v-presets > * { pointer-events: auto; }
#vantage.v-railhidden .v-presets { left: 128px; }
#vantage.v-dossier-open .v-presets { right: 356px; }
.v-presets .v-preset { padding: 4.5px 9px; font-size: 11.5px; }

/* bottom-right zoom / view cluster */
.v-zoom { position: absolute; z-index: 5; right: 12px; bottom: 12px; display: flex; flex-direction: column; gap: 5px; }
.v-zoom .v-btn { width: 34px; height: 32px; padding: 0; font-size: 15px; line-height: 1; display: flex; align-items: center; justify-content: center; }

/* bottom-left status strip */
.v-status { position: absolute; z-index: 5; left: 12px; bottom: 12px; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; max-width: calc(100% - 120px); }
.v-stat { font-size: 11px; color: var(--v-mute); background: var(--v-panel); border: 1px solid var(--v-edge); border-radius: 6px; padding: 4px 8px; backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px); }
.v-stat b { color: var(--v-gold); font-weight: 600; }
.v-stat.v-warn { color: #e0b070; border-color: #4d3a20; }

/* hover tooltip */
.v-tip { position: absolute; z-index: 6; pointer-events: none; background: var(--v-panel-solid); border: 1px solid var(--v-edge); border-radius: 6px; padding: 4px 8px; font-size: 11.5px; color: var(--v-ink); white-space: nowrap; display: none; box-shadow: 0 6px 18px rgba(0, 0, 0, .5); }
.v-tip.v-on { display: block; }
.v-tip .v-t2 { color: var(--v-mute2); font-size: 10.5px; }

/* Strategic-family header band — the same generated hex camo as /strategic and the home
   theme card. The radial vignette is not decoration: without it the hero text sits on
   shifting tones and visibly flickers as the eye tracks across it. */
.hex-band {
  background-color: #131c2e;
  background-image: url("/brand/pattern-hex.svg?v=1");
  background-size: 164px auto;
  border: 1px solid #263751;
  border-radius: 16px;
  padding: 26px 24px;
  margin: 0 0 22px;
  position: relative;
  overflow: hidden;
}
.hex-band::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(118% 132% at 50% 0%, rgba(11,17,32,.10) 0%, rgba(11,17,32,.60) 72%, rgba(11,17,32,.80) 100%);
}
.hex-band > * { position: relative; z-index: 1; }
.hex-band .hero-title { margin: 0 0 10px; }
.hex-band .tagline { margin: 0; }
.hex-kicker { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: #8fa8d0; margin: 0 0 9px; font-weight: 600; }
.hex-kicker a { color: #8fa8d0; }

/* ------------------------------------------------------------- below the map */

.v-below { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; margin-top: 20px; }
.v-card { background: #0d1526; border: 1px solid #1e2a44; border-radius: 10px; padding: 15px 17px; }
.v-card h3 { margin: 0 0 9px; font-size: 15px; color: #e8b04b; }
.v-card p { margin: 0 0 9px; font-size: 13.5px; line-height: 1.62; color: #9aa8c2; }
.v-card p:last-child { margin-bottom: 0; }
.v-card strong { color: #dbe4f2; }
.v-card ul { margin: 0 0 9px; padding-left: 18px; font-size: 13.5px; line-height: 1.6; color: #9aa8c2; }
.v-card li { margin-bottom: 6px; }
.v-card.v-wide { grid-column: 1 / -1; }
.v-card a { color: #e8b04b; }
/* Code samples on the API page. Scroll rather than wrap: a wrapped fetch() URL is
   miserable to copy, and the page must never scroll horizontally itself. */
.v-card pre { margin: 0 0 12px; padding: 12px 14px; background: #070d1a; border: 1px solid #1e2a44;
  border-radius: 8px; overflow-x: auto; }
.v-card pre code { display: block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; line-height: 1.62; color: #c3d2ea; white-space: pre; }
.v-card code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px;
  color: #e8b04b; }

/* the precision key */
.v-key { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; }
.v-key div { font-size: 12px; color: #9aa8c2; }
.v-key b { color: #dbe4f2; font-weight: 600; }

/* ---------------------------------------------------------------- responsive */

@media (max-width: 900px) {
  .v-stage { height: 62vh; min-height: 420px; }

  /* MOBILE: the rail is an overlay SHEET and starts closed (see setRail() in the JS).
     On a phone the map is the whole point and a permanent 200px rail eats most of it —
     and, worse, the preset row wrapped to three lines straight over the rail, covering
     its own close button. Now: rail closed by default, presets a single scrolling row,
     and the two are never on screen together. */
  .v-layers { width: min(290px, 78vw); max-height: calc(100% - 96px); }
  .v-railshow { z-index: 9; }

  .v-presets { top: 12px; left: 12px; right: 58px; transform: none; max-width: none;
    flex-wrap: nowrap; overflow-x: auto; justify-content: flex-start;
    scrollbar-width: none; -ms-overflow-style: none; }
  .v-presets::-webkit-scrollbar { display: none; }
  /* Rail open on a phone = presets out of the way entirely. */
  #vantage:not(.v-railhidden) .v-presets { display: none; }
  /* The restore pill sits at top-left; shift the preset row past it when it is showing. */
  #vantage.v-railhidden .v-presets { left: 116px; }
  .v-dossier { width: auto; left: 12px; right: 12px; top: auto; bottom: 56px; max-height: 52%; }
  /* Bottom sheet: give the drag a visible handle, and make the whole header grabbable. */
  .v-dh { padding-top: 18px; touch-action: none; }
  .v-dh::before { content: ""; position: absolute; top: 7px; left: 50%; transform: translateX(-50%);
    width: 36px; height: 4px; border-radius: 2px; background: var(--v-edge); }
  .v-top { top: auto; bottom: 12px; left: 12px; right: 58px; transform: none; }
  #vantage.v-railhidden .v-top { left: 12px; }
  .v-search { flex: 1 1 auto; }
  .v-search input { width: 100%; }
  .v-status { display: none; }
  /* On a phone the presets move to the top-right, clear of the layer rail and of the
     search row that has moved to the bottom. */
  /* On a phone the dossier is a bottom sheet, so the top controls need no right inset. */
  #vantage.v-dossier-open .v-top, #vantage.v-dossier-open .v-presets { right: 58px; }
}
@media (max-width: 560px) {
  .v-layers { width: 172px; }
  .v-layers h3 { padding: 9px 10px 6px; }
  .v-lyr { font-size: 11.5px; }
}

/* kiosk mode for the specenvoy-video capture rig */
body.v-kiosk .topbar, body.v-kiosk .crumbs, body.v-kiosk footer,
body.v-kiosk .hero-title, body.v-kiosk .tagline, body.v-kiosk .v-below, body.v-kiosk .note { display: none !important; }
body.v-kiosk .wrap { max-width: none; padding: 0; margin: 0; }
body.v-kiosk #vantage { border: 0; border-radius: 0; }
body.v-kiosk .v-stage { height: 100vh; }

@media (prefers-reduced-motion: reduce) {
  .v-lyr .v-livedot { animation: none; }
}

/* ------------------------------------------------ screen-reader only content
 * Visually hidden but NOT display:none — it must stay in the accessibility tree and
 * stay focusable. The canvas carries the interaction; this carries the semantics.
 * Focused children become visible so a sighted keyboard user is never lost in an
 * invisible list. */
.v-sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}
.v-sr:focus-within {
  position: absolute; z-index: 20; top: 8px; left: 50%; transform: translateX(-50%);
  width: min(420px, 80%); height: auto; max-height: 60%; overflow-y: auto;
  clip: auto; clip-path: none; white-space: normal; margin: 0;
  padding: 10px 12px; border: 1px solid var(--v-gold-dim); border-radius: 10px;
  background: var(--v-panel-solid); box-shadow: 0 10px 34px rgba(0,0,0,.6);
}
.v-sr h4 { margin: 0 0 6px; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--v-gold-txt); }
.v-sr ul { list-style: none; margin: 0; padding: 0; }
.v-sr li button {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  color: var(--v-ink); font: inherit; font-size: 12px; padding: 4px 6px; border-radius: 5px; cursor: pointer;
}
.v-sr li button:hover, .v-sr li button:focus-visible { background: rgba(232,176,75,.16); outline: none; }
.v-sr .v-sr-more { color: var(--v-mute2); font-size: 11px; margin: 6px 0 0; }
/* The canvas is now focusable — say so visibly. */
.v-canvas:focus-visible { outline: 2px solid var(--v-gold); outline-offset: -2px; }

/* ------------------------------------------------------------- range rings
 * Gold, matching the ring stroke on the canvas, so the control and the mark it draws
 * are visibly the same object. */
.v-rings { margin-top: 12px; border-top: 1px solid var(--v-edge); padding-top: 10px; }
.v-rings-h { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--v-gold-txt); font-weight: 700; margin-bottom: 6px; }
.v-ring { display: flex; align-items: flex-start; gap: 8px; padding: 3px 0; cursor: pointer; font-size: 12.5px; line-height: 1.35; }
.v-ring input { margin-top: 2px; accent-color: var(--v-gold); flex: 0 0 auto; }
.v-ring b { color: var(--v-gold); font-weight: 650; }
.v-ring-b { display: block; font-style: normal; font-size: 10.5px; color: var(--v-mute2); }
/* An operator-stated figure and a number everyone repeats must not look alike. */
.v-ring-b.v-b-official { color: var(--v-gold-txt); font-weight: 700; }
.v-ring-b.v-b-open-estimate { color: var(--v-mute2); font-style: italic; }
.v-ring-n { margin: 2px 0 8px 24px; font-size: 11.5px; color: var(--v-mute); line-height: 1.45; }
.v-ring-scope { margin: 8px 0 0; font-size: 11px; color: var(--v-mute2); line-height: 1.5; border-left: 2px solid var(--v-gold-dim); padding-left: 8px; }

/* ------------------------------------------------------- "how we placed this"
 * Always visible, never a tooltip. The single most important caveat on this map —
 * that 98.6% of records are sourced only to a finding aid — used to be a ◇ glyph with a
 * title attribute, which does not exist on touch and nobody discovers on desktop. */
.v-why { margin-top: 12px; border-left: 2px solid var(--v-edge); padding: 2px 0 2px 10px; }
.v-dq { margin: 6px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--v-mute);
  border-left: 2px solid var(--v-gold-dim); padding-left: 8px; }
.v-dq-t { color: var(--v-gold-txt); font-weight: 700; }
.v-why-h { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--v-mute2); font-weight: 700; margin-bottom: 3px; }
.v-why p { margin: 0; font-size: 11.5px; line-height: 1.55; color: var(--v-mute); }
/* The weak chip is now words, not a glyph, so it needs room to read as a chip. */
.v-chip.v-weak { border-style: dashed; color: var(--v-mute2); }
