/* Homepage service-zone map (geofencing) */

/* Map-surface colours only — these match the OpenStreetMap Standard basemap
   artwork, not the brand palette, so they live here rather than in theme.css.
   Every brand colour on this component still resolves from the theme tokens. */
.zonemap-sec {
  --zonemap-land: #F2EFE9;
  --zonemap-surface: #fff;
  --zonemap-hairline: rgba(0, 0, 0, .1);
  --zonemap-mini-land: #E9E9EC;
  --zonemap-mini-road: #FFFFFF;

  /* Zone identity colours. These are the operator's own geofence palette —
     not brand tokens — so they live with the component. Declared once here
     and read by both the legend dots below and zone-map.js, which resolves
     them at runtime; there is no hex in the JS. */
  --zone-service:       var(--primary-color);
  --zone-rider:         #87A71B;
  --zone-noride:        #4B73E2;
  --zone-noparking:     #FF0000;
  --zone-slow:          #FF9900;
  --zone-parking:       #BC00E9;
  --zone-bonusparking:  #F5C700;
}

.zonemap-head {
  max-width: 720px;
  margin: 0 auto var(--space-10);
  text-align: center;
}

.zonemap-head p {
  color: var(--muted);
  font-size: var(--fs-body);
  margin-top: var(--space-3);
}

/* isolation contains Leaflet's internal panes and controls (z-index 400–1000)
   so they can never paint over the sticky site header */
.zonemap {
  position: relative;
  z-index: 0;
  isolation: isolate;
  height: 560px;
  width: 100%;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--zonemap-land);
  border: 1px solid var(--zonemap-hairline);
  box-shadow: var(--shadow-2);
  opacity: 0;
  transition: opacity .4s ease;
}

.zonemap.is-ready {
  opacity: 1;
}

.zonemap .leaflet-container {
  background: var(--zonemap-land);
  font-family: var(--font-family-base);
}

/* Clicking a zone focuses its SVG path, and browsers draw a rectangular
   focus ring around it — which reads as a stray box over the map. Suppressed
   for pointer input only; keyboard focus keeps a visible ring below. */
.zonemap .leaflet-interactive:focus,
.zonemap path:focus,
.zonemap svg:focus,
.zonemap .leaflet-container:focus {
  outline: none;
}

.zonemap .leaflet-interactive:focus-visible {
  outline: 2px solid var(--primary-color);
  outline-offset: 2px;
}

.zonemap .leaflet-tooltip {
  background: var(--zonemap-surface);
  border: 1px solid var(--zonemap-hairline);
  border-radius: var(--radius-badge);
  color: var(--color-heading);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
  padding: 6px 10px;
  box-shadow: var(--shadow-2);
}

.zonemap .leaflet-tooltip::before {
  border-top-color: var(--zonemap-surface);
}

/* Zone centre icons. Held back until the boundaries have finished tracing,
   so they don't sit on the map ahead of the zones they belong to. */
.zonemap .zonemap-pin {
  opacity: 0;
  transition: opacity .45s ease-out;
  pointer-events: none;
}

.zonemap.is-drawn .zonemap-pin {
  opacity: 1;
}

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

  .zm-ride-state.is-on .zm-scan-beam,
  .zm-ride-state.is-on .zm-rider,
  .zm-ride-state.is-on .zm-route-wipe-x,
  .zm-ride-state.is-on .zm-route-wipe-y,
  .zm-ops-live i {
    animation: none;
  }

  .zm-scan-beam {
    opacity: 1;
  }
}

.zonemap-stage {
  position: relative;
}

.zonemap-card {
  position: absolute;
  z-index: 2;
  background: var(--surface);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  font-family: var(--font-family-base);
  pointer-events: none;
  opacity: 0;
  transition: opacity .4s ease;
}

.zonemap.is-ready ~ .zonemap-card {
  opacity: 1;
}

.zm-ops {
  top: var(--space-4);
  left: var(--space-4);
  width: 292px;
  overflow: hidden;
}

.zm-ops-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-blue);
}

.zm-ops-title {
  color: var(--color-heading);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
}

.zm-ops-live {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-danger);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
}

.zm-ops-live i {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  animation: zm-live-pulse 1.6s infinite;
}

@keyframes zm-live-pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: .3;
  }
}

.zm-ops-body {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-3);
}

.zm-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-badge);
}

.zm-row-col {
  display: block;
}

.zm-row-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.zm-label {
  color: var(--color-text);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-medium);
}

