/* Map page. Inherits every colour token from fw.css — same rule applies here:
   colour only ever means something needs attention. The base map is Apple's,
   so the only saturated things on screen are fire perimeters and status. */

.mapbody { overflow: hidden; height: 100%; }

#map {
  position: fixed;
  inset: 0;
  background: var(--bg);
}

/* ---------- top bar ---------- */

.mapbar {
  position: fixed;
  z-index: 20;
  top: max(0.8rem, env(safe-area-inset-top));
  left: 0.8rem;
  right: 0.8rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.7rem 0.9rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.35);
  border-left: 3px solid var(--sev, var(--line));
}

.mapbar-back {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  height: 32px;
  padding: 0 0.6rem 0 0.45rem;
  border-radius: 8px;
  color: var(--dim);
  background: var(--well);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}
.mapbar-back svg { width: 14px; height: 14px; flex: 0 0 auto; }
.mapbar-back:hover { color: var(--text); }

/* A bare chevron is a guess. At the narrowest widths the word is dropped and
   the aria-label still carries it for screen readers. */
@media (max-width: 359px) { .mapbar-back .lbl { display: none; } }
.mapbar-back:hover { color: var(--text); }

.mapbar-main { min-width: 0; }
.mapbar-head {
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--sev, var(--text));
}
.mapbar-sub {
  margin-top: 0.15rem;
  font-size: 0.78rem;
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- legend ---------- */

/* Present because the map uses colour to encode state, and a legend is the
   difference between a reader knowing that and guessing it. */
.maplegend {
  position: fixed;
  z-index: 20;
  left: 0.8rem;
  bottom: calc(0.8rem + env(safe-area-inset-bottom));
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.9rem;
  padding: 0.5rem 0.75rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 0.7rem;
  color: var(--dim);
}
.maplegend span { display: inline-flex; align-items: center; gap: 0.35rem; }
.k { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.k-fire { background: var(--alarm); }
.k-held { background: transparent; border: 2.5px solid var(--alarm); }
.k-cam  { background: var(--flame); }

/* The legend and the sheet both want the bottom of a phone screen, and the
   sheet won — it covered the aircraft keys, which are the ones people actually
   need explained. The legend hides while the sheet is open rather than being
   squeezed somewhere it cannot be read. */
body.sheet-open .maplegend { opacity: 0; pointer-events: none; }
.maplegend { transition: opacity 0.15s; }

@media (prefers-reduced-motion: reduce) { .maplegend { transition: none; } }

/* ---------- failure ---------- */

.mapfail {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: grid;
  place-content: center;
  gap: 0.4rem;
  padding: 2rem;
  text-align: center;
  background: var(--bg);
  color: var(--dim);
  font-size: 0.9rem;
}
.mapfail-sub { font-size: 0.8rem; color: var(--faint); }
.mapfail a { color: var(--text); }

/* NOTE: MapKit JS 5.81 draws Apple's logo and legal link INTO THE CANVAS, not
   as DOM nodes — there is no .mk-attribution-container to target, so any CSS
   aimed at one is a no-op. Apple's terms require that attribution stay visible
   and unobscured, which means nothing may be positioned over the bottom-right
   of the map. The legend therefore sits bottom-LEFT deliberately. */

/* ---------- custom annotations ---------- */

/* MapKit's MarkerAnnotation is a teardrop pin that cannot be resized or
   rotated. These are custom annotations for two reasons that matter: a fire's
   mark is sized by relevance rather than acreage, and a camera's cone shows
   the bearing it is actually pointed. */

.fa, .ca, .ha { position: relative; cursor: pointer; }

/* 44px hit target around a small visual — Apple's minimum, and why the target
   is the wrapper rather than the dot. */
.fa, .ca {
  width: 44px; height: 44px;
  display: grid; place-items: center;
}

.fa-dot {
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--alarm);
  box-shadow: 0 0 0 1.5px rgb(255 255 255 / 0.4);
}
.fa.near .fa-dot { width: 18px; height: 18px; }
/* ALMOST CONTAINED — hollow, same hue.

   It was amber, which collided head-on with the amber fire cameras: two
   different things wearing one colour on the same screen. Containment is a
   MAGNITUDE of the same thing, not a different kind of thing, so it keeps the
   fire hue and differs by form — a ring instead of a disc. Reads as "less
   filled in", which is exactly what it means, and it survives colour blindness
   because the shape carries it.

   Amber is now unambiguous: on this map amber means camera. */
.fa.held .fa-dot {
  background: transparent;
  border: 3px solid var(--alarm);
  opacity: 0.9;
}

.fa-halo {
  position: absolute;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--alarm);
  opacity: 0.2;
}
.fa.near .fa-halo { width: 40px; height: 40px; }
.fa.held .fa-halo { background: var(--alarm); opacity: 0.1; }

.ca-dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--flame);
  box-shadow: 0 0 0 2px var(--bg);
  position: relative;
}
.ca.off .ca-dot { background: var(--faint); }

/* Drawn pointing north and rotated to the bearing. The transform origin is the
   dot so it pivots on the camera, not on its own centre. */
.ca-cone {
  position: absolute;
  left: 50%; bottom: 50%;
  width: 34px; height: 34px;
  margin-left: -17px;
  transform-origin: 50% 100%;
  background: linear-gradient(to top,
    color-mix(in srgb, var(--flame) 42%, transparent),
    color-mix(in srgb, var(--flame) 2%, transparent));
  clip-path: polygon(50% 100%, 8% 0%, 92% 0%);
  pointer-events: none;
}

