/* Wolfpak — design system
   Pure CSS, no build step. */

:root {
  --bg: #0a0c0f;
  --bg-grad: radial-gradient(1200px 800px at 15% -10%, #16202b 0%, transparent 60%),
             radial-gradient(900px 700px at 110% 10%, #1b1508 0%, transparent 55%),
             #0a0c0f;
  --panel: #10151b;
  --panel-2: #161d25;
  --panel-3: #1d2630;
  --border: #232d38;
  --border-soft: #1a222b;
  --text: #e7eef6;
  --muted: #8a99a8;
  --muted-2: #5f6d7b;
  --accent: #f5a524;
  --accent-ink: #1a1204;
  --cyan: #38bdf8;
  --ok: #2fbf71;
  --warn: #f5a524;
  --bad: #ef4757;
  --radius: 10px;
  --radius-sm: 7px;
  --shadow: 0 10px 30px rgba(0, 0, 0, .45);
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  background: var(--bg-grad);
  background-attachment: fixed;
  color: var(--text);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

[x-cloak] { display: none !important; }

a { color: var(--cyan); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.01em; }
h1 { font-size: 22px; }
h2 { font-size: 16px; }
h3 { font-size: 13px; }

p { margin: 0 0 10px; }

hr { border: 0; border-top: 1px solid var(--border-soft); margin: 16px 0; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #263140; border-radius: 6px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: #34435a; background-clip: content-box; }

/* ---------- Brand ---------- */

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  font-size: 13px;
}
/* The logo mark.
 *
 * Previously a glyph in an amber rounded box. The real mark IS the amber shape, so the box,
 * the gradient and the glow are gone — putting a logo inside a tile of its own colour reads
 * as a placeholder.
 *
 * One shared file, img/mark.svg, referenced by all eight pages rather than the path being
 * inlined eight times. That is a deliberate change of approach: an inline path cannot drift
 * between pages only because somebody remembers to update all of them, and the eight copies
 * of the old chevron are what made this replacement a scripted edit rather than a one-line
 * one.
 *
 * Slightly wider than tall, matching the artwork's 402x395 viewBox, so it is not stretched.
 */
.brand .mark {
  width: 27px;
  height: 26px;
  flex: none;
  display: block;
}
.brand .mark img {
  width: 100%;
  height: 100%;
  /* contain, so a future change to the artwork's aspect ratio letterboxes rather than
     distorting the logo. */
  object-fit: contain;
  display: block;
}

/* ---------- App shell ---------- */

.app {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.topbar {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 0 16px;
  height: 52px;
  flex: none;
  background: rgba(13, 17, 22, .82);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  z-index: 40;
}

.topnav { display: flex; gap: 4px; align-items: center; }
.topnav a {
  padding: 6px 11px;
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-weight: 500;
  font-size: 13px;
  text-decoration: none;
  transition: .12s;
}
.topnav a:hover { background: var(--panel-2); color: var(--text); text-decoration: none; }
.topnav a.active { background: var(--panel-3); color: var(--text); }

.spacer { flex: 1 1 auto; }

.main { flex: 1 1 auto; overflow: auto; }
.main.flush { overflow: hidden; }

.container { max-width: 1240px; margin: 0 auto; padding: 24px 20px 60px; }

.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.page-head .sub { color: var(--muted); font-size: 13px; margin-top: 2px; }

/* Controls sitting at the right-hand end of a page head.
 *
 * Its own class because .row was the obvious thing to reach for and is wrong: `.row > *`
 * sets `flex: 1 1 0` on every child, which is what makes a line of form fields share the
 * width evenly — and what made a status badge stretch to half the header and collide with
 * the button beside it.
 *
 * `flex: none` on the children, so each takes exactly the width of its own content. Wraps,
 * so a narrow window stacks them instead of overflowing. */
.head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.head-actions > * { flex: none; }

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

.card {
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.card + .card { margin-top: 16px; }
.card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-soft);
}
.card-head h2 { font-size: 14px; }
.card-body { padding: 16px; }
.card-body.tight { padding: 0; }

.grid { display: grid; gap: 16px; }
.grid.cols-2 { grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); }
.grid.cols-3 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }

/* ---------- Forms ---------- */

.field { margin-bottom: 12px; }
.field:last-child { margin-bottom: 0; }
label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
input[type=text], input[type=email], input[type=password], input[type=number], select, textarea {
  width: 100%;
  padding: 9px 11px;
  background: #0c1116;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  outline: none;
  transition: .12s;
}
input:focus, select:focus, textarea:focus {
  border-color: #3c586f;
  box-shadow: 0 0 0 3px rgba(56, 189, 248, .12);
}
input::placeholder, textarea::placeholder { color: var(--muted-2); }
textarea { resize: vertical; min-height: 70px; }
select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238a99a8' stroke-width='3'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 30px;
}