.zm-figure {
  color: var(--color-heading);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
}

.zm-figure-blue {
  color: var(--primary-color);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
}

.zm-pill {
  flex: none;
  padding: 3px 12px;
  background: var(--primary-color);
  color: var(--white);
  border-radius: var(--radius-pill);
  font-size: var(--fs-caption);
  font-weight: var(--font-weight-semibold);
}

.zm-spark {
  display: block;
  width: 100%;
  height: auto;
  margin-top: var(--space-2);
}

.zm-spark-line {
  fill: none;
  stroke: var(--primary-color);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.zm-spark-stem {
  stroke: var(--primary-color);
  stroke-width: 1.5;
}

.zm-spark-dot {
  fill: var(--primary-color);
}

.zm-alert {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding: var(--space-2);
  background: var(--surface-blue);
  border-radius: var(--radius-badge);
}

.zm-alert-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  background: var(--surface);
  border-radius: var(--radius-badge);
}

.zm-alert-icon img {
  width: 22px;
  height: 22px;
  display: block;
}

.zm-alert-text {
  flex: 1 1 auto;
  display: grid;
  min-width: 0;
}

.zm-alert-text b {
  color: var(--primary-color);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
}

.zm-alert-text em {
  color: var(--color-muted);
  font-size: var(--fs-caption);
  font-style: normal;
}

.zm-alert-pct {
  flex: none;
  color: var(--color-danger);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
}

.zm-ride {
  right: var(--space-4);
  bottom: var(--space-4);
  width: 225px;
  padding: var(--space-2);
}

.zm-ride-states {
  display: grid;
}

.zm-ride-state {
  grid-area: 1 / 1;
  opacity: 0;
  transition: opacity .5s ease;
}

.zm-ride-state.is-on {
  opacity: 1;
}

.zm-ride-map {
  position: relative;
  height: 104px;
  background: var(--zonemap-mini-land);
  border-radius: var(--radius-badge);
  overflow: hidden;
}

.zm-ride-roads {
  display: block;
  width: 100%;
  height: 100%;
}

.zm-ride-marks {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.zm-route {
  fill: none;
  stroke: var(--primary-color);
  stroke-width: 3;
  stroke-dasharray: 7 7;
  stroke-linecap: round;
}

.zm-route-wipe-x {
  transform: translateX(42px);
}

.zm-route-wipe-y {
  transform: translateY(34px);
}

.zm-ride-state.is-on .zm-route-wipe-x {
  animation: zm-route-wipe-x 2.8s ease-in-out forwards;
}

.zm-ride-state.is-on .zm-route-wipe-y {
  animation: zm-route-wipe-y 2.8s ease-in-out forwards;
}

@keyframes zm-route-wipe-x {
  0%, 6% {
    transform: translateX(42px);
  }
  90%, 100% {
    transform: translateX(176px);
  }
}

@keyframes zm-route-wipe-y {
  0%, 90% {
    transform: translateY(34px);
  }
  100% {
    transform: translateY(44px);
  }
}

.zm-ride-scan {
  display: grid;
  place-items: center;
  background: var(--surface-blue);
}

.zm-qr {
  width: auto;
  height: 78%;
}

.zm-qr-mod {
  fill: var(--color-heading);
}

.zm-qr-frame path {
  fill: none;
  stroke: var(--primary-color);
  stroke-width: 5;
  stroke-linecap: round;
}

.zm-scan-beam {
  position: absolute;
  top: 16%;
  left: 16%;
  right: 16%;
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--primary-color);
  box-shadow: 0 0 10px 2px rgba(var(--primary-rgb), .55);
  opacity: 0;
}

.zm-ride-state.is-on .zm-scan-beam {
  animation: zm-scan 1.6s ease-in-out infinite;
}

@keyframes zm-scan {
  0% {
    top: 16%;
    opacity: 0;
  }
  15% {
    opacity: 1;
  }
  85% {
    opacity: 1;
  }
  100% {
    top: 80%;
    opacity: 0;
  }
}

.zm-rider-ring {
  fill: var(--surface);
  stroke: var(--primary-color);
  stroke-width: 2;
}

.zm-rider-glyph path {
  fill: var(--primary-color);
}

.zm-rider {
  transform: translate(42px, 34px);
}

.zm-ride-state.is-on .zm-rider {
  animation: zm-ride-travel 2.8s ease-in-out forwards;
}

