:root {
  --bg: #07090c; --panel: rgba(10, 13, 18, 0.72); --line: rgba(255, 255, 255, 0.09); --ink: #e9edf2; --mute: #9aa6b4; --dim: #8a95a3;
  --gold: #f2c46d; --red: #ff5a3c; --blue: #7fb6e8; --before: #8fc1ff; --after: #ffb36b;
  --serif: 'Cormorant Garamond', Georgia, serif; --sans: 'Inter', system-ui, -apple-system, sans-serif;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink); font-family: var(--sans); overflow: hidden; -webkit-font-smoothing: antialiased; }
#gl { position: fixed; inset: 0; width: 100vw; height: 100vh; display: block; }
a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }

.vignette { position: fixed; inset: 0; pointer-events: none; background: radial-gradient(120% 90% at 50% 45%, transparent 55%, rgba(0,0,0,.55) 100%),
  linear-gradient(180deg, rgba(0,0,0,.45) 0%, transparent 18%, transparent 78%, rgba(0,0,0,.6) 100%); }

.title { position: fixed; left: 18px; top: 14px; max-width: 46vw; pointer-events: none; padding: 12px 16px 12px; border-radius: 14px; background: rgba(8,10,14,.66); backdrop-filter: blur(8px); border: 1px solid rgba(255,255,255,.06); }
.eyebrow { font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--gold); font-weight: 600; }
.title h1 { font-family: var(--serif); font-weight: 500; font-size: 44px; line-height: 1.02; margin: 8px 0 6px; letter-spacing: -.01em; text-shadow: 0 2px 24px rgba(0,0,0,.6); }
.title .sub { font-size: 13px; color: #b9c3cf; }

.imgcard { position: fixed; right: 28px; top: 26px; display: flex; gap: 10px; }
.imgcard .s { background: var(--panel); backdrop-filter: blur(10px); border: 1px solid var(--line); border-radius: 10px; padding: 9px 13px; min-width: 210px; opacity: .55; transition: opacity .4s, border-color .4s; }
.imgcard .s.on { opacity: 1; }
.imgcard .s.b.on { border-color: rgba(143,193,255,.6); } .imgcard .s.a.on { border-color: rgba(255,179,107,.6); }
.imgcard .k { font-size: 10px; letter-spacing: .18em; font-weight: 700; }
.imgcard .b .k { color: var(--before); } .imgcard .a .k { color: var(--after); }
.imgcard .d { font-family: var(--serif); font-size: 22px; margin: 2px 0 1px; }
.imgcard .id { font: 10px ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--dim); }