.ha {
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--text);
  box-shadow: 0 0 0 2.5px var(--bg), 0 1px 4px rgb(0 0 0 / 0.5);
}

/* ---------- details button ---------- */

.detailsbtn {
  position: fixed;
  z-index: 20;
  right: 0.8rem;
  bottom: calc(0.8rem + env(safe-area-inset-bottom));
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.6rem 1rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.85rem; font-weight: 600;
  cursor: pointer;
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.35);
}
.detailsbtn svg { width: 14px; height: 14px; }

/* ---------- sheet ---------- */

.scrim { position: fixed; inset: 0; z-index: 29; background: var(--backdrop, rgb(0 0 0 / 0.6)); }

.sheet {
  position: fixed;
  z-index: 30;
  left: 0; right: 0; bottom: 0;
  max-height: 78vh;
  display: flex; flex-direction: column;
  background: var(--bg);
  border-top: 1px solid var(--line);
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -12px 40px rgb(0 0 0 / 0.5);
  animation: sheetup 0.2s ease-out;
}
@keyframes sheetup { from { transform: translateY(12px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .sheet { animation: none; } }

.sheet-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 0.8rem;
  padding: 0.9rem 1rem 0.7rem;
  border-bottom: 1px solid var(--line);
}
.sheet-bar h2 { margin: 0; font-size: 0.95rem; font-weight: 600; }
.sheet-close { font-size: 1.5rem; line-height: 1; color: var(--dim); cursor: pointer; padding: 0 0.3rem; }

.sheet-body {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0.9rem 1rem calc(1.4rem + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 0.6rem;
}
.sheet-body .label { margin: 0.5rem 0 0; }
.sheet-body .label:first-child { margin-top: 0; }

.facts {
  display: grid; grid-template-columns: auto 1fr;
  gap: 0.4rem 1rem; margin: 0;
  font-size: 0.87rem;
}
.facts dt { color: var(--dim); }
.facts dd {
  margin: 0; text-align: right;
  font-family: var(--data); font-variant-numeric: tabular-nums;
}

/* Camera frame — 16:9, black backing, honest failure text. */
.camwrap {
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: 8px;
  overflow: hidden;
  display: grid; place-items: center;
}
.camwrap img { width: 100%; height: 100%; object-fit: contain; display: block; }
.camwrap.failed img { display: none; }
.camwrap.failed::after {
  content: "No current frame — the camera or its link may be down.";
  color: var(--dim); font-size: 0.8rem; text-align: center; padding: 0 1.2rem;
}

@media (min-width: 760px) {
  .sheet {
    left: auto; right: 0.8rem; bottom: 0.8rem;
    width: 380px; max-height: 70vh;
    border: 1px solid var(--line);
    border-radius: 12px;
  }
  .scrim { display: none; }
  .detailsbtn { bottom: calc(0.8rem + env(safe-area-inset-bottom)); }
}

/* ---------- aircraft ---------- */

/* Shape carries the distinction, not colour. A tanker and a helicopter must be
   tellable apart at a glance on a phone, by someone who has never seen a
   legend, and shape survives both small sizes and colour blindness. */

.ac {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  cursor: pointer;
  pointer-events: auto;
}

.ac-glyph {
  display: block;
  width: 22px; height: 22px;
  /* Rotated by JS to the aircraft's live track. No CSS transition here: the
     motion loop already eases heading toward the reported track, and a second
     easing layer on top fights it and produces a wobble. */
  transform-origin: 50% 50%;
  will-change: transform;
}
.ac-glyph svg { width: 100%; height: 100%; display: block; }

/* Fixed wing — the workhorse tankers. */
.ac-plane .ac-glyph svg { fill: var(--text); }
.ac-plane .ac-glyph {
  filter: drop-shadow(0 0 3px rgb(0 0 0 / 0.55));
}

/* Rotorcraft. Slightly warmer so the two read apart in peripheral vision even
   before the shape resolves — but still not a status colour, because an
   aircraft being present is not itself a warning. */
.ac-helicopter .ac-glyph svg { fill: var(--text); }
.ac-helicopter .ac-glyph {
  filter: drop-shadow(0 0 3px rgb(0 0 0 / 0.55));
}
.ac-helicopter .rotor {
  fill: var(--text);
  opacity: 0.42;
  transform-origin: 12px 9px;
  animation: rotor 0.9s linear infinite;
}

/* The disc widens and narrows, which is what a turning rotor reads as from
   above. It is the one piece of motion on this map that is decorative, and it
   earns its place by making "this is a helicopter" instant. */
@keyframes rotor {
  0%, 100% { transform: scaleX(1); opacity: 0.42; }
  50%      { transform: scaleX(0.55); opacity: 0.62; }
}

@media (prefers-reduced-motion: reduce) {
  .ac-helicopter .rotor { animation: none; opacity: 0.5; }
}

.k-plane, .k-heli {
  width: 11px; height: 11px;
  border-radius: 0;
  background: var(--text);
}
.k-plane { clip-path: polygon(50% 0%, 60% 45%, 100% 65%, 100% 75%, 58% 65%, 58% 85%, 70% 95%, 70% 100%, 30% 100%, 30% 95%, 42% 85%, 42% 65%, 0% 75%, 0% 65%, 40% 45%); }
.k-heli  { clip-path: polygon(0% 30%, 100% 30%, 100% 42%, 58% 42%, 58% 100%, 42% 100%, 42% 42%, 0% 42%); }
