/* css/11-toast.css — toast.
   Split from the index.html <style> block (REFACTOR-PLAN Phase 2). Load order = cascade order; do not reorder. */
/* ---------- toast ---------- */
/* wave9: TWO toast placements, never a third.
   1) Every screen except Drive (Verify, Cameras, Sector, End) gets a DEDICATED
      top strip directly under the header: --toast-zone is real reserved
      padding on that view's content wrapper (see #view-cams .camwrap, .verify,
      .sector, .sumwrap), not a floating guess, so the toast can never land on
      a .btn, a .tile or a header card no matter which message is showing — the
      wave9 defect was a stale position computed for a DIFFERENT view (the
      Cameras gap math) still in effect after setView() switched to Verify.
      Centred by simple `left:50%` + `translateX(-50%)`, unconditionally.
   2) Drive keeps the TOP-OF-MAP-STAGE slot (verify-wave3 EX7 — never the
      header band), but the slot is now measured off the live .zm rect
      (positionToast(), below) instead of hard-coded percentages, so it always
      clamps to the actual free middle zone and can never drift onto the
      guidance banner or the camera wall regardless of breakpoint.
   The old bottom-above-dock slot is gone entirely — it was the source of the
   Reopen-button / Right-tile overlaps (verify-wave9 evidence). */
/* wave13 fix 6: on every view except Drive the strip sits 8 px under the rail,
   centred, as a translucent glass overlay. It is `position:fixed`, so it can
   never push the KPI strip or the content top down — it floats clear of them
   and fades out. */
.toast{position:fixed;left:50%;top:calc(var(--header-h) + 8px);z-index:46;transform:translateX(-50%) translateY(-6px);opacity:0;transition:opacity .2s var(--ease),transform .2s var(--ease);pointer-events:none;background:var(--glass);border:1px solid var(--hair2);border-left:4px solid var(--acc);border-radius:14px;padding:8px 14px;font-size:var(--fz-body);font-weight:600;max-width:min(560px,calc(100vw - 48px));min-height:48px;display:flex;align-items:center;gap:12px;box-shadow:var(--sh-lg);-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur)}
.toast .msg{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}
.toast.act-on{min-height:64px}
.toast .act{flex:0 0 auto;height:48px;padding:0 16px;border-radius:14px;background:rgba(255,255,255,.08);border:1px solid var(--hair2);color:var(--tx);font-size:var(--fz-body);font-weight:700}
.toast .act:active{transform:scale(.97)}
.toast.on{opacity:1;transform:translateX(-50%) translateY(0)}
.toast.act-on{pointer-events:auto}
.toast.info{border-left-color:var(--info)}.toast.warn{border-left-color:var(--minor)}.toast.bad{border-left-color:var(--crit)}

/* directional perimeter edge — Front=top · Left=left · Right=right · Rear=bottom
   (alert economy §5). Transient functional signalling, not decoration. */
/* Wave 6, defect 2: the 44 px blurred bloom these four rules used to carry was
   the "warm gradient at the bottom edge of the map stage" the wave-5 screenshot
   pass found — a Rear-camera medium/minor arrival washing 40 px of severity
   colour up into the stage. The signal is now a crisp 5 px bar on the camera's
   own edge: same directional meaning, no gradient over the city, and nothing
   that can be mistaken for the vignette. The vignette itself stays a pure
   #070A0B alpha ramp (see #vignette). */
#edge{position:fixed;inset:0;z-index:90;pointer-events:none;opacity:0;will-change:opacity}
#edge.on{animation:edgefade 900ms ease-out forwards}
#edge.dim.on{animation:edgefade 300ms ease-out forwards}
@keyframes edgefade{0%{opacity:1}100%{opacity:0}}
#edge.top{box-shadow:inset 0 5px 0 0 var(--ec)}
#edge.bottom{box-shadow:inset 0 -5px 0 0 var(--ec)}
#edge.left{box-shadow:inset 5px 0 0 0 var(--ec)}
#edge.right{box-shadow:inset -5px 0 0 0 var(--ec)}