@keyframes zm-ride-travel {
  0% {
    transform: translate(42px, 34px);
  }
  6% {
    transform: translate(42px, 34px);
  }
  90% {
    transform: translate(176px, 34px);
  }
  100% {
    transform: translate(176px, 44px);
  }
}

.zm-vpin {
  position: absolute;
  width: 21px;
  height: auto;
}

.zm-vpin-a {
  top: 10%;
  left: 46%;
}

.zm-vpin-b {
  top: 42%;
  left: 20%;
}

.zm-vpin-c {
  top: 42%;
  left: 72%;
}

.zm-road path {
  fill: none;
  stroke: var(--zonemap-mini-road);
  stroke-width: 9;
  stroke-linecap: round;
}

.zm-map-pin path {
  fill: var(--color-danger);
}

.zm-map-pin .zm-map-pin-eye {
  fill: var(--white);
}

.zm-ride-badge {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  background: var(--surface);
  border: 2px solid var(--primary-color);
  border-radius: 50%;
  box-shadow: var(--shadow-1);
}

.zm-ride-badge svg {
  width: 16px;
  height: 16px;
}

.zm-ride-badge svg path {
  fill: var(--primary-color);
}

.zm-ride-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding: var(--space-2);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-badge);
}

.zm-ride-text {
  display: grid;
  min-width: 0;
  white-space: nowrap;
}

.zm-ride-text b {
  color: var(--color-heading);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
}

.zm-ride-text em {
  color: var(--color-muted-2);
  font-size: var(--fs-caption);
  font-style: normal;
}

.zm-ride-btn {
  display: block;
  margin-top: var(--space-2);
  padding: var(--space-2);
  background: var(--primary-color);
  color: var(--white);
  border-radius: var(--radius-badge);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
  text-align: center;
}

.zonemap-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3) var(--space-6);
  margin-top: var(--space-6);
}

.zonemap-legend .lg {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--muted);
  font-size: var(--fs-small);
  font-weight: var(--font-weight-semibold);
}

.zonemap-legend .lg b {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: none;
}

.zonemap-legend .dot-service      { background: var(--zone-service); }
.zonemap-legend .dot-rider        { background: var(--zone-rider); }
.zonemap-legend .dot-parking      { background: var(--zone-parking); }
.zonemap-legend .dot-bonusparking { background: var(--zone-bonusparking); }
.zonemap-legend .dot-slow         { background: var(--zone-slow); }
.zonemap-legend .dot-noride       { background: var(--zone-noride); }
.zonemap-legend .dot-noparking    { background: var(--zone-noparking); }

/* ≤1024px */
@media (max-width: 1024px) {
  .zonemap {
    height: 480px;
  }

  .zm-ops {
    width: 262px;
  }

  .zm-ride-map {
    height: 88px;
  }
}

/* 769–1023px */
@media (min-width: 769px) and (max-width: 1023px) {
  .zm-ops {
    top: var(--space-3);
    left: var(--space-3);
    width: 230px;
  }

  .zm-ops-body {
    gap: var(--space-1);
    padding: var(--space-2);
  }

  .zm-row {
    padding: var(--space-1) var(--space-2);
  }

  .zm-ride {
    right: var(--space-3);
    bottom: var(--space-3);
    width: 184px;
  }

  .zm-ride-map {
    height: 72px;
  }
}

/* ≤768px */
@media (max-width: 768px) {
  .zonemap {
    height: 400px;
    border-radius: var(--radius-md);
  }

  .zonemap-head {
    margin-bottom: var(--space-6);
  }

  .zonemap-stage {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4);
    align-items: start;
  }

  .zonemap {
    grid-column: 1 / -1;
  }

  .zonemap-card,
  .zonemap.is-ready ~ .zonemap-card {
    position: static;
    width: auto;
    opacity: 1;
  }

  /* the mini-map SVGs are xMidYMid slice, so height has to follow width
     or the artwork is cropped away */
  .zm-ride-map {
    height: auto;
    aspect-ratio: 240 / 132;
  }
}

/* ≤560px */
@media (max-width: 560px) {
  .zonemap-stage {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
  }

  .zonemap-card,
  .zonemap.is-ready ~ .zonemap-card {
    width: 100%;
    max-width: 360px;
  }
}

/* ≤480px */
@media (max-width: 480px) {
  .zonemap {
    height: 340px;
  }

  .zonemap-legend {
    gap: var(--space-2) var(--space-4);
  }
}