/* ==========================================================================
   MASAR — map surface: canvas, KPI HUD, time scrubber, readout, tooltip.
   ========================================================================== */

/* ── the map is full-bleed; all chrome floats above it ─────────────────── */
#map {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: var(--bg);
}

#map canvas { outline: none; }

/* Atmospheric horizon at pitch 55 — the distance hazes into the night sky.
   (maplibre-gl 4.7.1 has no sky/fog layer, so this is done in CSS.) */
#map::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(5, 8, 15, .82) 0%, rgba(6, 10, 20, .34) 13%, rgba(5, 8, 15, 0) 30%),
    radial-gradient(130% 80% at 50% 116%, rgba(34, 211, 238, .055), transparent 60%);
}

/* MapLibre resets — we supply our own chrome */
.maplibregl-ctrl-attrib,
.maplibregl-ctrl-logo { display: none !important; }

.maplibregl-ctrl-group {
  background: var(--panel) !important;
  border: var(--panel-border) !important;
  border-radius: var(--radius-sm) !important;
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow-sm) !important;
  overflow: hidden;
}
.maplibregl-ctrl-group button + button { border-block-start: 1px solid var(--hairline-soft) !important; }
.maplibregl-ctrl-group button { inline-size: 30px !important; block-size: 30px !important; }
.maplibregl-ctrl-group button:hover { background: rgba(120, 150, 200, .1) !important; }
.maplibregl-ctrl-group button .maplibregl-ctrl-icon { filter: invert(1) opacity(.62); }
.maplibregl-ctrl-bottom-right { inset-block-end: 12px; inset-inline-end: 12px; }

/* the compass/zoom cluster sits under the nav rail's column — the only strip
   that stays clear at every viewport width (the top band belongs to the KPI
   HUD, the far edge to #panel-root, and the bottom center to the timebar).
   MapLibre corners are physical, so mirror explicitly for RTL, where the rail
   (and the free column under it) is on the right. */
.maplibregl-ctrl-bottom-left { left: var(--gutter); bottom: var(--gutter); z-index: 32; }
[dir="rtl"] .maplibregl-ctrl-bottom-left { left: auto; right: var(--gutter); }

body.is-picking .maplibregl-canvas-container,
body.is-picking #map canvas { cursor: crosshair !important; }

/* ==========================================================================
   KPI HUD
   ========================================================================== */
.hud {
  position: fixed;
  z-index: 30;
  inset-block-start: calc(var(--topbar-h) + var(--gutter));
  inset-inline-start: calc(var(--rail-w) + var(--gutter) * 2);
  display: grid;
  grid-auto-flow: column;
  gap: var(--sp-1);
  pointer-events: none;
}
.hud > * { pointer-events: auto; }

.kpi {
  position: relative;
  inline-size: 172px;
  padding: 10px var(--sp-2) 11px;
  background: var(--panel);
  border: var(--panel-border);
  border-radius: var(--radius);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.kpi::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 1px;
  background: linear-gradient(90deg, transparent, rgba(124, 140, 255, .3), transparent);
}

.kpi__label {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.kpi__value {
  display: flex;
  align-items: baseline;
  gap: 5px;
  margin-block-start: 5px;
  min-block-size: 30px;
}

.kpi__num {
  font-family: var(--font-display);
  font-size: 27px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.015em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  direction: ltr;               /* Western digits stay LTR in both languages */
  unicode-bidi: isolate;
}

.kpi__unit {
  font-size: var(--fs-tiny);
  font-weight: 500;
  letter-spacing: .04em;
  color: var(--muted);
}

.kpi__meter {
  margin-block-start: 9px;
  block-size: 2px;
  border-radius: var(--radius-pill);
  background: rgba(120, 150, 200, .13);
  overflow: hidden;
}
.kpi__meter span {
  display: block;
  block-size: 100%;
  inline-size: 0%;
  border-radius: var(--radius-pill);
  background: var(--accent);
  box-shadow: 0 0 10px -1px currentColor;
  transition: inline-size .6s var(--ease-out), background-color .4s var(--ease);
}
.kpi[data-state='good'] .kpi__meter span { background: var(--good); }
.kpi[data-state='warn'] .kpi__meter span { background: var(--warn); }
.kpi[data-state='bad']  .kpi__meter span { background: var(--bad); }

/* skeleton shimmer until the first masar:kpis-updated */
.kpi.is-loading .kpi__num,
.kpi.is-loading .kpi__unit { visibility: hidden; }

.kpi.is-loading .kpi__value::after {
  content: '';
  position: absolute;
  inset-inline: var(--sp-2);
  block-size: 22px;
  border-radius: 6px;
  background: linear-gradient(100deg,
    rgba(120, 150, 200, .07) 20%,
    rgba(120, 150, 200, .17) 40%,
    rgba(120, 150, 200, .07) 62%);
  background-size: 260% 100%;
  animation: shimmer 1.5s var(--ease) infinite;
}
.kpi.is-loading .kpi__label { color: rgba(139, 152, 173, .55); }

@keyframes shimmer {
  from { background-position: 130% 0; }
  to   { background-position: -60% 0; }
}

.kpi.is-stalled .kpi__num { color: var(--muted); }

/* ==========================================================================
   Time scrubber
   ========================================================================== */
.timebar {
  position: fixed;
  z-index: 32;
  inset-block-end: var(--gutter);
  inset-inline-start: calc(var(--rail-w) + var(--gutter) * 2);
  inset-inline-end: var(--gutter);
  margin-inline: auto;
  inline-size: min(760px, 100%);
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  gap: var(--sp-2);
  padding: 11px var(--sp-2) 13px;
  background: var(--panel);
  border: var(--panel-border);
  border-radius: var(--radius);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow);
}

