/* css/10-map-furniture.css — map furniture + MapLibre markers.
   Split from the index.html <style> block (REFACTOR-PLAN Phase 2). Load order = cascade order; do not reorder. */
/* ---------- map furniture (middle zone) ---------- */
/* control cluster + Re-center pill: bottom-right of the map stage, 12px inset,
   stacked so the pill sits under the icon column with no overlap. */
/* revamp 11: the cluster gained a fifth control (simulation speed) and the
   top-right HUD tiles grew, so the column drops to 48 px buttons on a 7 px
   gap — still over the 44 px in-vehicle touch floor — and the stack clears the
   tiles on a 604 px head unit. */
/* pass 23 (client): "the map controls ... look floating in the air". The rail
   used to stand off at bottom:68px, reserving a lane for the Re-center pill —
   which is hidden on every frame the follow camera is on, i.e. almost all of
   them — so 68 px of empty stage sat under the rail for the whole drive. The
   stage (.zm) already ends above the floating dock (main's --dock-clear
   padding), so a 12 px inset here IS the bottom edge of the map viewport,
   with ~20 px of air over the dock at 1280x604. The pill's lane is no longer
   reserved: it is given back only in the rare frames the pill is actually on
   screen (the :has rule below), and the pill itself is untouched. */
.mapctl{position:absolute;right:12px;bottom:12px;display:flex;flex-direction:column;gap:7px;pointer-events:auto}
/* ...and the one state that still needs the lane: while #recenter is on
   screen (the inspector has dragged the map off the vehicle) the rail steps
   up over it. The pill is a LATER sibling, so this reads it off the shared
   stage rather than with a sibling combinator. */