.row { display: flex; gap: 10px; }
.row > * { flex: 1 1 0; min-width: 0; }
.row.tight { gap: 8px; }
.row.middle { align-items: center; }

.check {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 10px;
  background: #0c1116;
  border: 1px solid var(--border);
  border-radius: 20px;
  cursor: pointer;
  font-size: 13px;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text);
  font-weight: 500;
  margin: 0;
  user-select: none;
}
.check:hover { border-color: #38495c; }
.check input { accent-color: var(--accent); margin: 0; width: 14px; height: 14px; }
.check.on { border-color: var(--accent); background: rgba(245, 165, 36, .1); }

.hint { font-size: 12px; color: var(--muted); margin-top: 6px; }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--panel-3);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: .12s;
}
.btn:hover:not(:disabled) { background: #26313e; border-color: #33414f; }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn svg { width: 15px; height: 15px; flex: none; }

.btn.primary {
  background: linear-gradient(180deg, #f9b545, var(--accent));
  border-color: #d99320;
  color: var(--accent-ink);
}
.btn.primary:hover:not(:disabled) { background: linear-gradient(180deg, #ffc262, #f7ae32); }

.btn.ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn.ghost:hover:not(:disabled) { background: var(--panel-2); color: var(--text); border-color: transparent; }

.btn.danger { background: rgba(239, 71, 87, .12); border-color: rgba(239, 71, 87, .35); color: #ff8a96; }
.btn.danger:hover:not(:disabled) { background: rgba(239, 71, 87, .2); }

.btn.sm { padding: 5px 10px; font-size: 12px; }
.btn.block { width: 100%; }

/* ---------- Tables ---------- */

table.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
table.tbl th {
  text-align: left;
  padding: 9px 16px;
  font-size: 11px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  border-bottom: 1px solid var(--border);
  background: rgba(0, 0, 0, .15);
  position: sticky;
  top: 0;
}
table.tbl td { padding: 10px 16px; border-bottom: 1px solid var(--border-soft); vertical-align: middle; }
table.tbl tr:last-child td { border-bottom: 0; }
table.tbl tbody tr:hover { background: rgba(255, 255, 255, .022); }

.mono { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 220px; display: inline-block; vertical-align: bottom; }

.empty { padding: 34px 16px; text-align: center; color: var(--muted-2); font-size: 13px; }

/* ---------- Badges / pills ---------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .03em;
  background: var(--panel-3);
  color: var(--muted);
  border: 1px solid var(--border);
}
.badge.ok { background: rgba(47, 191, 113, .12); color: #59d99a; border-color: rgba(47, 191, 113, .3); }
.badge.warn { background: rgba(245, 165, 36, .12); color: #f7bd5c; border-color: rgba(245, 165, 36, .3); }
.badge.bad { background: rgba(239, 71, 87, .12); color: #ff8a96; border-color: rgba(239, 71, 87, .3); }
.badge.info { background: rgba(56, 189, 248, .12); color: #6fd0fb; border-color: rgba(56, 189, 248, .3); }

.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted-2); flex: none; }
.dot.ok { background: var(--ok); box-shadow: 0 0 0 3px rgba(47, 191, 113, .18); }
.dot.warn { background: var(--warn); box-shadow: 0 0 0 3px rgba(245, 165, 36, .18); }
.dot.bad { background: var(--bad); }

.avatar {
  width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--panel-3);
  border: 1px solid var(--border);
  font-size: 11px; font-weight: 700; color: var(--muted);
  flex: none;
}

/* ---------- Login ---------- */

.auth-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
}
.auth-card {
  width: 100%;
  max-width: 390px;
  background: linear-gradient(180deg, rgba(24, 31, 40, .96), rgba(14, 19, 25, .96));
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 30px 28px;
  box-shadow: var(--shadow);
}
.auth-card .brand { justify-content: center; margin-bottom: 6px; font-size: 15px; }
.auth-card .tagline { text-align: center; color: var(--muted); font-size: 13px; margin-bottom: 24px; }

/* ---------- Toasts ---------- */

.toasts {
  position: fixed;
  bottom: 18px;
  right: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 9999;
  max-width: 380px;
}
.toast {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  background: var(--panel-3);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  font-size: 13px;
  animation: slidein .18s ease-out;
}
.toast.err { border-color: rgba(239, 71, 87, .45); background: #2a1519; }
.toast.ok { border-color: rgba(47, 191, 113, .4); background: #10241a; }
@keyframes slidein { from { opacity: 0; transform: translateX(16px); } }

/* ---------- Map console ---------- */

.console { display: flex; height: 100%; min-height: 0; }

.map-stage { position: relative; flex: 1 1 auto; min-width: 0; }
#map, .map { position: absolute; inset: 0; background: #0d1116; }

.map-overlay { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.map-overlay.armed { pointer-events: auto; cursor: crosshair; }

.marquee {
  position: absolute;
  border: 1.5px solid var(--accent);
  background: rgba(245, 165, 36, .14);
  border-radius: 3px;
  pointer-events: none;
}

.map-toolbar {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 10;
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.map-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 11px;
  border-radius: 20px;
  background: rgba(16, 21, 27, .92);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  transition: .12s;
  white-space: nowrap;
}
.map-chip:hover { border-color: #3a4a5c; }
.map-chip.on { border-color: var(--accent); color: var(--accent); background: rgba(245, 165, 36, .13); }
.map-chip.static { cursor: default; color: var(--muted); }
.map-chip svg { width: 14px; height: 14px; }

.map-hint {
  position: absolute;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  padding: 8px 15px;
  border-radius: 20px;
  background: rgba(16, 21, 27, .93);
  backdrop-filter: blur(8px);
  border: 1px solid var(--accent);
  font-size: 12.5px;
  color: var(--text);
  box-shadow: var(--shadow);
  pointer-events: none;
  white-space: nowrap;
}
.map-hint kbd {
  font-family: var(--mono);
  font-size: 11px;
  background: var(--panel-3);
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 1px 5px;
  margin: 0 2px;
}

.side {
  width: 320px;
  flex: none;
  background: var(--panel);
  border-left: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.side.left { border-left: 0; border-right: 1px solid var(--border); width: 268px; }
.side-head {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-soft);
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
}
.side-head h3 { font-size: 11px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.side-body { flex: 1 1 auto; overflow-y: auto; min-height: 0; }

/* The right sidebar's sections do not deserve equal room.
 *
 * Active taskings is the live question during a callout — who has acknowledged, who is en
 * route, who has said nothing — and those per-unit rows are the ones an operator is
 * chasing. Incidents below it is largely history: the list matters for opening one and for
 * the log link, and it is read at leisure.
 *
 * It was the other way round. Taskings carried an inline `max-height: 42%` and could not
 * grow, while Incidents inherited `flex: 1 1 auto` and took everything left over — so a
 * tasking with four assignees was already scrolling while the incident list sat half empty
 * below it.
 *
 * `flex-basis: 0` on both, with grow factors, so the split is proportional rather than
 * content-driven: 2:1, giving taskings two thirds. Content-based basis was the alternative
 * and is worse here — the panel would resize whenever an assignee answered, which on a
 * screen somebody is watching continuously is movement for its own sake. A fixed
 * proportion also means the layout does not jump when the first tasking of the night
 * arrives.
 */
.side-body.primary { flex: 2 1 0; }
.side-body.secondary { flex: 1 1 0; }

/* A section wrapped in an x-if template, where the wrapper is the flex child rather than
   the .side-body inside it. Takes only the room its content needs, up to a cap. */
.side-section {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.side-section.capped { flex: 0 1 auto; max-height: 26%; }
.side-foot { flex: none; padding: 12px 14px; border-top: 1px solid var(--border-soft); }

.unit {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--border-soft);
  cursor: pointer;
  transition: .1s;
}
.unit:hover { background: rgba(255, 255, 255, .03); }
.unit.sel { background: rgba(245, 165, 36, .1); box-shadow: inset 3px 0 0 var(--accent); }
.unit .nm { font-weight: 600; font-size: 13px; }
.unit .meta { font-size: 11.5px; color: var(--muted); }
/* A line on a row that is a caveat rather than detail. Amber against the muted grey of
   ordinary metadata, so it reads as something to act on. */
.unit .meta.warn-text { color: var(--warn); }

/* One assignee's answer to a tasking, listed under it in the taskings panel.
   Indented and quieter than a .unit row so the tasking stays the thing you scan
   and these read as detail belonging to it. */
.assignee {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 14px 5px 34px;
  font-size: 11.5px;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 1px solid var(--border-soft);
}
.assignee:hover { background: rgba(255, 255, 255, .03); color: var(--text); }
.assignee .grow { color: inherit; }
.assignee-state { color: var(--muted-2); font-variant-numeric: tabular-nums; }
.assignee:hover .assignee-state { color: var(--muted); }
.unit .grow { flex: 1 1 auto; min-width: 0; }

/* Truncation inside a .unit row has to be elastic, and the base .truncate is not.
   That rule sets `max-width: 220px; display: inline-block`, which shrink-wraps to the
   text up to 220px and then stops caring what room it has. In a 320px sidebar — 292px
   once padding is off — 220px of text plus a dot, a status badge and three buttons do
   not fit, so the row overflowed and the badge sat on top of the text.
   `min-width: 0` on .grow was not enough on its own: it lets the *container* shrink,
   while the inline-block inside it stays as wide as its content. Block display plus a
   percentage max-width is what makes the ellipsis appear instead. */
.unit .truncate { display: block; max-width: 100%; }

/* An incident row carries more than a member row: two lines of text, a status badge,
   and four actions. Those do not fit on one line at sidebar width and cramming them
   there is what caused the overlap, so the actions get their own line.

   Stacking rather than hiding them behind a menu, because during an incident all four
   are one click each and an operator placing a pin while somebody is on the phone
   should not have to open anything to find them. */
.unit.stacked { flex-direction: column; align-items: stretch; gap: 7px; }
.unit-head { display: flex; align-items: center; gap: 10px; min-width: 0; }

/* Wraps, so a row with four actions degrades to two lines rather than overflowing
   again the next time one is added. Indented to line up with the text above rather
   than the dot, so the actions read as belonging to the row and the dot column stays
   scannable down the list. */
.unit-actions { display: flex; flex-wrap: wrap; gap: 6px; padding-left: 18px; }

/* Terms and privacy links on an app page — the sign-in screen, and anywhere else somebody
   needs to reach them without a footer. Quiet, since they are not the task at hand, but
   present, because a person accepting an invitation should be able to read what they are
   agreeing to before they set a password. */
.doc-links {
  margin-top: 22px;
  text-align: center;
  font-size: 12.5px;
  color: var(--muted-2);
  display: flex;
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
}
.doc-links a { color: var(--muted); }

/* ---------- Address search (the incident form) ---------- */

.addr { position: relative; }

/* Absolute, so the suggestions float over the fields below instead of pushing the modal
   taller as the operator types — a form that resizes under the cursor is a form where the
   Create button moves out from under a click. */
.addr-menu {
  position: absolute;
  z-index: 30;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--panel-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  overflow: hidden;
  /* Capped, with a scroll. Six results is the API's limit, but the cap is stated here too
     so a longer list can never run off the bottom of the viewport. */
  max-height: 216px;
  overflow-y: auto;
}
.addr-item {
  padding: 8px 11px;
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
  border-bottom: 1px solid var(--border-soft);
}
.addr-item:last-child { border-bottom: 0; }
.addr-item:hover { background: rgba(245, 165, 36, .13); color: var(--accent); }

/* ---------- Incident log (incident.html) ---------- */

/* Filter chips. Not .map-chip, which is built for floating over a map — it carries a
   backdrop blur and a translucent background that read as a smudge on a solid panel. */
.log-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border-soft);
}
.filter-chip {
  padding: 4px 11px;
  border-radius: 20px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: .1s;
}
.filter-chip:hover { color: var(--text); border-color: #3a4a5c; }
.filter-chip.on {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(245, 165, 36, .13);
}

/* A day heading. Sticky, because an incident that runs for hours scrolls past several and
   the reader loses which day they are looking at — which is the exact confusion the
   headings exist to prevent. */
.log-day {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 7px 16px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--border-soft);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted-2);
}

.log-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 16px;
  border-bottom: 1px solid var(--border-soft);
}
.log-row:hover { background: rgba(255, 255, 255, .02); }
/* Nudged down to sit on the first line of text rather than the top of the block, since
   a note can be several lines tall. */
.log-row .dot { margin-top: 6px; }
.log-row .grow { flex: 1 1 auto; min-width: 0; }

/* Tabular figures so the times form a straight column down the page. Without it the
   proportional digits jitter and the log stops being scannable by time. */
.log-time {
  flex: none;
  width: 62px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}

/* A note is what a person wrote, so it is the loudest thing in the row — full text
   colour and pre-wrap, because a responder's line breaks are part of what they wrote.
   overflow-wrap breaks a pasted URL or a long unbroken string rather than letting it
   widen the row and push the times out of alignment. */
.log-note {
  font-size: 13px;
  color: var(--text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* What the system observed. Quieter than a note, deliberately: on a busy incident these
   outnumber the notes several times over, and the entries a person wrote are the ones
   somebody scanning the log is looking for. */
.log-summary { font-size: 12.5px; color: var(--muted); overflow-wrap: anywhere; }
.log-note + .log-summary { margin-top: 3px; }

/* The position an entry carried. Monospaced figures so coordinates down the page line up
   and a reader can compare them without reading each digit. */
.log-where {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--cyan);
  margin-top: 3px;
  overflow-wrap: anywhere;
}

/* A fix too old to be evidence of where somebody is now. Amber rather than cyan, because
   the difference between "position" and "last known position" is the single most
   misreadable thing on this page and colour carries it faster than the words do. */
.log-where.stale { color: var(--warn); }

.log-by { font-size: 11px; color: var(--muted-2); margin-top: 3px; }
.log-sep { margin: 0 5px; }

.stat-row { display: flex; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--border-soft); }
.stat { flex: 1 1 0; text-align: center; }
.stat .n { font-size: 20px; font-weight: 700; line-height: 1.1; }
.stat .l { font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-top: 2px; }

/* ---------- Modal ---------- */

.modal-bg {
  position: fixed;
  inset: 0;
  background: rgba(4, 6, 9, .72);
  backdrop-filter: blur(3px);
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 24px;
}
.modal {
  width: 100%;
  max-width: 460px;
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}
.modal-head {
  padding: 15px 18px;
  border-bottom: 1px solid var(--border-soft);
  display: flex;
  align-items: center;
  gap: 10px;
}
.modal-body { padding: 18px; overflow-y: auto; }
.modal-foot {
  padding: 13px 18px;
  border-top: 1px solid var(--border-soft);
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* ---------- Misc ---------- */

.loading-bar {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 500;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  background-size: 40% 100%;
  animation: sweep 1s linear infinite;
}
@keyframes sweep { from { background-position: -40% 0; } to { background-position: 140% 0; } }

.gm-style .gm-style-iw-c { background: var(--panel-2) !important; color: var(--text); border-radius: 8px; padding: 10px !important; }
.gm-style .gm-style-iw-d { overflow: hidden !important; }
.gm-style .gm-style-iw-tc::after { background: var(--panel-2) !important; }

@media (max-width: 900px) {
  .side, .side.left { width: 240px; }
  .topnav a { padding: 6px 8px; }
}