body.has-panel .timebar { inset-inline-end: calc(var(--panel-w, 392px) + var(--gutter)); }

/* Above 1320px the legend/telemetry card occupies the bottom-start corner, so
   the scrubber has to start after it — otherwise a panel narrows the centring
   box and pushes the scrubber onto the legend. */
@media (min-width: 1321px) {
  .timebar { inset-inline-start: calc(var(--rail-w) + var(--gutter) * 3 + 224px); }
}

.timebar__play {
  inline-size: 38px;
  block-size: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(34, 211, 238, .34);
  background: radial-gradient(120% 120% at 32% 18%, rgba(34, 211, 238, .24), rgba(10, 16, 28, .5));
  color: var(--accent);
  transition: box-shadow .2s var(--ease), border-color .2s var(--ease), transform .12s var(--ease);
}
.timebar__play:hover { box-shadow: var(--glow-accent); border-color: rgba(34, 211, 238, .6); }
.timebar__play:active { transform: scale(.94); }
.timebar__play svg { inline-size: 15px; block-size: 15px; fill: currentColor; }
.timebar__play .icon-pause { display: none; }
.timebar__play[data-playing='true'] .icon-play { display: none; }
.timebar__play[data-playing='true'] .icon-pause { display: block; }

.timebar__readout {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-inline-size: 76px;
}
.timebar__time {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
  direction: ltr;
  unicode-bidi: isolate;
  text-align: start;
}
.timebar__day {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.timebar__scrub { display: flex; flex-direction: column; gap: 5px; min-inline-size: 0; }

.timebar__track {
  position: relative;
  block-size: 34px;
  cursor: pointer;
  touch-action: none;
  border-radius: var(--radius-xs);
}
/* clock axes never mirror: hours run 00→24 left-to-right in BOTH languages,
   matching the panels' charts (a mirrored time axis reads as a bug). Applies
   to the track (playhead, fill, drag math — timebar.js reads its computed
   direction) and the tick row, which is a sibling of the track. */
.timebar__track,
.timebar__ticks { direction: ltr; }
.timebar__track:focus-visible { outline-offset: 4px; }

/* congestion-by-hour ribbon: the day's shape, straight from the baseline data */
.timebar__ribbon {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 22px;
  inline-size: 100%;
  overflow: visible;
  pointer-events: none;
}
.timebar__ribbon .ribbon-area { fill: url(#ribbon-grad); }
.timebar__ribbon .ribbon-line { fill: none; stroke: rgba(148, 178, 214, .5); stroke-width: 1; }

.timebar__rail {
  position: absolute;
  inset-block-start: 24px;
  inset-inline: 0;
  block-size: 4px;
  border-radius: var(--radius-pill);
  background: rgba(120, 150, 200, .16);
  overflow: hidden;
}
.timebar__fill {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 0%;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, rgba(124, 140, 255, .55), var(--accent));
  box-shadow: 0 0 12px -1px rgba(34, 211, 238, .8);
}

.timebar__head {
  position: absolute;
  inset-block-start: 15px;
  inset-inline-start: 0;
  inline-size: 2px;
  block-size: 22px;
  margin-inline-start: -1px;
  border-radius: 2px;
  background: #eaf6ff;
  box-shadow: 0 0 14px 1px rgba(34, 211, 238, .95);
  pointer-events: none;
}
.timebar__head::after {
  content: '';
  position: absolute;
  /* head top is 15px into the track; the rail's center line is at 26px —
     11px down keeps the knob riding ON the bar, not dangling under it */
  inset-block-start: 11px;
  inset-inline-start: 50%;
  transform: translate(-50%, -50%);
  inline-size: 11px;
  block-size: 11px;
  border-radius: 50%;
  background: #eaf6ff;
  box-shadow: 0 0 16px 2px rgba(34, 211, 238, .9);
  transition: transform .12s var(--ease);
}
.timebar__track:hover .timebar__head::after,
.timebar__track.is-dragging .timebar__head::after { transform: translate(-50%, -50%) scale(1.18); }

.timebar__ticks {
  position: relative;
  block-size: 11px;
  font-size: var(--fs-micro);
  color: rgba(139, 152, 173, .82);
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
}
.timebar__tick {
  position: absolute;
  inset-block-start: 0;
  transform: translateX(-50%);
  letter-spacing: .04em;
  white-space: nowrap;
  unicode-bidi: isolate;
}
.timebar__tick::before {
  content: '';
  position: absolute;
  inset-block-start: -9px;
  inset-inline-start: 50%;
  inline-size: 1px;
  block-size: 4px;
  background: rgba(120, 150, 200, .3);
}
.timebar__tick.is-peak { color: #f0c977; }
.timebar__tick.is-peak::before { background: rgba(251, 191, 36, .6); }

/* ==========================================================================
   Bottom-start readout: legend + telemetry + attribution
   ========================================================================== */
.readout {
  position: fixed;
  z-index: 28;
  inset-block-end: var(--gutter);
  inset-inline-start: calc(var(--rail-w) + var(--gutter) * 2);
  inline-size: 224px;
  padding: 10px 12px 9px;
  background: var(--panel);
  border: var(--panel-border);
  border-radius: var(--radius);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow);
}

.readout__title {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--muted);
}

.readout__ramp {
  margin-block-start: 7px;
  block-size: 6px;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, #e11d48 0%, #fb4d5d 16%, #fb923c 34%, #fbbf24 50%, #34d399 70%, #22d3ee 88%, #1ac8e2 100%);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
}
[dir='rtl'] .readout__ramp {
  background: linear-gradient(270deg, #e11d48 0%, #fb4d5d 16%, #fb923c 34%, #fbbf24 50%, #34d399 70%, #22d3ee 88%, #1ac8e2 100%);
}

.readout__scale {
  display: flex;
  justify-content: space-between;
  margin-block-start: 5px;
  font-size: var(--fs-micro);
  color: rgba(139, 152, 173, .86);
  letter-spacing: .04em;
}

.readout__div { height: 1px; margin: 9px -12px 8px; background: var(--hairline-soft); }

.readout__stats {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: var(--fs-micro);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.readout__dot {
  inline-size: 6px;
  block-size: 6px;
  border-radius: 50%;
  background: var(--good);
  box-shadow: 0 0 8px 1px rgba(52, 211, 153, .8);
  flex: none;
  transition: background-color .3s var(--ease);
}
.readout__dot[data-level='warn'] { background: var(--warn); box-shadow: 0 0 8px 1px rgba(251, 191, 36, .8); }
.readout__dot[data-level='bad']  { background: var(--bad);  box-shadow: 0 0 8px 1px rgba(251, 77, 93, .8); }
.readout__sep { opacity: .4; }

.readout__attrib {
  margin-block-start: 7px;
  font-size: 9.5px;
  line-height: 1.45;
  color: rgba(139, 152, 173, .62);
}
.readout__attrib a { color: rgba(139, 152, 173, .82); text-decoration: none; }
.readout__attrib a:hover { color: var(--accent); text-decoration: underline; }

@media (max-width: 1320px) { .readout { display: none; } }

/* ==========================================================================
   Edge tooltip
   ========================================================================== */
.map-tip {
  position: fixed;
  z-index: 36;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: 232px;
  padding: 10px 12px 11px;
  background: rgba(8, 13, 24, .9);
  border: var(--panel-border);
  border-radius: var(--radius-sm);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow);
  pointer-events: none;
  opacity: 0;
  transform: translate3d(0, 0, 0);
  transition: opacity .12s var(--ease);
}
.map-tip.is-on { opacity: 1; }

.map-tip__name {
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1.25;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.map-tip__ar {
  font-family: var(--font-ar);
  font-size: var(--fs-xs);
  color: var(--muted);
  direction: rtl;
  text-align: start;
  margin-block-start: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.map-tip__chip {
  display: inline-block;
  margin-block-start: 7px;
  padding: 2px 7px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}
.map-tip__grid {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3px var(--sp-1);
  margin-block-start: 9px;
  font-size: var(--fs-tiny);
}
.map-tip__k { color: var(--muted); }
.map-tip__v {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  color: var(--text);
  text-align: end;
  direction: ltr;
  unicode-bidi: isolate;
}
.map-tip__v[data-state='good'] { color: var(--good); }
.map-tip__v[data-state='warn'] { color: var(--warn); }
.map-tip__v[data-state='bad']  { color: var(--bad); }

.map-tip__bar {
  margin-block-start: 9px;
  block-size: 3px;
  border-radius: var(--radius-pill);
  background: rgba(120, 150, 200, .14);
  overflow: hidden;
}
.map-tip__bar span {
  display: block;
  block-size: 100%;
  border-radius: var(--radius-pill);
  background: var(--accent);
  box-shadow: 0 0 8px -1px currentColor;
}

/* ==========================================================================
   Pick-mode prompt
   ========================================================================== */
.pick-hint {
  position: fixed;
  z-index: 38;
  inset-block-start: calc(var(--topbar-h) + 152px);
  inset-inline: 0;
  margin-inline: auto;
  inline-size: max-content;
  max-inline-size: 82vw;
  display: none;
  align-items: center;
  gap: var(--sp-1);
  padding: 9px 15px;
  border-radius: var(--radius-pill);
  background: rgba(8, 13, 24, .88);
  border: 1px solid rgba(34, 211, 238, .34);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--glow-accent), var(--shadow);
  font-size: var(--fs-xs);
  letter-spacing: .03em;
}
body.is-picking .pick-hint { display: flex; }
.pick-hint__pulse {
  inline-size: 7px;
  block-size: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px 1px rgba(34, 211, 238, .9);
  animation: pick-pulse 1.4s var(--ease) infinite;
  flex: none;
}
@keyframes pick-pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(.6); opacity: .55; }
}

/* ==========================================================================
   Scenario / route mode banner (map state must always be legible)
   ========================================================================== */
.map-mode {
  position: fixed;
  z-index: 31;
  /* clears the KPI row, which occupies the same top band */
  inset-block-start: calc(var(--topbar-h) + var(--gutter) + 96px);
  inset-inline: 0;
  margin-inline: auto;
  inline-size: max-content;
  display: none;
  align-items: center;
  gap: 10px;
  padding: 7px 8px 7px 14px;
  border-radius: var(--radius-pill);
  background: rgba(8, 13, 24, .88);
  border: var(--panel-border);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow);
  font-size: var(--fs-tiny);
  letter-spacing: .05em;
}
body.is-diff .map-mode,
body.is-routing .map-mode { display: flex; }

