:root {
  --bg: #0f1216; --panel: #161a20ee; --line: #2a313b; --text: #e6e9ee; --muted: #8a94a3;
  --drone: #ffb020; --jet: #ff6a00; --cruise: #ff3b5c; --ballistic: #d946ef; --kab: #22d3ee;
  font: 13px/1.4 -apple-system, BlinkMacSystemFont, "Inter", sans-serif;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text); overflow: hidden;
  overscroll-behavior: none; -webkit-text-size-adjust: 100%; }
#map { position: absolute; inset: 0; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
/* +/- zoom: top corner on the side the panel is NOT on (the right corner while the panel is on the left) */
.maplibregl-ctrl-top-left { top: env(safe-area-inset-top); left: env(safe-area-inset-left); }
@media (min-width: 701px) {
  body.panel-left .maplibregl-ctrl-top-left { left: auto; right: env(safe-area-inset-right); }
  body.panel-left .maplibregl-ctrl-top-left .maplibregl-ctrl { float: right; }
}
/* no overflow:hidden: the toggle sticks out of the left edge; the scrolling tabs clip themselves to the corners */
#panel {
  --gap: max(10px, env(safe-area-inset-right));
  position: absolute; top: max(10px, env(safe-area-inset-top)); right: var(--gap); bottom: max(10px, env(safe-area-inset-bottom));
  width: 360px; display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px; backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px); transition: transform .25s ease;
}
/* collapsed to the right: only the toggle stays on screen, at the window edge */
#panel.collapsed { transform: translateX(calc(100% + var(--gap))); }
/* docked to the left: mirror of the above */
#panel.left { --gap: max(10px, env(safe-area-inset-left)); right: auto; left: var(--gap); }
#panel.left.collapsed { transform: translateX(calc(-100% - var(--gap))); }
#panel.left #panel-toggle { left: auto; right: -24px; border-right: 1px solid var(--line); border-left: 0; border-radius: 0 8px 8px 0; }
#panel.left #panel-toggle svg { transform: rotate(180deg); }
#panel.left.collapsed #panel-toggle svg { transform: none; }
#panel-toggle {
  position: absolute; top: 12px; left: -24px; width: 24px; height: 44px; padding: 0;
  display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--muted);
  background: var(--panel); border: 1px solid var(--line); border-right: 0; border-radius: 8px 0 0 8px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
#panel-toggle:hover { color: var(--text); }
#panel-toggle svg { width: 14px; height: 14px; transition: transform .25s; }
#panel.collapsed #panel-toggle svg { transform: rotate(180deg); }
#panel header { padding: 10px 12px 0; border-bottom: 1px solid var(--line); }
#status { font: 12px/1.4 ui-monospace, Menlo, monospace; color: var(--muted); margin-bottom: 8px; }
#panel header { padding-top: 8px; }
.credits { font-size: 11px; opacity: .8; }
#status .bad { color: #ff7070; font-weight: 600; }
#status .ok { color: #6ee7a0; }
.tabs { display: flex; gap: 4px; }
.tabs button {
  background: none; border: 0; color: var(--muted); padding: 6px 10px; border-bottom: 2px solid transparent;
  cursor: pointer; font: inherit;
}
.tabs button.active { color: var(--text); border-color: var(--text); }
.tabs .help { margin: 0 0 6px auto; width: 24px; height: 24px; padding: 0; flex: none; border: 1px solid var(--line); border-radius: 50%;
  font: 600 12px/22px -apple-system, sans-serif; text-align: center; align-self: center; }