.side { position: fixed; right: 28px; top: 150px; bottom: 120px; width: 340px; display: flex; flex-direction: column; gap: 10px; }
.card { background: var(--panel); backdrop-filter: blur(10px); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.card h3 { margin: 0 0 8px; font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: var(--mute); font-weight: 600; display: flex; justify-content: space-between; }
.events { overflow: auto; flex: 1; min-height: 80px; }
.ev { padding: 8px 0; border-top: 1px solid var(--line); font-size: 12px; line-height: 1.4; }
.ev:first-of-type { border-top: 0; }
.ev .dt { font-weight: 600; color: var(--ink); }
.ev .f { color: #cfd6de; }
.ev .m { color: var(--dim); font-size: 11px; margin-top: 2px; }
.ev.pin .dt::before { content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--red); margin-right: 6px; box-shadow: 0 0 8px var(--red); }
.badge { display: inline-block; font-size: 9.5px; letter-spacing: .06em; padding: 1px 6px; border-radius: 99px; border: 1px solid var(--line); color: var(--mute); margin-left: 4px; text-transform: uppercase; }
.badge.claim { color: #ffb0a0; border-color: rgba(255,90,60,.4); }
.legend { font-size: 11.5px; color: #c9d1da; line-height: 1.5; }
.legend .r { display: flex; gap: 8px; align-items: flex-start; margin: 3px 0; }
.legend i { flex: 0 0 12px; height: 12px; border-radius: 3px; margin-top: 2px; }
.legend small { color: var(--dim); }
.collapse .events, .collapse .legend { display: none; }

.controls { position: fixed; left: 50%; bottom: 44px; transform: translateX(-50%); display: flex; gap: 6px; background: var(--panel); backdrop-filter: blur(10px); border: 1px solid var(--line); border-radius: 999px; padding: 5px; }
.controls button { background: transparent; color: var(--mute); border: 0; border-radius: 999px; padding: 8px 15px; font: 600 12px var(--sans); letter-spacing: .04em; cursor: pointer; }
.controls button:hover { color: var(--ink); }
.controls button.on { background: rgba(255,255,255,.1); color: var(--ink); }
.controls .sep { width: 1px; background: var(--line); margin: 6px 3px; }
.ports { position: fixed; left: 32px; bottom: 44px; display: flex; gap: 4px; flex-wrap: wrap; max-width: 30vw; }
.ports a { font-size: 11px; color: var(--mute); padding: 5px 9px; border: 1px solid var(--line); border-radius: 999px; background: var(--panel); }
.ports a.on { color: var(--ink); border-color: rgba(242,196,109,.5); }

.caption { position: fixed; left: 50%; bottom: 112px; transform: translateX(-50%); text-align: center; max-width: 60vw; pointer-events: none; opacity: 0; transition: opacity .8s; }
.caption.on { opacity: 1; }
.caption .t { font-family: var(--serif); font-size: 30px; line-height: 1.15; text-shadow: 0 2px 20px rgba(0,0,0,.85); }
.caption .s { font-size: 12.5px; color: #c3ccd6; margin-top: 6px; text-shadow: 0 1px 10px rgba(0,0,0,.9); }

.credits { position: fixed; left: 0; right: 0; bottom: 0; padding: 7px 32px; font-size: 10.5px; color: #8893a1; background: linear-gradient(0deg, rgba(0,0,0,.75), rgba(0,0,0,0)); display: flex; justify-content: space-between; gap: 20px; pointer-events: none; }
.credits b { color: #b7c0cb; font-weight: 600; }

.labels { position: fixed; inset: 0; pointer-events: none; }
.lbl { position: absolute; transform: translate(-50%, -100%); white-space: nowrap; max-width: 46vw; font-size: 11px; color: var(--ink); text-shadow: 0 1px 6px rgba(0,0,0,.95); }
.lbl::after { content: ''; position: absolute; left: 50%; top: 100%; width: 1px; height: 26px; background: linear-gradient(rgba(255,255,255,.7), rgba(255,255,255,0)); }
.lbl span { display: inline-block; white-space: normal; padding: 3px 8px; border-radius: 6px; background: rgba(8,10,14,.62); border: 1px solid var(--line); }
.lbl.strike span { border-color: rgba(255,90,60,.65); }
.lbl.strike b { color: #ffb19f; }
.lbl.grain span { border-color: rgba(242,196,109,.45); }
.lbl.wipe { transform: translate(-50%, 0); }
.lbl.wipe::after { display: none; }

.wipebar { position: fixed; top: 0; bottom: 0; width: 2px; background: linear-gradient(180deg, transparent, rgba(255,255,255,.85) 20%, rgba(255,255,255,.85) 80%, transparent); box-shadow: 0 0 18px rgba(255,255,255,.6); pointer-events: none; display: none; }
.wipebar .l, .wipebar .r { position: absolute; top: 38%; font-size: 10px; letter-spacing: .2em; font-weight: 700; white-space: nowrap; }
.wipebar .l { right: 10px; color: var(--before); } .wipebar .r { left: 10px; color: var(--after); }

.loading { position: fixed; inset: 0; display: grid; place-items: center; background: var(--bg); font: 13px var(--sans); color: var(--mute); letter-spacing: .1em; transition: opacity .8s; z-index: 10; }
.loading.done { opacity: 0; pointer-events: none; }
.err { color: #ff8a7a; }
@media (max-width: 900px) { .ports { display: none; } }

/* --- round 2: plain status, satellite findings, amber sites, phone bottom sheet --- */
.title .num { margin-top: 8px; font-size: 12.5px; color: #e8d3a8; max-width: 560px; line-height: 1.45; text-shadow: 0 1px 8px rgba(0,0,0,.9); }
.title .num a { color: #9aa6b4; font-size: 11px; pointer-events: auto; }
.imgcard .id a { color: #8fb3d6; }
.imgcard .note { margin-top: 4px; font: 10.5px var(--sans); color: #c9b48a; max-width: 230px; white-space: normal; }
.status { padding: 8px 10px; margin: 0 0 8px; border-radius: 8px; background: rgba(255,179,71,.09); border: 1px solid rgba(255,179,71,.25); font-size: 12px; line-height: 1.45; }
.status .m, .satf .m { color: var(--dim); font-size: 10.5px; margin-top: 3px; }
.satf { padding: 7px 9px; font-size: 11px !important; margin: 0 0 8px; border-radius: 8px; background: rgba(95,212,255,.07); border: 1px solid rgba(95,212,255,.22); font-size: 11.5px; line-height: 1.45; color: #cfe3ee; }
.satf .h { font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: #8fd8f5; margin-bottom: 3px; }
.satf div + div { margin-top: 4px; }
.ev .v { color: #b9c2cc; font-size: 11.5px; margin-top: 2px; }
.ev.pin.amber .dt::before { background: #ffb347; box-shadow: 0 0 8px #ffb347; }
.lbl.amber span { border-color: rgba(255,179,71,.7); } .lbl.amber b { color: #ffd59a; }
.lbl.sat span { border-color: rgba(95,212,255,.6); color: #d6f2ff; }
.legend details summary { cursor: pointer; font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: var(--mute); font-weight: 600; list-style: none; }
.legend details summary::before { content: '+ '; } .legend details[open] summary::before { content: '− '; }
.legend { flex: 0 0 auto; }
.caption { left: 32px; right: 400px; transform: none; max-width: none; margin: 0 auto; }
.wipecap { position: fixed; left: 32px; right: 400px; bottom: 96px; text-align: center; font-size: 13px; color: #e9edf2; text-shadow: 0 1px 10px rgba(0,0,0,.95); display: none; pointer-events: none; }
.caveat, .sheetbtn, .credbtn { display: none; }
.credits .credbtn { pointer-events: auto; }
@media (max-width: 900px) {
  .title { left: 16px; right: 16px; top: 12px; max-width: none; }
  .title h1 { font-size: 26px; margin: 4px 0 2px; }
  .title .num { font-size: 11.5px; }
  .imgcard { top: auto; bottom: 84px; left: 8px; right: 8px; gap: 6px; }
  .imgcard .long { display: none; }
  .imgcard .s { flex: 1; min-width: 0; padding: 6px 9px; }
  .imgcard .d { font-size: 17px; } .imgcard .id { display: block; font-size: 9.5px; } .imgcard .note { display: none; }
  .controls { bottom: 34px; left: 8px; right: 8px; transform: none; flex-wrap: nowrap; justify-content: space-between; gap: 0; padding: 3px; }
  .controls .sep { display: none; }
  .controls button { padding: 6px 7px; font-size: 10.5px; letter-spacing: 0; white-space: nowrap; }
  .credits { padding: 4px 12px; font-size: 9.5px; display: block; }
  .credits .ctext { display: none; } .credopen .credits .ctext { display: block; background: rgba(0,0,0,.85); padding: 4px 0; }
  .credits .credbtn { display: inline-block; background: none; border: 0; color: #9aa6b4; font: 600 10px var(--sans); text-decoration: underline; padding: 0; }
  .caveat { display: block; position: fixed; left: 16px; right: 16px; bottom: 166px; font-size: 10.5px; color: #c9d1da; text-shadow: 0 1px 6px rgba(0,0,0,.95); text-align: center; pointer-events: none; }
  .sheetbtn { display: block; position: fixed; left: 8px; right: 8px; bottom: 198px; background: var(--panel); backdrop-filter: blur(10px); border: 1px solid rgba(255,179,71,.35); color: var(--ink); border-radius: 10px; padding: 8px 10px; font: 600 11.5px var(--sans); text-align: left; }
  .side { display: flex !important; position: fixed; left: 8px; right: 8px; top: auto; bottom: 100px; width: auto; max-height: 55vh; overflow: auto; transform: translateY(120%); transition: transform .35s; z-index: 5; }
  .side { bottom: 84px; max-height: 58vh; }
  .sheetopen .side { transform: none; } .sheetopen .sheetbtn { bottom: calc(84px + 58vh + 6px); }
  .side .events { flex: none; }
  .caption { left: 16px; right: 16px; bottom: 250px; } .caption .t { font-size: 19px; } .caption .s { font-size: 11px; }
  .wipecap { left: 16px; right: 16px; top: auto; bottom: 250px; font-size: 11.5px; }
  .lbl { font-size: 10px; } .lbl span { white-space: normal; display: inline-block; max-width: 72vw; }
}

/* print still (?clean=1): the scene only */
.clean .title, .clean .imgcard, .clean .side, .clean .controls, .clean .ports, .clean .credits, .clean .caption, .clean .wipecap, .clean .caveat, .clean .sheetbtn, .clean .wipebar, .clean .vignette { display: none !important; }
.clean .lbl.big { font: 600 22px var(--sans); }
.clean .lbl.big span { padding: 7px 16px; border-radius: 9px; background: rgba(8,10,14,.72); border: 1px solid rgba(242,196,109,.7); white-space: nowrap; letter-spacing: .01em; }
.clean .lbl.big::after { height: 46px; width: 2px; background: linear-gradient(rgba(242,196,109,.9), rgba(242,196,109,0)); }
.clean .lbl:not(.big) { display: none !important; }

/* --- round 3: report grade, phone status bar, legible phone text --- */
.status .grade { margin-top: 4px; font-size: 11.5px; color: #ffd9b0; }
.sheetbtn .stl { color: #ffb19f; } .sheetbtn .tap { display: block; font-weight: 400; color: var(--mute); font-size: 12px; margin-top: 2px; }
.satline { display: none; }
.lbl.sat.short span { padding: 1px 6px; font-weight: 700; }
@media (max-width: 900px) {
  .controls button { font-size: 13px; padding: 7px 6px; }
  .caveat { font-size: 12px; bottom: 146px; }
  .lbl { font-size: 12px; } .badge { font-size: 11px; }
  .ev .m, .status .m, .satf .m { font-size: 12px; color: var(--mute); }
  .ev, .ev .v, .satf, .status { font-size: 13px !important; }
  .imgcard .id { display: none !important; } .imgcard .k { font-size: 11px; }
  .credits .credbtn { font-size: 12px; }
  .sheetbtn { font-size: 13px; bottom: 222px; }
  .satline { display: block; position: fixed; left: 12px; right: 12px; bottom: 180px; font-size: 12px; line-height: 1.35; color: #d6f2ff; text-shadow: 0 1px 6px rgba(0,0,0,.95); pointer-events: none; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .caveat { bottom: 146px; }
  .sheetopen .sheetbtn { bottom: calc(84px + 58vh + 6px); }
  .caption { bottom: 330px; } .wipecap { bottom: 330px; font-size: 12px; }
}

@media (max-width: 900px) {
  .eyebrow { font-size: 12px; } .title .num { font-size: 12.5px; } .title .num a { font-size: 12px; }
  .imgcard .k { font-size: 12px; }
}
/* labels keep their natural width (wrap only when longer than the cap), so the screen clamp never squeezes them into a column */
.lbl { width: max-content; max-width: 46vw; }
@media (max-width: 900px) { .lbl { max-width: 74vw; } .lbl span { max-width: 74vw; } }
/* the "i" next to a report count, and its floating explanation (js/tip.js) */
.info { display: inline-grid; place-items: center; width: 15px; height: 15px; margin-left: 5px; border-radius: 50%; border: 1px solid rgba(255,255,255,.45); color: #e9edf2; font: italic 700 10px Georgia, serif; text-transform: none; letter-spacing: 0; cursor: help; vertical-align: 1px; pointer-events: auto; }
.info:hover, .info:focus-visible, .info[aria-expanded="true"] { background: #f2c46d; color: #111; border-color: #f2c46d; outline: none; }
.tipbox { position: fixed; z-index: 100; display: none; padding: 11px 13px; border-radius: 10px; background: rgba(12,15,20,.97); border: 1px solid rgba(242,196,109,.45); box-shadow: 0 8px 30px rgba(0,0,0,.6); font: 400 12.5px/1.5 var(--sans, Inter, system-ui, sans-serif); color: #e1e6ec; text-transform: none; letter-spacing: 0; white-space: normal; }
.tipbox b { color: #fff; }
@media (max-width: 900px) { .info { width: 22px; height: 22px; font-size: 13px; } .tipbox { font-size: 13px; } }

.title .cnt { margin-top: 6px; font-size: 12.5px; color: #dfe5ec; pointer-events: auto; }
.title { pointer-events: auto; }
@media (max-width: 900px) { .title .cnt { display: none; } }

.card h3 .cnote { display: block; margin-top: 4px; font-size: 11px; letter-spacing: 0; text-transform: none; color: var(--mute); font-weight: 400; line-height: 1.4; }
@media (max-width: 900px) { .card h3 .cnote { font-size: 12px; } }

/* round 4 */
.title .satl { margin-top: 4px; font-size: 12px; color: #bfe6f7; }
.title { z-index: 20; } .loading { z-index: 10; }
@media (max-width: 900px) {
  .title .satl { display: none; }
  .wipecap { top: 196px; bottom: auto; }
  .card h3, .card h3 span, .satf .h, .legend details summary, .events h3 span { font-size: 12px; letter-spacing: .1em; }
}

/* round 5 */
.wipecap { background: rgba(10,14,20,.86); padding: 6px 10px; border-radius: 8px; text-shadow: none; }
@media (max-width: 900px) {
  .sheetopen .title { display: none; }
  .wipecap { top: auto; bottom: 330px; }
  .wipebar .l, .wipebar .r { top: auto; bottom: calc(330px + 64px); }
}

/* round 6 */
#evcard > p.cnote { margin: -2px 0 8px; font-size: 11.5px; line-height: 1.4; color: var(--mute); }
@media (max-width: 900px) { #evcard > p.cnote { font-size: 12px; } .satline { display: block; -webkit-line-clamp: unset; overflow: visible; } }   /* G13b: never clamp away a qualifier; check_g9 [6] measures the fit. G14: no clamp at all (a clamp could still cut a qualifier on a longer line): the line takes the lines it needs and fitSheet keeps the status card above it */
/* R6-43: larger small text on laptop */
@media (min-width: 901px) {
  .badge { font-size: 10.5px; }
  .ev .m, .status .m, .satf .m, .credits, .credits .ctext, .imgcard .k { font-size: 11.5px; }
}
/* phone: room for a 3-line satellite line under the sheet button */
@media (max-width: 900px) { .sheetbtn { bottom: max(230px, var(--sbmin, 0px)); } .sheetopen .sheetbtn { bottom: calc(84px + 58vh + 6px); } }   /* G13b: --sbmin set by recon.js fitSheet */

/* round 9: on laptops up to 1366 px the port buttons ran under the Before/Compare/After bar (about 580 px wide, centred): stop them short of it */
@media (min-width: 901px) and (max-width: 1366px) { .ports { max-width: calc(50vw - 330px); } }
/* round 10: a label placed below its marker (no room above it): the leader line points up */
.lbl.flip::after { top: auto; bottom: 100%; background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,.7)); height: 12px; }
/* round 34: the tour caption is a card, not a big title floating over the scene: its heading and its line read as one caption,
   and the scene labels keep off the whole card (recon.js uiRects / bottomFloor) */
.caption { width: fit-content; max-width: calc(100vw - 432px); padding: 9px 18px 10px; border-radius: 12px; background: rgba(8,10,14,.74); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); border: 1px solid rgba(255,255,255,.08); }
.caption .t { font-size: 24px; line-height: 1.2; text-shadow: none; }
.caption .s { margin-top: 5px; text-shadow: none; }
@media (max-width: 900px) { .caption { max-width: calc(100vw - 32px); padding: 7px 12px 8px; bottom: 344px; } .caption .t { font-size: 18px; } }
.wipecap.undercap { display: none !important; }
@media (min-width: 1367px) { .ports { max-width: min(30vw, calc(50vw - 330px)); } }   /* round 34: at 1440 the port buttons still ran 34 px under the control bar */

/* G11: phone tap targets of at least 44 x 44 px (as the globe got in round 34). The bar moves up 14 px and the date cards 4 px, so the
   bar's enlarged hit areas and the 'Sources' hit area under it do not overlap */
@media (max-width: 900px) {
  .controls { bottom: 48px; }
  .imgcard { bottom: 88px; }
  .controls button { position: relative; min-width: 44px; }
  .controls button::after { content: ''; position: absolute; left: 0; right: 0; top: -8px; bottom: -6px; }
  .credits .credbtn { position: relative; }
  .credits .credbtn::after { content: ''; position: absolute; left: -12px; right: -12px; top: -27px; bottom: -6px; }
  .info { position: relative; }
  .info::after { content: ''; position: absolute; inset: -12px; border-radius: 50%; }
}
/* G11: a marker label placed beside its ring (no room above or below it) has no leader line */
.lbl.beside::after { display: none; }
/* G11 (laptop): our satellite-finding labels wrap narrower, so a second one still finds room beside its ring next to the port label */
@media (min-width: 901px) { .lbl.sat { max-width: 26vw; } }
.labels .lead { position: absolute; height: 1px; background: rgba(255,255,255,.7); transform-origin: 0 50%; pointer-events: none; }

/* G13 (phone): where a dated red site label shares the view (Odesa), the port-level label is a little narrower, so it fits beside its ring at 360 px */
@media (max-width: 900px) { .lbl.pl, .lbl.pl span { max-width: 64vw; } }
/* G14: short laptop screens (1366x657), scenes with lettered patches (body.lettered, Izmail A-F): the tour caption card is narrower and sits at the right end of its band (just left of the reports
   panel), so the left part of the scene stays free down to the port buttons: at Izmail the lettered patches A-F the caption points to
   then fit above the cards (recon.js keepRingClear slides the picture into the free part) */
@media (min-width: 901px) and (max-height: 700px) { .lettered .caption { max-width: min(540px, calc(100vw - 432px)); margin: 0 0 0 auto; } }
/* G14: a long caption heading (a port status shown whole, e.g. Novorossiysk 'all three grain terminals halted (12-13 Aug); still suspended
   26 Aug (CGTN); by 30 Sep KSK and NZT operating at reduced rates…') is set in the text face, smaller, so the whole line fits the card */
.caption.long .t { font-family: var(--sans); font-size: 15px; line-height: 1.4; font-weight: 500; }
@media (max-width: 900px) { .caption.long .t { font-size: 13px; line-height: 1.35; } }
