/* Kept intentionally small: the frontend ships no custom CSS beyond layout
   helpers, so the operations view stays readable on a projector. */
body {
  margin: 0;
  background: #f9fafb;
}

table td {
  padding: 4px 14px 4px 0;
  border-bottom: 1px solid #f3f4f6;
}

.leaflet-container {
  background: #eef2f5;
}

/* Click detail on the map: readable at arm's length on a phone.
   Leaflet's defaults give one unwrapped line and no height cap, which is why
   long object details were unreadable. */
.leaflet-popup-content-wrapper {
  border-radius: 8px;
}

.ops-popup .leaflet-popup-content,
.leaflet-popup-content {
  margin: 10px 12px;
  font-size: 12px;
  line-height: 1.35;
  max-height: min(45vh, 320px);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.leaflet-popup-content b {
  font-weight: 600;
}

/* Map markers are inline SVG inside a Leaflet div icon, so the class must not
   inherit the default white box. A small shadow keeps the shapes readable over
   tiles that happen to be the same colour. */
.ops-pin {
  background: none;
  border: none;
}

.ops-pin svg {
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.45));
}

.leaflet-tooltip {
  font-size: 12px;
  padding: 4px 8px;
  white-space: nowrap;
}

/* --- map-first shell ------------------------------------------------------
   Google Maps' shape, which is the shape an operator already knows: the map
   fills the window, the ride card floats over its top-left corner, the
   controls fold into a sheet along the bottom, and the map's own controls sit
   in the corners the two leave free. Nothing covers the geography unless the
   operator asked for it. */
.ops-shell {
  position: relative;
  height: 100vh;
  height: 100dvh;
  width: 100%;
  overflow: hidden;
}

.ops-map {
  position: absolute;
  inset: 0;
}

/* --- the ride card: the top-left panel, Google Maps' search box ----------- */
.ops-card {
  position: absolute;
  top: 12px;
  left: 12px;
  width: 380px;
  max-width: calc(100% - 24px);
  max-height: calc(100vh - 150px);
  max-height: calc(100dvh - 150px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: #ffffff;
  border-radius: 16px;
  box-shadow: 0 6px 24px rgba(15, 23, 42, 0.22);
  z-index: 1000;
}

.ops-card-head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid #eef0f3;
  background: #ffffff;
  border-radius: 16px 16px 0 0;
}

.ops-card-title {
  flex: 1 1 auto;
  min-width: 0;
}

.ops-card-body {
  padding: 12px;
}

/* --- the summary: the city at a glance, above the ride form --------------
   One small card per live fact, four to a row, label on top and value under
   it. It used to be one sentence, so the clock, the fleet, the rides and the
   bays ran together and a value could not be found without reading the line.
   The grid takes the same rows the sentence took, so the card has not grown.
   It keeps the rule under it because it is the seam between "where the city
   is" and "what you are about to book". */
.ops-summary-cards {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eef0f3;
}

.ops-kpi-card {
  min-width: 0;
  background: #f8fafc;
  border: 1px solid #eef0f3;
  border-radius: 8px;
  padding: 4px 6px;
}

.ops-kpi-label {
  font-size: 9px;
  line-height: 1.2;
  color: #9ca3af;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ops-kpi-value {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  color: #111827;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The ▾ in both panels. A square, because it is a control, not a link. */
.ops-toggle {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  line-height: 1;
  font-size: 14px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #ffffff;
  cursor: pointer;
}

/* --- the bottom sheet: the knobs and the reference material ---------------
   Collapsed it is one bar at the bottom of the map, the way Google Maps'
   sheet is, and it grows upward when the operator wants it. */
.ops-sheet {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 0;
  max-width: 640px;
  margin: 0 auto;
  background: #ffffff;
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -4px 20px rgba(15, 23, 42, 0.18);
  z-index: 1000;
}

.ops-sheet-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
}

.ops-sheet-label {
  font-size: 12px;
  font-weight: 600;
  color: #111827;
}

.ops-sheet-body {
  padding: 0 12px 14px;
  max-height: 46vh;
  max-height: 46dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* --- the ride request: two ends, each with its own crosshair -------------- */
.ops-field-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
}

.ops-geo-badge {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  color: #ffffff;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ops-coord-input {
  flex: 1 1 0;
  min-width: 0;
  width: 100%;
  padding: 6px 8px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font-size: 12px;
}