.tabs .help:hover { color: var(--text); border-color: #5a6675; }
.tabs .side { margin-left: auto; display: flex; align-items: center; justify-content: center; }
.tabs .side + .help { margin-left: 6px; }
.tabs .side svg { width: 14px; height: 14px; }
#legend { padding: 0; width: min(420px, calc(100vw - 24px)); max-height: min(80vh, 80dvh); background: #161a20; color: var(--text);
  border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 12px 40px #000a; overflow: hidden; }
#legend[open] { display: flex; flex-direction: column; }
#legend::backdrop { background: #0009; }
.dlg-head { display: flex; justify-content: space-between; align-items: center; padding: 12px 14px 10px; border-bottom: 1px solid var(--line); }
.dlg-head button { background: none; border: 0; color: var(--muted); font-size: 15px; padding: 4px 6px; cursor: pointer; border-radius: 6px; }
.dlg-head button:hover { color: var(--text); background: #ffffff10; }
.dlg-body { overflow-y: auto; padding: 6px 0 10px; scrollbar-width: thin; scrollbar-color: #3a424e transparent; }
.tab { display: none; overflow-y: auto; flex: 1; padding: 6px 0; border-radius: 0 0 9px 9px;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.tab.active { display: block; }

.dot { display: inline-block; width: 12px; height: 12px; border-radius: 50%; background: var(--c); }
.swatch { display: inline-block; width: 22px; height: 12px; border-radius: 2px; }
.legend-row { display: flex; align-items: center; gap: 10px; padding: 5px 12px; }
.note { color: var(--muted); padding: 6px 12px; font-size: 12px; }
.log-item { padding: 7px 12px; border-bottom: 1px solid #ffffff0d; font-size: 12px; }
.log-item .meta { color: var(--muted); font: 11px ui-monospace, Menlo, monospace; }
.log-item .text { white-space: pre-wrap; margin: 2px 0; }
.log-item .parsed { font: 11px ui-monospace, Menlo, monospace; color: #6ee7a0; }
.log-item .parsed.none { color: #ff9b70; }
.empty { color: var(--muted); padding: 16px 12px; }

/* no "position" here: MapLibre places markers with position:absolute + transform; overriding it makes them drift */
/* map icon: the type's silhouette, nose to the course, over a soft glow of the type's colour */
.tm-marker { width: 44px; height: 44px; cursor: pointer; }
.tm-marker::before { content: ""; position: absolute; inset: 4px; border-radius: 50%; transition: opacity .2s, transform .2s;
  background: radial-gradient(circle, color-mix(in srgb, var(--c) 45%, transparent) 0, transparent 68%); }
.tm-marker .glyph { position: absolute; left: 5px; top: 5px; width: 34px; height: 34px; overflow: visible;
  filter: drop-shadow(0 1px 1.5px #000c) drop-shadow(0 0 5px color-mix(in srgb, var(--c) 45%, transparent));
  transition: rotate .4s, scale .2s; }
.tm-marker:hover .glyph, .tm-marker.selected .glyph { scale: 1.14; }
.tm-marker:hover::before, .tm-marker.selected::before { transform: scale(1.25); }
/* selected (popup open): a white ring, like the radar's */
.tm-marker.selected::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 2px solid #fff;
  box-shadow: 0 0 0 1px #0008, inset 0 0 0 1px #0008; }
/* no course known: upright and smaller, inside a dashed ring that slowly turns ("course unknown") */
.tm-marker .ring { position: absolute; inset: 0; width: 44px; height: 44px; display: none; fill: #0b0e13b0;
  stroke: var(--c); stroke-width: 2; stroke-dasharray: 5 3.6; filter: drop-shadow(0 0 2px #000);
  animation: spin 14s linear infinite; }
@keyframes spin { to { rotate: 360deg; } }
.tm-marker.no-heading:not(.silent) .ring { display: block; }
.tm-marker.no-heading:not(.silent) .glyph { scale: .66; }
.tm-marker.no-heading:not(.silent):hover .glyph, .tm-marker.no-heading:not(.silent).selected .glyph { scale: .74; }
/* silent (no news): a ghost — the same silhouette, all grey with a dashed outline, slowly pulsing in opacity.
   Without a known course it is drawn upright */
.tm-marker.silent::before { display: none; }
.tm-marker.silent .glyph { filter: drop-shadow(0 1px 2px #000c); }
.tm-marker.silent { animation: ghost 2.6s ease-in-out infinite; }
@keyframes ghost { 0%, 100% { opacity: .4; } 50% { opacity: .9; } }
@media (prefers-reduced-motion: reduce) {
  .tm-marker.silent, .chip.silent .cb { animation: none; opacity: .6; }
  .tm-marker .ring { animation: none; }
}
/* a group: how many, in a pill at the top right */
.tm-marker .count { position: absolute; top: -2px; right: -6px; min-width: 16px; padding: 0 4px; border-radius: 8px;
  background: #0b0e13; color: #fff; border: 1px solid var(--c); text-align: center;
  font: 700 10px/14px ui-monospace, Menlo, monospace; box-shadow: 0 1px 3px #000a; }
.tm-marker.silent .count { border-color: #8b94a1; color: #c4cad3; }
/* approximate positions are marked with ≈ in the list and popup, not with another ring */
/* ---- target card (the map popup) ---- */
.maplibregl-popup-content { width: 300px; max-width: 320px; padding: 0; border-radius: 12px; color: var(--text);
  background: #151a21; border: 1px solid #ffffff14; box-shadow: 0 14px 40px #000b, 0 2px 6px #0008; font-size: 12px; }
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip, .maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip,
.maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip { border-top-color: #151a21; }
.maplibregl-popup-anchor-top .maplibregl-popup-tip, .maplibregl-popup-anchor-top-left .maplibregl-popup-tip,
.maplibregl-popup-anchor-top-right .maplibregl-popup-tip { border-bottom-color: #151a21; }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: #151a21; }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: #151a21; }
.maplibregl-popup-close-button { top: 12px; right: 10px; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 50%;
  color: var(--muted); font-size: 18px; line-height: 26px; background: none; cursor: pointer; }
.maplibregl-popup-close-button:hover { color: var(--text); background: #ffffff14; }
.maplibregl-popup-close-button:focus { outline: none; }
.maplibregl-popup-close-button:focus-visible { outline: 2px solid #6ee7a0; outline-offset: 1px; }
.pp { padding: 14px 14px 12px; }
.pp-head { display: flex; align-items: center; gap: 11px; padding-right: 24px; }
.pp-icon { width: 40px; height: 40px; flex: none; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle, color-mix(in srgb, var(--c) 32%, #10141a) 0, #10141a 75%);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 45%, transparent); }
.pp-icon svg { width: 32px; height: 32px; overflow: visible; filter: drop-shadow(0 1px 1px #000a); }
.pp-icon.still { box-shadow: none; outline: 1.5px dashed var(--c); outline-offset: -1.5px; }
.pp-icon.still svg { width: 22px; height: 22px; }
.pp.silent .pp-icon { background: #12161c; box-shadow: inset 0 0 0 1px #6b7380; }
.pp-title { flex: 1; min-width: 0; }
.pp-type { font-size: 14px; font-weight: 650; line-height: 1.2; }
.pp-type em { font-style: normal; font-weight: 500; color: var(--muted); margin-left: 6px; }
.pp-course { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; color: var(--muted); font-size: 12px; margin-top: 4px; }
.pp-state { flex: none; padding: 1px 7px; border-radius: 10px; white-space: nowrap;
  font: 600 10px/14px -apple-system, sans-serif; letter-spacing: .2px; }
.pp-state.live { color: var(--c); background: color-mix(in srgb, var(--c) 16%, transparent); }
.pp-state.live::before { content: ""; display: inline-block; width: 6px; height: 6px; margin: 0 5px 1px 0; border-radius: 50%;
  background: currentColor; box-shadow: 0 0 6px currentColor; animation: blink 1.6s ease-in-out infinite; }
@keyframes blink { 50% { opacity: .35; } }
.pp-state.silent { color: #c4cad3; background: #ffffff12; }
/* where: now (or last seen) → the named destination */
.pp-route { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding: 9px 11px; border-radius: 9px;
  background: #0f1318; border: 1px solid #ffffff0d; }
.pp-pt { min-width: 0; flex: 1; }
.pp-pt i, .pp-stats i { display: block; font: normal 600 9.5px/1.2 -apple-system, sans-serif; letter-spacing: .6px;
  text-transform: uppercase; color: #6d7786; }
.pp-pt b { display: block; margin-top: 3px; font-size: 13px; font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
.pp-pt + .pp-arrow + .pp-pt { text-align: right; }
.pp-arrow { flex: none; width: 16px; height: 16px; fill: none; stroke: var(--c); stroke-width: 1.8; stroke-linecap: round;
  stroke-linejoin: round; }
.pp.silent .pp-arrow { stroke: #8b94a1; }
.pp-approx { color: var(--muted); font-weight: 500; }
.pp-warn { margin-top: 8px; padding: 8px 10px; border-radius: 9px; line-height: 1.4; color: #f3dfae;
  background: #ffb0200f; border: 1px solid #ffb02033; }
.pp-warn b { color: #ffd27a; }
.pp-stats { display: grid; grid-template-columns: 1fr 1.3fr .8fr; gap: 8px; margin-top: 10px; padding: 0 2px; }
.pp-stats b { display: block; margin-top: 3px; font: 600 12.5px/1.2 ui-monospace, Menlo, monospace; font-variant-numeric: tabular-nums;
  white-space: nowrap; }
/* the reports this target came from, newest first */
.pp-feed { position: relative; list-style: none; margin: 12px 0 0; padding: 10px 0 0; border-top: 1px solid #ffffff10; max-height: 168px;
  overflow-y: auto; scrollbar-width: thin; scrollbar-color: #3a424e transparent; overscroll-behavior: contain; }
.pp-feed li { position: relative; padding: 0 0 10px 12px; }
.pp-feed li:last-child { padding-bottom: 0; }
.pp-feed li::before { content: ""; position: absolute; left: 0; top: 5px; width: 5px; height: 5px; border-radius: 50%;
  background: color-mix(in srgb, var(--c) 70%, #000); }
.pp-feed li:first-child::before { background: var(--c); box-shadow: 0 0 5px var(--c); }
.pp.silent .pp-feed li::before { background: #6b7380; box-shadow: none; }
.pp-meta { display: flex; gap: 7px; align-items: baseline; color: #6d7786; font-size: 11px; }
.pp-meta time { color: #aeb6c2; font: 600 11px ui-monospace, Menlo, monospace; }
.pp-text { margin-top: 2px; color: #c9cfd8; line-height: 1.4; white-space: pre-wrap; overflow-wrap: anywhere; }


/* ---- radar ---- */
.radar-head { display: flex; justify-content: space-between; align-items: center; padding: 6px 12px; color: var(--muted);
  font: 12px ui-monospace, Menlo, monospace; }
.radar-scale button { background: none; border: 1px solid var(--line); color: var(--muted); border-radius: 4px;
  font: inherit; padding: 1px 6px; cursor: pointer; }
.radar-scale button.active { color: var(--text); border-color: #6ee7a0; }
#radar { cursor: pointer; display: block; margin: 0 auto; width: min(336px, 100%); height: auto; aspect-ratio: 1; }
#loc-bar { display: flex; gap: 6px; padding: 4px 12px 8px; }
#loc-bar button { flex: 1; background: none; border: 1px solid var(--line); color: var(--muted); border-radius: 6px;
  font: inherit; padding: 5px 8px; cursor: pointer; }
#loc-bar button:hover { color: var(--text); border-color: #5a6675; }
#loc-bar.need button { color: #6ee7a0; border-color: #6ee7a0; }
/* targets within 500 km: one row each — icon, name and distance, big ETA on the right */
#radar-list { padding: 2px 6px 10px; }
#radar-list .empty { padding: 10px 6px; }
.chip { all: unset; box-sizing: border-box; width: 100%; cursor: pointer; display: grid; grid-template-columns: 34px 1fr auto auto;
  grid-template-areas: "icon name dist eta" "icon where dist eta"; column-gap: 12px; align-items: center; padding: 9px 8px;
  border-radius: 8px; -webkit-tap-highlight-color: transparent; }
.chip + .chip { box-shadow: 0 -1px 0 #ffffff0d; }
.chip:hover { background: #ffffff0d; box-shadow: none; }
.chip:hover + .chip { box-shadow: none; }
.more { all: unset; box-sizing: border-box; display: block; width: 100%; margin-top: 6px; padding: 8px; text-align: center; cursor: pointer;
  color: var(--muted); font-size: 12px; border-radius: 8px; }
.more:hover { color: var(--text); background: #ffffff0d; }
.chip.selected { background: #ffffff14; box-shadow: inset 0 0 0 1px #ffffff40; }
.chip:focus-visible { outline: 2px solid #6ee7a0; outline-offset: -2px; }
/* list icon: the silhouette on a dark disc tinted with the type's colour */
.chip .cb { grid-area: icon; position: relative; width: 34px; height: 34px; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--c) 30%, #10141a) 0, #10141a 75%);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 40%, transparent);
  display: flex; align-items: center; justify-content: center; }
.chip .cb svg { width: 28px; height: 28px; overflow: visible; filter: drop-shadow(0 1px 1px #000a); }
.chip .cb.still { box-shadow: none; outline: 1.5px dashed var(--c); outline-offset: -1.5px; }
.chip .cb.still svg { width: 20px; height: 20px; }
.chip .cname { grid-area: name; font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chip .cname em { font-style: normal; color: var(--muted); font-weight: 500; }
.chip .cd { grid-area: where; color: var(--muted); font-size: 12px; line-height: 1.3; overflow-wrap: anywhere; }
.chip .cdist { grid-area: dist; display: flex; align-items: baseline; justify-content: flex-end; gap: 3px; min-width: 56px; color: #c3cad4; }
.chip .cdist b { font: 500 18px/1 ui-monospace, Menlo, monospace; letter-spacing: -.5px; font-variant-numeric: tabular-nums; }
.chip .cdist i { font: normal 500 11px/1 -apple-system, sans-serif; color: var(--muted); }
.chip .cnum { grid-area: eta; min-width: 56px; justify-content: flex-end; display: flex; align-items: baseline; gap: 1px; }
.chip .cnum b { font: 600 28px/1 ui-monospace, Menlo, monospace; letter-spacing: -1.5px; font-variant-numeric: tabular-nums; }
.chip .cnum i { font: normal 500 12px/1 -apple-system, sans-serif; color: var(--muted); }
.chip.hot .cnum b { color: #ff6b6b; }
.chip.warm .cnum b { color: #ffb020; }
.chip.away { opacity: .6; }
.chip.silent .cname, .chip.silent .cd, .chip.silent .cdist, .chip.silent .cnum { opacity: .65; }
.chip.silent .cb { background: #12161c; box-shadow: inset 0 0 0 1px #6b7380; animation: ghost 2.6s ease-in-out infinite; }
/* the page's own scroll bars: thin, dark, shown on hover */
.tab { scrollbar-width: thin; scrollbar-color: #3a424e transparent; }
.tab::-webkit-scrollbar { width: 8px; }
.tab::-webkit-scrollbar-track { background: transparent; margin: 6px 0; }
.tab::-webkit-scrollbar-thumb { background: #343b46; border-radius: 4px; border: 2px solid transparent; background-clip: content-box; }
.tab::-webkit-scrollbar-thumb:hover { background: #4a5463; background-clip: content-box; }
.legend-badge { width: 28px; height: 28px; border-radius: 50%; flex: none; display: inline-flex; align-items: center;
  justify-content: center; background: radial-gradient(circle, color-mix(in srgb, var(--c) 30%, #10141a) 0, #10141a 75%);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 40%, transparent); }
.legend-badge svg { width: 24px; height: 24px; overflow: visible; filter: drop-shadow(0 1px 1px #000a); }

#toast { position: absolute; z-index: 5; bottom: max(20px, env(safe-area-inset-bottom)); transform: translateX(-50%);
  display: flex; align-items: center; gap: 14px; padding: 8px 10px 8px 14px; white-space: nowrap;
  background: #161a20f2; border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 4px 16px #0009; }
#toast[hidden] { display: none; }
#toast button { background: none; border: 0; color: #6ee7a0; font: inherit; font-weight: 600; padding: 6px 4px; cursor: pointer; }

/* ---- phones: the panel is a bottom sheet that collapses down to its tab bar ---- */
@media (max-width: 700px) {
  #panel {
    top: auto; width: auto; height: 50vh; height: 50dvh;
    left: max(8px, env(safe-area-inset-left)); right: max(8px, env(safe-area-inset-right));
    bottom: max(8px, env(safe-area-inset-bottom)); transition: none;
  }
  #panel.collapsed { transform: none; height: auto; }
  #panel.collapsed .tab { display: none; }
  #panel.collapsed header { border-bottom: 0; padding-bottom: 4px; }
  /* the toggle becomes a grabber pill on top of the sheet: tap or swipe it */
  .tabs .side { display: none; }
  .tabs .side + .help { margin-left: auto; }
  #panel-toggle { position: static; width: 100%; height: 20px; flex: none; border: 0; border-radius: 10px 10px 0 0;
    background: none; backdrop-filter: none; -webkit-backdrop-filter: none; touch-action: none; }
  #panel-toggle svg { display: none; }
  #panel-toggle::before { content: ""; width: 38px; height: 4px; border-radius: 2px; background: #5a6675; }
  #panel header { padding: 0 6px; touch-action: pan-x; }
  .tabs { overflow-x: auto; scrollbar-width: none; }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs button[data-tab] { flex: 1 0 auto; padding: 10px 6px; white-space: nowrap; }
  .radar-scale button { padding: 4px 8px; }
  /* radar small enough to leave room for the chips */
  #radar { width: min(300px, 100%, 30dvh); }
  #tab-radar.active { display: flex; flex-direction: column; }
  #tab-radar > * { flex: none; }
  .maplibregl-popup-content { width: auto; max-width: min(300px, 86vw); }
}
/* phone in landscape: side panel, but the radar must fit the short height */
@media (min-width: 701px) and (max-height: 500px) {
  #panel { width: 320px; }
  #radar { width: min(336px, 100%, 55dvh); }
}