.map-mode__swatches { display: flex; align-items: center; gap: 6px; color: var(--muted); }
.map-mode__sw {
  inline-size: 9px;
  block-size: 3px;
  border-radius: 2px;
  display: inline-block;
}
.map-mode__sw--good { background: var(--good); box-shadow: 0 0 8px -1px var(--good); }
.map-mode__sw--bad  { background: var(--bad);  box-shadow: 0 0 8px -1px var(--bad); }
.map-mode__label { font-weight: 600; color: var(--text); }
.map-mode__clear {
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: .08em;
  color: var(--muted);
  transition: color .16s var(--ease), border-color .16s var(--ease);
}
.map-mode__clear:hover { color: var(--text); border-color: var(--hairline-strong); }

/* ==========================================================================
   Fill roots owned by the panels layer — reserve the space, stay invisible
   ========================================================================== */
#panel-root {
  position: fixed;
  z-index: 34;
  inset-block-start: calc(var(--topbar-h) + var(--gutter));
  inset-block-end: var(--gutter);
  inset-inline-end: var(--gutter);
  inline-size: var(--panel-w, 392px);
  max-inline-size: calc(100vw - var(--rail-w) - var(--gutter) * 4);
  pointer-events: none;
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}
#panel-root > * { pointer-events: auto; }
#panel-root:empty { display: none; }

#modal-root { position: fixed; inset: 0; z-index: 70; pointer-events: none; }
#modal-root > * { pointer-events: auto; }
#modal-root:empty { display: none; }

#report-root { position: fixed; inset: 0; z-index: 60; pointer-events: none; }
#report-root > * { pointer-events: auto; }
#report-root:empty { display: none; }

@media (max-width: 1180px) {
  .hud { grid-auto-flow: row; grid-template-columns: repeat(2, 1fr); }
  .kpi { inline-size: 150px; }
}

@media (max-width: 900px) {
  .hud { display: none; }
}
