/* ==================================================================
   SGF.cams — layout insets

   Everything over the map is absolutely positioned, and until now each
   overlay assumed it was the only one there: the timeline bar ran the
   full width and clipped the bottom of the camera rail, the incidents
   feed covered the timeline's own controls, and Leaflet's zoom buttons
   and attribution — pinned bottom-right — sat under both.

   The fix is one set of measured insets, published on :root by
   layout.js, that every overlay reads. Nothing here hard-codes a panel
   size: the JS measures the real boxes, so a wrapped header, a taller
   touch-sized timeline bar, or a safe-area inset all come out right.

   Loaded after index.html's own <style> so these rules win on source
   order at equal specificity.
   ================================================================== */

:root{
  --hdr-h:0px;      /* header, which wraps to two rows under 1300px  */
  --tabbar-h:0px;   /* phone tab bar; 0 on desktop                   */
  --feed-w:0px;     /* incidents feed — the outermost right panel    */
  --side-w:0px;     /* live-camera rail, inboard of the feed         */
  --rail-w:0px;     /* both of them: how much of the right edge is spoken for */
  --bar-h:0px;      /* replay timeline bar                           */
  --sheet-h:0px;    /* phone: incidents feed as a bottom sheet       */
}

/* ---------- the right rail stacks instead of self-overlapping ----------
   #side and #incFeed both anchored to right:0, so opening incidents
   swallowed the camera rail whole — 300px of live video painted under
   340px of opaque panel. The rail now sits inboard of the feed. */
#side{
  right:var(--feed-w);
  transition:translate .25s, right .25s, opacity .2s;
}
/* Two full-height panels only fit while the map keeps a usable width.
   When it doesn't, the rail steps aside for the feed rather than hiding
   underneath it, and comes back on its own when the feed closes. */
#side.yield{
  translate:300px 0;
  opacity:0;
  pointer-events:none;
}

/* The head is a scroll boundary, so it needs to read as one — without a
   background the first card underneath it bled through as it scrolled. */
#sideHead{
  padding-bottom:9px;
  background:rgba(13,18,29,.97);
  border-bottom:1px solid var(--line);
  position:relative;
  z-index:1;
}
#sideList{ padding-top:10px }

/* ---------- the timeline bar spans the map, not the panels ----------
   It used to run edge to edge at z-index 1005: over the camera rail
   (1000), which clipped the last preview tile, and under the incidents
   feed (1010), which hid its live / clips / close buttons entirely. */
#recBar{ right:var(--rail-w) }

/* ---------- map furniture clears the bar and the rail ----------
   Leaflet's corners are z-index 1000 inside #map, which comes first in
   the DOM, so every same-or-higher overlay painted over them. The zoom
   control is set to bottomright, i.e. exactly where the rail and the
   bar meet — it was unreachable. Scoped to #map so the weather view's
   own map, which has neither, is left alone. */
#map .leaflet-right{ right:var(--rail-w) }
#map .leaflet-bottom{ bottom:calc(var(--bar-h) + var(--sheet-h)) }
/* Same easing as the panels that push them, so the zoom buttons travel with
   the rail instead of jumping ahead of it and being brushed over mid-slide. */
#map .leaflet-right,
#map .leaflet-bottom{ transition:right .25s, bottom .25s }

#keysHint{ bottom:calc(14px + var(--bar-h)) }

/* The toast is fixed to the viewport, so it has to clear the phone tab
   bar as well as anything docked inside #main. */
#toast{ bottom:calc(26px + var(--tabbar-h) + var(--bar-h) + var(--sheet-h)) }

/* Centred on the map rather than on the whole pane, and capped so a long
   place name can't grow back under the rail. */
#placePill{
  left:calc(50% - var(--rail-w) / 2);
  max-width:min(64%, calc(100% - var(--rail-w) - 28px));
}

/* ---------- weather view sits below the real header ----------
   The base rule hard-codes top:53px, which is the one-row header. Under
   1300px the search wraps to its own row and the header is nearly twice
   that, so the overlay ate the search box. --hdr-h is measured, and it
   keeps tracking on resize instead of being sampled once at open. */
#storm{
  top:var(--hdr-h,53px);
  bottom:var(--tabbar-h,0px);
}

/* ---------- incidents feed: no clipped chips ----------
   Both rows were overflow-x:auto inside a 340px panel, so the last chip
   was always sliced mid-word — "No location" read as "No", "· kept 3d"
   lost its number. There are only ever a handful of each; wrapping shows
   them all. */
#incTabs,
#incDays{
  flex-wrap:wrap;
  overflow-x:visible;
  row-gap:6px;
}
#incDays{ padding-bottom:2px }

@media(max-width:900px){
  /* The feed becomes a bottom sheet here, pinned to the same edge as the
     timeline bar and painting over it at z-index 1010. Sit above it. */
  #incFeed{ bottom:var(--bar-h) }
  #incFeed.hid{ translate:0 calc(100% + var(--bar-h)) }

  /* 72dvh was measured against the viewport, but the sheet lives in #main —
     which the header, chipbar and tab bar have already taken ~230px out of.
     On a 812px phone that made the "sheet" taller than the box holding it,
     so it covered the whole map and buried the camera-health pill. A
     percentage is of #main, which is itself sized in dvh, so this keeps the
     URL-bar correctness the original comment was after and still leaves the
     top of the map showing. */
  #incFeed{ height:72%; max-height:72% }

  /* Set by layout.js when the sheet and the timeline bar between them have
     left the map too short to hold the health pill as well. Landscape
     phones are the only shape this reaches, and it is the same call the
     app already makes there for the chipbar and the keyboard hint. */
  #main.cramped #statusPill{ opacity:0; pointer-events:none }
}