.zm:has(#recenter:not([hidden])) .mapctl{bottom:68px}
.mapctl .iconbtn{background:var(--glass-solid);border:1px solid var(--hair);backdrop-filter:var(--blur);color:var(--tx);width:48px;height:48px;border-radius:14px}
.mapctl .iconbtn.on{color:var(--acc);border-color:rgba(34,200,130,.4)}
/* revamp 11 (client): the simulation-speed control. A mono multiplier rather
   than a glyph — it IS a number — 18 px so it reads at the same distance as
   the icons beside it, accent-tinted only while the sim is running fast. */
.mapctl .simx{font-family:var(--mono);font-size:16px;font-weight:700;letter-spacing:-.03em;padding:0;
  display:grid;place-items:center;font-variant-numeric:tabular-nums}
.mapctl .simx .num{line-height:1;pointer-events:none}
.mapctl .simx.on{color:var(--acc);border-color:rgba(34,200,130,.45);
  background:linear-gradient(180deg,rgba(34,200,130,.12),rgba(34,200,130,.05)),var(--glass-solid)}
.recenter{position:absolute;right:12px;left:auto;bottom:12px;height:48px;padding:0 22px;border-radius:999px;background:var(--glass-solid);border:1px solid rgba(34,200,130,.55);color:var(--acc);font-size:var(--fz-body);font-weight:700;z-index:4;backdrop-filter:var(--blur)}
.recenter:active{transform:scale(.97)}
/* revamp 11 (client): the attribution is OFF the map. Three licence credits
   ran across the bottom of the stage on every screen the map appears on, and
   at 1.5 s of glance time they are the least useful twelve words in the
   cockpit. The node stays (drawMap() still writes ATTR into it) and the same
   string is printed at the foot of the Settings sheet, so the credit the
   OpenStreetMap / OpenMapTiles licences require still exists in the app. */
.attrib{display:none}
.fbnote{position:absolute;left:50%;top:12px;transform:translateX(-50%);font-size:var(--fz-meta);color:var(--tx3);z-index:2;pointer-events:none;background:var(--glass-solid);padding:5px 10px;border-radius:999px}
.oos{position:absolute;left:0;bottom:0;z-index:7;display:none;align-items:center;gap:10px;height:48px;padding:0 15px;border-radius:999px;background:rgba(255,159,67,.16);border:1px solid rgba(255,159,67,.55);color:#FFC078;font-size:var(--fz-body);font-weight:700;white-space:nowrap;backdrop-filter:var(--blur)}
.oos.on{display:flex}
.oos .badge{min-width:22px;height:22px;border-radius:11px;background:var(--med);color:#1A1206;font-size:var(--fz-meta);font-weight:800;display:grid;place-items:center;padding:0 6px;font-family:var(--mono)}
/* the legend duplicated the Sector screen and crowded the stage: the centre
   third stays empty on Drive (wave3-layout "Remove") */
#view-drive .legend,#view-drive .sci{display:none}

/* ---------- MapLibre markers ---------- */
.maplibregl-canvas{outline:none}
.maplibregl-ctrl-attrib,.maplibregl-ctrl-logo{display:none}
/* ground plane: perception cone + static sensor rings, map-aligned so they lie
   on the road like a real sensor footprint */
/* MapLibre owns position on a marker element (it writes the transform against
   position:absolute): declaring position:relative here made the puck flow after
   the 190px ground plane and land 190px low. */
.veh{width:190px;height:190px;pointer-events:none}
.veh .cone{position:absolute;left:50%;top:50%;width:190px;height:190px;transform:translate(-50%,-50%);border-radius:50%;
  /* wave13: a 60 deg wedge at ~25% opacity, kept in FRONT of the puck */
  background:conic-gradient(from 300deg at 50% 50%, rgba(34,200,130,.25) 0deg, rgba(34,200,130,.16) 34deg, rgba(34,200,130,0) 60deg, rgba(34,200,130,0) 360deg);
  -webkit-mask-image:radial-gradient(circle at 50% 50%, #000 12%, rgba(0,0,0,.75) 52%, transparent 86%);
  mask-image:radial-gradient(circle at 50% 50%, #000 12%, rgba(0,0,0,.75) 52%, transparent 86%)}
.veh .rings{position:absolute;left:50%;top:50%;width:180px;height:180px;transform:translate(-50%,-50%)}
.veh .rings svg{width:180px;height:180px;display:block}
.veh .halo{position:absolute;left:50%;top:50%;width:52px;height:52px;transform:translate(-50%,-50%);border-radius:50%;
  background:radial-gradient(circle,rgba(34,200,130,.40) 0,rgba(34,200,130,0) 70%)}
.veh.paused .cone{display:none}
.veh.nofix .cone,.veh.nofix .rings,.veh.nofix .halo{display:none}
/* wave13 — THE NAVIGATION PUCK, the way a shipped navigation app draws it:
   a 44 px accent disc with a 2 px white ring and a soft drop shadow, carrying a
   white navigation arrow whose tip points along the heading. Viewport-aligned,
   so it never foreshortens with the map pitch, and above the route line and the
   pins. The floating turn-icon bubble that used to hover over it is gone: the
   turn arrow already lives in the guidance strip, and two of them was one
   restatement too many. */
/* wave13 fix 5: the puck is ALWAYS on top. The old .behind-cluster rule
   (z-index:-1 whenever a cluster badge sat on the vehicle's own pixel) hid the
   driver's own position behind a count badge — the one thing on the map that
   may never be occluded. Pins and clusters are GL layers (below every DOM
   marker) and any DOM badge stays under this z-index. */
.puck{width:44px;height:44px;pointer-events:none;z-index:20;
  border-radius:50%;background:var(--acc);border:2px solid #fff;
  box-shadow:0 4px 14px rgba(0,0,0,.55),0 0 0 1px rgba(0,0,0,.25);
  display:grid;place-items:center}
.puck .navarrow{width:22px;height:22px;display:block;transform-origin:50% 50%;
  fill:#fff;transition:none}
.puck.nofix{background:#1A2226;border-color:rgba(238,244,242,.55)}
.puck.nofix .navarrow{fill:rgba(238,244,242,.45)}
/* revamp 1 — DETECTION FLASH. A detection is something the vehicle itself just
   drove past, so the driver's own marker is what announces it: the puck goes
   critical-red with a wide soft ring for 1.4 s (JS adds/removes .hit), and the
   ground halo under the vehicle goes red with it. Colour is the signal, the
   glow is only the amplifier, so reduced motion keeps the colour and drops the
   transition and the spread. */
.puck{transition:background .25s var(--ease),box-shadow .25s var(--ease)}
.puck.hit{background:var(--crit);
  box-shadow:0 0 0 7px rgba(255,90,95,.32),0 0 26px rgba(255,90,95,.65),0 4px 14px rgba(0,0,0,.55)}
.veh .halo{transition:background .25s var(--ease)}
.veh.hit .halo{background:radial-gradient(circle,rgba(255,90,95,.52) 0,rgba(255,90,95,0) 70%)}
@media (prefers-reduced-motion: reduce){
  .puck,.veh .halo{transition:none}
  .puck.hit{box-shadow:0 4px 14px rgba(0,0,0,.55),0 0 0 1px rgba(0,0,0,.25)}
}
.bpop .maplibregl-popup-content{background:var(--glass-solid);color:var(--tx);border:1px solid var(--hair2);border-radius:14px;padding:8px 12px;font:inherit;box-shadow:var(--sh-lg);backdrop-filter:var(--blur)}
.bpop .maplibregl-popup-content b{display:block;font-size:var(--fz-body);font-weight:700}
.bpop .maplibregl-popup-content span{font-size:var(--fz-meta);color:var(--tx2)}
.bpop .maplibregl-popup-tip{border-top-color:rgba(10,15,17,.8);border-bottom-color:rgba(10,15,17,.8);border-left-color:rgba(10,15,17,.8);border-right-color:rgba(10,15,17,.8)}


/* ---------- revamp task 3: the drive-past capture card ----------
   Bottom-centre of the map stage — a callout pinned under the vehicle as it
   rolls to a stop at an incident, rather than top-centre where it would sit
   across the coverage card and the toast slot. Blue hairline while the camera
   captures, green the moment the incident is closed: the same two colours the
   pin itself steps through. */
.vcap{position:absolute;bottom:56px;left:50%;transform:translateX(-50%);
  display:flex;align-items:center;gap:12px;height:56px;padding:0 16px 0 12px;
  border-radius:var(--r-sm);background:var(--glass-solid);backdrop-filter:var(--blur);
  border:1px solid rgba(77,163,255,.55);box-shadow:var(--sh);
  z-index:8;pointer-events:none;white-space:nowrap;
  transition:border-color .2s var(--ease),opacity .2s var(--ease),transform .2s var(--ease)}
.vcap[hidden]{display:none}
.vcap .ring{flex:0 0 auto;width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  background:rgba(77,163,255,.16);border:1px solid rgba(77,163,255,.45)}
.vcap .ring .i{width:17px;height:17px;stroke-width:2.2;stroke:var(--info)}
.vcap .txt{display:flex;flex-direction:column;gap:3px;min-width:0}
.vcap .txt b{font-size:var(--fz-card);font-weight:700;color:var(--tx);line-height:1}
.vcap .txt span{font-family:var(--mono);font-size:var(--fz-meta);color:var(--tx3);line-height:1}
.vcap.live .ring{animation:vcapRing 1.1s var(--ease) infinite}
.vcap.ok{border-color:rgba(34,200,130,.6)}
.vcap.ok .ring{background:var(--acc-dim);border-color:rgba(34,200,130,.5);animation:none}
.vcap.ok .ring .i{stroke:var(--acc)}
.vcap.ok .txt b{color:var(--acc)}
@keyframes vcapRing{
  0%,100%{box-shadow:0 0 0 0 rgba(77,163,255,.45)}
  60%    {box-shadow:0 0 0 9px rgba(77,163,255,0)}
}
/* the capture flash: one 140 ms white wash over the basemap, nothing else. */
#camflash{position:absolute;inset:0;z-index:4;pointer-events:none;background:#fff;opacity:0}
#camflash.on{animation:camFlash .14s linear 1}
@keyframes camFlash{0%{opacity:0}45%{opacity:.55}100%{opacity:0}}
@media (prefers-reduced-motion: reduce){
  .vcap.live .ring{animation:none}
  #camflash.on{animation:none;opacity:0}
}