.ops-locate-field {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  line-height: 1;
  font-size: 15px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  background: #f9fafb;
  cursor: pointer;
}

.ops-locate-field:hover {
  background: #eef2f5;
}

.ops-party-input {
  width: 60px;
  padding: 6px 8px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font-size: 12px;
}

.ops-book {
  padding: 7px 14px;
  border: none;
  border-radius: 6px;
  background: #0b6e4f;
  color: #ffffff;
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
}

.ops-field-note {
  font-size: 11px;
  color: #6b7280;
  line-height: 1.35;
  margin-top: 4px;
}

/* --- the address box, above the coordinates it fills ---------------------- */
/* The address is a convenience over coordinates, and it is laid out that way:
   the box the operator types an address into sits above the pair that the
   booking actually sends. */
.ops-field-block {
  margin-bottom: 10px;
}

.ops-addr-input {
  flex: 1 1 0;
  min-width: 0;
  width: 100%;
  padding: 6px 8px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font-size: 13px;
}

/* Matches appear *under the box as it is typed*, five at most, each one a
   click away from setting the ride point. A dropdown that had to be opened
   read as a second, empty address field. */
.ops-match {
  flex-direction: column;
  gap: 2px;
  margin-top: 4px;
}

.ops-sugg {
  display: block;
  width: 100%;
  text-align: left;
  font-size: 12px;
  line-height: 1.3;
  padding: 5px 8px;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  background: #ffffff;
  cursor: pointer;
  white-space: normal;
}

.ops-sugg:hover {
  background: #eef2f5;
  border-color: #cbd5e1;
}

/* A match outside the operating area is still an answer, and it is not a
   bookable one: it looks like the warning it is. */
.ops-sugg-near {
  color: #92400e;
  background: #fffbeb;
  border-color: #fde68a;
}

/* --- the two knobs, one row, never wrapping ------------------------------ */
.ops-knobs {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: nowrap;
}

/* --- the round buttons, bottom-right, Google Maps' corner ---------------- */
.ops-fab-wrap {
  position: absolute;
  right: 12px;
  /* Above the credit line, which sits at the bottom of this corner, and above
     the collapsed sheet, which spans the full width on a phone. */
  bottom: 76px;
  z-index: 1000;
}

.ops-fab {
  width: 42px;
  height: 42px;
  line-height: 1;
  font-size: 18px;
  border: none;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 2px 10px rgba(15, 23, 42, 0.28);
  cursor: pointer;
}

.ops-fab:hover {
  background: #f3f4f6;
}

/* --- the map's own controls: above the sheet, never behind it -------------
   The sheet owns the bottom edge at every width — full-width on a phone,
   centred on a desktop — so both bottom corners start above it. That is what
   puts the credit line directly under the round locate button (a credit line
   the operator cannot see is not a credit line) and the legend toggle on the
   left in front of the sheet rather than behind it. Measured before this, on a
   500px window: the legend toggle sat at y643 with the sheet, z-index 1000,
   drawn over it — `document.elementFromPoint` returned the sheet's own toggle. */
.ops-map .leaflet-bottom.leaflet-left,
.ops-map .leaflet-bottom.leaflet-right {
  margin-bottom: 52px;
}

/* The zoom control clears the round button. */
.ops-map .leaflet-control-zoom {
  margin-bottom: 74px;
}

/* --- narrow screens: the card is a top panel, the sheet a bottom bar ------ */
@media (max-width: 720px) {
  .ops-card {
    top: 8px;
    left: 8px;
    right: 8px;
    width: auto;
    max-height: 52vh;
    max-height: 52dvh;
  }

  .ops-sheet {
    left: 0;
    right: 0;
    border-radius: 16px 16px 0 0;
  }
}

/* --- wide windows: the sheet is centred, so the bottom corners are free ----
   There the round button, the credit line and the legend drop to the true
   bottom edge, exactly where Google Maps puts them. The threshold is
   arithmetic, not taste: the sheet is 640px wide and the credit line 246px
   plus its margin, so below 1132px of window the centred sheet still reaches
   into the right corner and the stack has to stay above it. */
@media (min-width: 1140px) {
  .ops-fab-wrap {
    bottom: 30px;
  }

  .ops-map .leaflet-bottom.leaflet-left,
  .ops-map .leaflet-bottom.leaflet-right {
    margin-bottom: 6px;
  }
}
