* { margin: 0; box-sizing: border-box; }
html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: #10141a;
  color: #1c2430;
  overflow: hidden;
}

/* Explicit viewport dimensions, not just inset: the classic Google Maps
   constructor sets position:relative inline on the container, which
   collapses an inset-sized fixed div to 0 height (found 2026-08-07). */
#map { position: fixed; inset: 0; width: 100vw; height: 100dvh; }
/* One persistent pane per engine — switching shows/hides, never
   destroys (Google Maps cannot be torn down; zombies hang the page). */
.map-pane { position: absolute; inset: 0; width: 100%; height: 100%; }

#brand {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 10;
  padding: 6px 12px;
  border-radius: 8px;
  background: rgba(16, 20, 26, .82);
  color: #e8ecf1;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: .08em;
  user-select: none;
}
#brand .red { color: #e53935; }
#tile-count { font-weight: 400; color: #aeb8c4; }

#rides-panel {
  top: 62px;
  right: 12px;
  width: min(340px, calc(100vw - 24px));
  max-height: 70vh;
  overflow-y: auto;
}
#rides-panel .ride-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px 10px 16px;
  border-top: 1px solid #f1f3f4;
}
#rides-panel .ride-row:first-child { border-top: none; }
#rides-panel .ride-main { flex: 1; min-width: 0; cursor: pointer; }
#rides-panel .ride-name {
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#rides-panel .ride-sub {
  font-size: 12px;
  color: #5f6368;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#rides-panel .ride-del {
  border: none;
  background: none;
  color: #9aa0a6;
  font-size: 15px;
  cursor: pointer;
  padding: 6px;
}
#rides-panel .ride-del:hover { color: #e53935; }
#rides-panel .bin-actions { display: flex; gap: 6px; margin-top: 6px; }
#rides-panel .bin-actions button {
  border: 1px solid #dadce0;
  background: #fff;
  border-radius: 12px;
  font-size: 11.5px;
  padding: 3px 10px;
  cursor: pointer;
  color: #3c4043;
}
#rides-panel .bin-actions button:hover { background: #f1f3f4; }
#rides-panel .bin-actions .bin-danger { color: #c62828; }

#toast {
  position: fixed;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  background: rgba(16, 20, 26, .92);
  color: #e8ecf1;
  padding: 10px 16px;
  border-radius: 8px;
  font-size: 14px;
  max-width: min(520px, 90vw);
  text-align: center;
}
#toast[hidden] { display: none; }

#drop-hint {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: grid;
  place-items: center;
  background: rgba(229, 57, 53, .18);
  border: 4px dashed #e53935;
  font-size: 1.3rem;
  font-weight: 700;
  color: #b71c1c;
  pointer-events: none;
}
#drop-hint[hidden] { display: none; }

/* --- circular buttons, app-FAB style (white surface, dark icon) --- */
.chip-btn {
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
  display: grid;
  place-items: center;
  cursor: pointer;
  z-index: 10;
  padding: 0;
}
.chip-btn svg { width: 22px; height: 22px; fill: #3c4043; }
.chip-btn:active { background: #f1f3f4; }

#menu-btn { position: fixed; top: 10px; right: 12px; }

/* Bottom-anchored: hiding/showing the FIRST child (re-center) grows or
   shrinks the stack upward, so the fixed icons below it never move. */
#action-stack {
  position: fixed;
  right: 12px;
  bottom: 28px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 10;
}
#action-stack .chip-btn { position: static; }
/* …except the layers thumb: its preview spans anchor to the BUTTON.
   Without this, the id-scoped static rule above won and the thumbnail
   stretched over the whole stack, hiding search/planner (2026-08-09). */
#action-stack .thumb-btn { position: relative; }

/* --- panels --- */
.panel {
  position: fixed;
  z-index: 20;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .3);
  overflow: hidden;
  min-width: 180px;
  /* Never wider than the phone: long settings rows once pushed the
     right-anchored panel off the LEFT edge of an iPhone (2026-08-08). */
  max-width: min(360px, calc(100vw - 24px));
}
#menu-panel { top: 62px; right: 12px; }
#layers-panel { bottom: 28px; right: 64px; }

.panel .row {
  display: block;
  width: 100%;
  border: none;
  background: none;
  text-align: left;
  font-size: 15px;
  color: #1c2430;
  padding: 12px 16px;
  cursor: pointer;
  white-space: normal; /* wrap on phones — nowrap blew the panel width */
  overflow: hidden;
}
.panel .row:hover:not(:disabled) { background: #f1f3f4; }
.panel .row:disabled { color: #9aa0a6; cursor: default; }
.panel .row.active { font-weight: 700; }
.panel .row.active::after { content: " ✓"; color: #e53935; }
.panel .sep { height: 1px; background: #e8eaed; margin: 4px 0; }
.panel .row.muted { color: #9aa0a6; cursor: default; }

/* Settings (mirrors the app's Settings screen sections) */
#settings-panel { top: 62px; right: 12px; max-height: calc(100dvh - 90px); overflow-y: auto; }
.panel .sect {
  padding: 10px 14px 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #9aa0a6;
}
.panel .row-sub { display: block; font-size: 11.5px; color: #9aa0a6; margin-top: 2px; }
/* Destructive row label (Settings → Clear this browser's data) — the
   sheet-actions danger red on a menu row. */
.panel .row .danger-text { color: #c5221f; }

/* Ride/plan detail sheet — bottom card, map stays visible (app parity) */
.sheet {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 16px;
  z-index: 30;
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, .35);
  width: min(360px, calc(100vw - 24px));
  padding: 14px 16px 10px;
}
.sheet[hidden] { display: none; }
#sheet-close {
  position: absolute; top: 8px; right: 10px;
  border: none; background: none; cursor: pointer;
  font-size: 14px; color: #9aa0a6;
}
#sheet-title-row {
  display: flex; align-items: center; gap: 6px; padding-right: 24px;
}
#sheet-title-row[hidden] { display: none; }
#sheet-title { font-size: 16px; font-weight: 700; min-width: 0; }
/* The one edit pencil (name + description) — the site's muted
   icon-button voice. */
#sheet-edit-pencil {
  border: none; background: none; cursor: pointer; padding: 1px 2px;
  color: #9aa0a6; flex: none;
}
#sheet-edit-pencil svg { width: 14px; height: 14px; fill: currentColor; display: block; }
#sheet-edit-pencil:hover { color: #3c4043; }
/* Combined name/description editor — the media gallery's .mg-editbar
   pattern translated to the sheet's light palette; Save is the site's
   primary red pill. */
#sheet-editbar { display: flex; flex-direction: column; gap: 8px; margin: 0 0 8px; }
#sheet-editbar[hidden] { display: none; }
#sheet-editbar input, #sheet-editbar textarea {
  width: 100%; font: inherit; color: #1c2430;
  border: 1px solid #dadce0; border-radius: 8px; padding: 6px 8px;
}
#sheet-editbar input { font-size: 15px; }
#sheet-editbar textarea { font-size: 13px; resize: vertical; }
#sheet-editbar textarea[hidden] { display: none; }
#sheet-edit-actions { display: flex; gap: 8px; justify-content: flex-end; }
#sheet-edit-actions button {
  border: none; border-radius: 999px; padding: 6px 14px; font-size: 13px;
  cursor: pointer; background: #f1f3f4; color: #1c2430;
}
#sheet-edit-actions button:hover { background: #e8eaed; }
#sheet-edit-actions #sheet-edit-save, #sheet-edit-actions #sheet-edit-save:hover {
  background: #e53935; color: #fff;
}
#save-plan-name {
  font-size: 15px; width: calc(100% - 36px); margin: 8px 18px 2px;
  border: 1px solid #dadce0; border-radius: 8px; padding: 6px 8px;
}
#sheet-sub { font-size: 12.5px; color: #9aa0a6; margin: 2px 0 8px; }
/* Cover photo strip (ride.coverMediaId) — the share card's #share-cover,
   sheet-sized. */
#sheet-cover {
  display: block; width: 100%; max-height: 140px; object-fit: cover;
  border-radius: 10px; margin: 0 0 8px;
}
#sheet-cover[hidden] { display: none; }
/* Ride description display — edited via the title pencil's combined
   editor. */
#sheet-desc { font-size: 13px; color: #3c4043; margin: 0 0 8px; white-space: pre-wrap; }
#sheet-desc[hidden] { display: none; }

/* Inline attach-media upload progress ("Uploading 2 of 5…"). */
#sheet-media-progress { font-size: 13px; color: #9aa0a6; margin: 0 0 8px; }
#sheet-media-progress[hidden] { display: none; }
.stat-row {
  display: flex; justify-content: space-between; gap: 18px;
  font-size: 13.5px; padding: 3px 0;
}
.modal-card .stat-row { padding: 3px 18px; }
.stat-row span { color: #5f6368; }
.muted-row { color: #9aa0a6; }
.sheet-actions {
  display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end;
  margin-top: 10px; padding-top: 8px; border-top: 1px solid #e8eaed;
}
.modal-note {
  padding: 0 18px 10px;
  font-size: 12.5px;
  color: #5f6368;
  /* Confirm notes can carry a per-ride line list (Fix all). */
  white-space: pre-line;
}
.sheet-actions button {
  border: none; background: #f1f3f4; border-radius: 8px;
  padding: 8px 14px; font-size: 13.5px; cursor: pointer; color: #1c2430;
}
.sheet-actions button:hover { background: #e8eaed; }
.sheet-actions .danger { color: #c5221f; }
.sheet-actions .primary { background: #e53935; color: #fff; }
.sheet-actions .primary:hover { background: #d32f2f; }
/* Compact icon actions (2026-08-19, app-sheet harmonization): same
   pill background, icon instead of a label; tooltips carry the verb. */
.sheet-actions .icon-btn {
  display: inline-flex; align-items: center; gap: 4px; padding: 8px 10px;
  color: #3c4043;
}
.sheet-actions .icon-btn svg {
  width: 17px; height: 17px; fill: currentColor; display: block;
}
.sheet-actions .icon-btn .count { font-size: 12px; line-height: 1; }
.sheet-actions .icon-btn.danger { color: #c5221f; }
/* Share icon turns Floateers-blue once a live link exists. */
.sheet-actions #sheet-share.shared { color: #1a73e8; }

/* Route-sketch toolbar — bottom center while drafting */
#sketch-bar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 16px;
  z-index: 30;
  background: #fff;
  border-radius: 24px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .3);
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px 8px 16px;
  max-width: calc(100vw - 24px);
}
#sketch-bar[hidden] { display: none; }
#sketch-stats { font-size: 13px; color: #1c2430; white-space: nowrap; }
#sketch-bar button {
  border: none; background: #f1f3f4; border-radius: 16px;
  padding: 7px 12px; font-size: 13px; cursor: pointer;
}
/* Compact icon controls (2026-08-19, app route-toolbar harmonization):
   same pill background as .sheet-actions .icon-btn; tooltips carry the
   verbs. Disabled = the app's greyed toolbar buttons. */
#sketch-bar .icon-btn {
  display: inline-flex; align-items: center; padding: 8px 10px;
  color: #3c4043;
}
#sketch-bar .icon-btn svg {
  width: 17px; height: 17px; fill: currentColor; display: block;
}
#sketch-bar button:hover:not(:disabled) { background: #e8eaed; }
#sketch-bar button:disabled { opacity: .4; cursor: default; }
#sketch-bar .danger { color: #c5221f; }
#sketch-bar .primary { background: #e53935; color: #fff; }
#sketch-bar .primary:hover:not(:disabled) { background: #d32f2f; }

/* Crop bar (entry 34): sketch-bar's visual family, stacked because the
   slider needs the width. The two-thumb timeline is two overlaid range
   inputs; only the thumbs receive pointer events, so both stay
   draggable. Start thumb green, end thumb red (the glow dwell palette). */
#crop-bar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 16px;
  z-index: 30;
  background: #fff;
  border-radius: 18px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .3);
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px 16px;
  width: min(440px, calc(100vw - 24px));
}
#crop-bar[hidden] { display: none; }
#crop-stats { font-size: 13px; color: #1c2430; text-align: center; }
.crop-slider { position: relative; height: 28px; }
.crop-slider input[type=range] {
  position: absolute; inset: 0; width: 100%; margin: 0;
  -webkit-appearance: none; appearance: none;
  background: none; pointer-events: none;
}
.crop-slider input[type=range]::-webkit-slider-runnable-track {
  height: 4px; margin-top: 12px; background: #ffd600; border-radius: 2px;
}
.crop-slider input#crop-end::-webkit-slider-runnable-track { background: none; }
.crop-slider input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 20px; height: 20px; border-radius: 50%;
  border: 3px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.4);
  margin-top: -8px; pointer-events: auto; cursor: grab;
}
.crop-slider input#crop-start::-webkit-slider-thumb { background: #00e676; }
.crop-slider input#crop-end::-webkit-slider-thumb { background: #ff5252; }
.crop-slider input[type=range]::-moz-range-track {
  height: 4px; background: #ffd600; border-radius: 2px;
}
.crop-slider input#crop-end::-moz-range-track { background: none; }
.crop-slider input[type=range]::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%;
  border: 3px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.4);
  pointer-events: auto; cursor: grab;
}
.crop-slider input#crop-start::-moz-range-thumb { background: #00e676; }
.crop-slider input#crop-end::-moz-range-thumb { background: #ff5252; }
.crop-actions { display: flex; justify-content: center; gap: 8px; }
.crop-actions button {
  border: none; background: #f1f3f4; border-radius: 16px;
  padding: 7px 14px; font-size: 13px; cursor: pointer;
}
.crop-actions .primary { background: #e53935; color: #fff; }
.crop-actions .primary:disabled { opacity: .4; cursor: default; }

/* Layers thumbnail button (Google-style): rounded square preview of
   the view a click switches to, tiny label at the bottom. */
.thumb-btn {
  position: relative;
  width: 48px;
  height: 48px;
  border-radius: 10px;
  padding: 0;
  overflow: hidden;
  border: 2px solid #fff;
  box-sizing: border-box;
}
.thumb { position: absolute; inset: 0; display: block; }
.thumb[hidden] { display: none; }
.thumb svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.thumb i {
  position: absolute;
  left: 0; right: 0; bottom: 1px;
  font: 600 8px/1.2 sans-serif;
  font-style: normal;
  color: #fff;
  text-align: center;
  text-shadow: 0 0 3px rgba(0, 0, 0, .9), 0 0 3px rgba(0, 0, 0, .9);
  pointer-events: none;
}

/* Planner popover sits by the action stack; active mode tints the chip */
#planner-panel { bottom: 76px; right: 64px; }
.chip-btn.active-mode { background: #e53935; }
.chip-btn.active-mode svg { fill: #fff; }
.chip-btn.active-mode svg .trail { stroke: #fff; }

/* "Under construction" notice — Jeroen shows the site to friends but
   nobody should expect a finished product yet (2026-08-08). Remove
   this block (and the div in index.html) at launch. */
#construction {
  position: fixed;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 18;
  background: #fff3cd;
  color: #664d03;
  border: 1px solid #ffda6a;
  border-radius: 999px;
  padding: 6px 14px;
  font: 600 12.5px/1.4 sans-serif;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
  pointer-events: none;
  white-space: nowrap;
}
@media (max-width: 560px) {
  #construction { top: 54px; } /* below brand+menu on phones */
}

/* Slow-renderer warning: shown when the site had to fall back to the
   Canvas-2D map because the browser blocks WebGL (Brave Shields
   Strict is the common case). Dismissible per session. */
#perf-warning {
  position: fixed;
  top: 44px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 18;
  background: #fdecea;
  color: #7a1f1c;
  border: 1px solid #f5b9b5;
  border-radius: 12px;
  padding: 8px 34px 8px 14px;
  font: 500 12.5px/1.45 sans-serif;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
  max-width: min(520px, calc(100vw - 24px));
}
#perf-warning[hidden] { display: none; }
#perf-warning-close {
  position: absolute;
  top: 6px;
  right: 8px;
  border: none;
  background: none;
  color: #7a1f1c;
  font-size: 13px;
  cursor: pointer;
}
@media (max-width: 560px) {
  #perf-warning { top: 88px; }
}

/* Scale bar: bottom-right, just left of the action stack (Jeroen,
   2026-08-08). Engine-independent — drawn from bounds math in ui.js. */
#scale-bar {
  position: fixed;
  right: 68px;
  bottom: 30px;
  z-index: 15;
  pointer-events: none;
  text-align: right;
}
#scale-label {
  font: 500 11px/1.4 sans-serif;
  color: #1c2430;
  text-shadow: 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff;
  padding-right: 2px;
}
#scale-line {
  height: 5px;
  border: 2px solid #1c2430;
  border-top: none;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .7), -1px 0 0 rgba(255, 255, 255, .7), 1px 0 0 rgba(255, 255, 255, .7);
  margin-left: auto;
}

/* Route-sketch editor markers (app _buildRouteMarkers): violet
   draggable waypoints, S/E endpoint badges, translucent magenta
   midpoint handles. Shared by the Leaflet and MapLibre adapters. */
.fl-wp {
  width: 16px; height: 16px; border-radius: 50%;
  background: #7C4DFF; border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .4);
  box-sizing: border-box;
  cursor: grab;
}
.fl-wp-badge {
  width: 22px; height: 22px;
  color: #fff; font: 700 11px/18px sans-serif; text-align: center;
}
.fl-mid {
  width: 14px; height: 14px; border-radius: 50%;
  background: #d81b60; border: 2px solid #fff;
  box-sizing: border-box;
  opacity: .45;
  cursor: grab;
}
.fl-mid:hover { opacity: .9; }

/* Segmented tabs in the rides panel (app rides_screen Ridden/Planned/Bin) */
.seg-tabs {
  display: flex;
  margin: 10px 12px 6px;
  border: 1px solid #dadce0;
  border-radius: 999px;
  overflow: hidden;
}
.seg-tabs button {
  flex: 1;
  border: none;
  background: none;
  padding: 7px 4px;
  font-size: 12.5px;
  color: #1c2430;
  cursor: pointer;
  white-space: nowrap;
}
.seg-tabs button + button { border-left: 1px solid #dadce0; }
.seg-tabs button.active { background: #fde3e2; font-weight: 700; }

/* Search + sort toolbar under the tabs (2026-08-19) */
.list-tools {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 12px 8px;
}
.list-search { position: relative; flex: 1; min-width: 0; }
.list-search input {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #dadce0;
  border-radius: 999px;
  padding: 5px 28px 5px 12px;
  font-size: 12.5px;
  color: #1c2430;
  background: #fff;
  outline: none;
}
.list-search input:focus { border-color: #e53935; }
.list-search .list-clear {
  position: absolute;
  right: 2px;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: none;
  color: #9aa0a6;
  font-size: 13px;
  padding: 4px 8px;
  cursor: pointer;
}
.list-search .list-clear:hover { color: #e53935; }
.list-sort,
.list-dir {
  border: 1px solid #dadce0;
  border-radius: 999px;
  background: #fff;
  font-size: 12px;
  color: #3c4043;
  padding: 4px 8px;
  cursor: pointer;
}
.list-sort { max-width: 92px; }
.list-sort:hover,
.list-dir:hover { background: #f1f3f4; }

/* Modal dialog (import mode) */
.modal {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(0, 0, 0, .4);
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal[hidden] { display: none; }
.modal-card {
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, .4);
  min-width: 260px;
  max-width: 86vw;
  padding: 6px 0 8px;
}
.modal-card .row {
  display: block;
  width: 100%;
  border: none;
  background: none;
  text-align: left;
  font-size: 15px;
  color: #1c2430;
  padding: 12px 18px;
  cursor: pointer;
}
.modal-card .row:hover { background: #f1f3f4; }
.modal-card .row-sub { display: block; font-size: 11.5px; color: #9aa0a6; margin-top: 2px; }
.modal-title {
  padding: 14px 18px 8px;
  font-size: 16px;
  font-weight: 700;
}

/* --- Profile modal (accounts round 2026-08-20) --- */
.profile-card { width: min(340px, 86vw); }
#profile-avatar {
  position: relative;
  display: block;
  margin: 2px auto 0;
  width: 84px;
  height: 84px;
  border: none;
  border-radius: 50%;
  padding: 0;
  overflow: hidden;
  background: #f1f3f4;
  cursor: pointer;
}
#profile-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
#profile-avatar img[hidden] { display: none; }
#profile-avatar-fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 34px;
  font-weight: 700;
  color: #9aa0a6;
}
#profile-avatar-fallback[hidden] { display: none; }
.profile-hint { text-align: center; font-size: 11.5px; color: #9aa0a6; margin: 6px 0 4px; }
.profile-fields { display: flex; flex-direction: column; gap: 8px; padding: 6px 18px 0; }
.profile-fields input, .profile-fields textarea {
  width: 100%; font: inherit; color: #1c2430;
  border: 1px solid #dadce0; border-radius: 8px; padding: 6px 8px;
}
.profile-fields input { font-size: 15px; }
.profile-fields textarea { font-size: 13px; resize: vertical; }
.profile-fields .field-sub { font-size: 11.5px; color: #9aa0a6; margin-top: -4px; }
.profile-fields .field-err { font-size: 11.5px; color: #c62828; margin-top: -4px; }
.profile-fields .field-err[hidden] { display: none; }
.profile-email { font-size: 12px; color: #9aa0a6; }
.profile-card .sheet-actions { padding: 8px 16px 2px; }

/* --- Maintenance (maintenance_ui.js): sect headers like the settings
   panel's, rows like the rides panel's, small pill buttons like the
   Bin actions'. The mnt- family serves TWO surfaces: the draggable
   floating panel (.float-card below) and the ride-check .modal. --- */
.mnt-card { width: min(460px, 86vw); }
#maintenance-body { max-height: min(520px, calc(100dvh - 150px)); overflow-y: auto; padding-bottom: 4px; }
#ride-check-body { max-height: min(520px, 68vh); overflow-y: auto; padding-bottom: 4px; }
/* The Maintenance panel is a floating window over a LIVE map — no
   backdrop, the map stays pannable; finding rows fly the camera and
   paint evidence overlays. Starts top-right under the menu chip,
   drag-repositioned via inline left/top (maintenance_ui.js). z-35 so
   the z-40 .modals (confirm, ride check) paint on top of it. */
.float-card {
  position: fixed;
  top: 62px;
  right: 12px;
  z-index: 35;
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, .4);
  padding: 0 0 8px;
  max-width: calc(100vw - 24px);
}
.float-card[hidden] { display: none; }
.float-card-head {
  display: flex;
  align-items: center;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;   /* the header drags the card, never the page */
}
.float-card-head .modal-title { flex: 1; }
.float-card-x {
  flex: none;
  border: none;
  background: none;
  font: inherit;
  font-size: 14px;
  color: #5f6368;
  padding: 12px 16px 8px;
  cursor: pointer;
}
.float-card-x:hover { color: #1c2430; }
/* Evidence clicks: panel rows fly the map to the finding and paint
   its overlay; the currently-viewed row carries the accent stripe. */
.mnt-row.mnt-clickable { cursor: pointer; }
.mnt-row.mnt-clickable:hover { background: #f1f3f4; }
.mnt-row.viewing { background: #e8f0fe; box-shadow: inset 3px 0 0 #1a73e8; }
.mnt-sect {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px 4px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #9aa0a6;
}
.mnt-empty { padding: 14px 18px 10px; font-size: 14px; color: #5f6368; }
.mnt-group { border-top: 1px solid #f1f3f4; padding: 6px 0 8px; }
.mnt-row { display: flex; align-items: center; gap: 10px; padding: 6px 18px 0; }
.mnt-main { flex: 1; min-width: 0; }
.mnt-name {
  font-size: 13.5px;
  font-weight: 600;
  color: #1c2430;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mnt-sub { font-size: 12px; color: #9aa0a6; }
.mnt-tag {
  flex: none;
  font-size: 10.5px;
  font-weight: 700;
  color: #188038;
  background: #e6f4ea;
  border-radius: 8px;
  padding: 2px 7px;
}
.mnt-gap { padding: 2px 18px; font-size: 11.5px; color: #9aa0a6; }
.mnt-actions { display: flex; gap: 6px; margin: 8px 18px 0; }
.mnt-btn {
  flex: none;
  font: inherit;
  font-size: 12.5px;
  color: #1c2430;
  border: 1px solid #dadce0;
  background: #fff;
  border-radius: 8px;
  padding: 4px 10px;
  cursor: pointer;
}
.mnt-btn:hover { background: #f1f3f4; }
.mnt-btn.primary { background: #e53935; border-color: #e53935; color: #fff; }
.mnt-btn.primary:hover { background: #d32f2f; }
/* The Maintenance panel reuses .seg-tabs (rides panel) for its
   Duplicates/Split sessions/Spikes strip; "⚡ Fix all" sits in an
   .mnt-actions bar above the Spikes pane's list. The amber pill
   marks findings that need the user's judgment (green = recommended). */
.mnt-tag.warn { color: #b06000; background: #fef7e0; }

/* --- Admin users modal: rides-panel row/toolbar family --- */
.admin-card { width: min(440px, calc(100vw - 24px)); }
.admin-card .list-tools { margin: 4px 14px 8px; }
.admin-card .list-sort { max-width: 118px; }
#admin-list { max-height: min(480px, 62vh); overflow-y: auto; }
#admin-list .muted-row { padding: 10px 18px 12px; font-size: 13px; }
.admin-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  border-top: 1px solid #f1f3f4;
}
.admin-ava {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #f1f3f4;
  overflow: hidden;
  display: grid;
  place-items: center;
  color: #9aa0a6;
  font-size: 15px;
  font-weight: 700;
}
.admin-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.admin-main { flex: 1; min-width: 0; }
.admin-name {
  font-size: 13.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.admin-email, .admin-sub {
  font-size: 11.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.admin-email { color: #9aa0a6; }
.admin-sub { color: #5f6368; }
.admin-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: 4px;
  background: #fde3e2;
  color: #c62828;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .05em;
  vertical-align: 1px;
}
.admin-act {
  flex: none;
  border: 1px solid #dadce0;
  background: #fff;
  border-radius: 12px;
  font-size: 11.5px;
  padding: 3px 10px;
  cursor: pointer;
  color: #3c4043;
}
.admin-act:hover:not(:disabled) { background: #f1f3f4; }
.admin-act:disabled { opacity: .5; cursor: default; }
.admin-act.danger { color: #c62828; }

/* --- search overlay (app parity: rounded card, top of map) --- */
.top-panel {
  top: 10px;
  left: 64px;              /* clear of the brand chip */
  right: 64px;             /* clear of the menu button */
  max-width: 560px;
  margin: 0 auto;
}
.search-line {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
}
.search-line svg { width: 20px; height: 20px; fill: #9aa0a6; flex: none; }
#search-input {
  flex: 1;
  border: none;
  outline: none;
  font-size: 16px;         /* ≥16px prevents iOS zoom-on-focus */
  padding: 8px 0;
  background: none;
  color: #1c2430;
}
#search-close {
  border: none;
  background: none;
  font-size: 16px;
  color: #9aa0a6;
  cursor: pointer;
  padding: 6px;
}
.busy {
  height: 2px;
  background: linear-gradient(90deg, #e53935, #ffb4b0, #e53935);
  background-size: 200% 100%;
  animation: busy 1s linear infinite;
}
@keyframes busy { from { background-position: 0 0; } to { background-position: 200% 0; } }
#search-results .result { border-top: 1px solid #f1f3f4; }

/* --- ride media (V1.1-PLAN §5 M2/M3) --- */
/* Rides-list camera badge (app rides_screen trailing icon + count). */
.ride-cam {
  display: flex; align-items: center; gap: 3px; flex: none;
  color: #9aa0a6; font-size: 12px;
}
.ride-cam svg { width: 14px; height: 14px; fill: #9aa0a6; }
/* Rides-list tiles-crossed badge (hex outline + count), same muted
   style as the camera badge. */
.ride-hex {
  display: flex; align-items: center; gap: 3px; flex: none;
  color: #9aa0a6; font-size: 12px;
}
.ride-hex svg {
  width: 13px; height: 13px; fill: none;
  stroke: #9aa0a6; stroke-width: 2; stroke-linejoin: round;
}
/* Detail-sheet subtitle hex (rides: " · ⬡ N" on the time-range line). */
#sheet-sub .sub-tiles { white-space: nowrap; }
#sheet-sub .sub-tiles svg {
  width: 11px; height: 11px; fill: none;
  stroke: currentColor; stroke-width: 2; stroke-linejoin: round;
  display: inline-block; vertical-align: -1px;
}

/* Share viewer, degraded no-map mode: the clickable "Photos" row. */
.share-media-row { cursor: pointer; }
.share-media-row b { color: #c62828; }

/* Full-screen gallery (app media_gallery.dart, the "little slideshow"):
   dark stage over everything — site panels (z ≤ 40), Leaflet panes
   (z ≤ 1000) and the share card (z 1100/1200). */
#media-gallery {
  position: fixed; inset: 0; z-index: 2000;
  background: rgba(8, 10, 13, .97);
  display: flex; flex-direction: column;
  touch-action: pan-y;
  user-select: none;
}
#media-gallery[hidden] { display: none; }
.mg-top {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px; flex: none;
  color: #e8ecf1; font-size: 14px;
}
.mg-top .mg-caption { flex: 1; }
.mg-close {
  border: none; background: none; color: #e8ecf1;
  font-size: 18px; cursor: pointer; padding: 4px 8px;
}
/* Owner actions (editable galleries only — never on share pages):
   star (cover, fills on the current one), pencil, trash. */
.mg-actions { display: flex; align-items: center; gap: 2px; margin-right: 6px; }
.mg-actions[hidden] { display: none; }
.mg-act {
  border: none; background: none; cursor: pointer; padding: 5px 6px;
  color: #aeb8c4;
}
.mg-act svg { width: 19px; height: 19px; fill: currentColor; display: block; }
.mg-act:hover { color: #fff; }
.mg-act[hidden] { display: none; }
.mg-delete:hover { color: #ff8a80; }
.mg-cover svg.on { display: none; }
.mg-cover.is-cover { color: #ffd600; }
.mg-cover.is-cover svg.on { display: block; }
.mg-cover.is-cover svg.off { display: none; }
/* Inline title/caption editor — replaces the info bar while open, same
   bottom-scrim palette; Save is the site's primary red. */
.mg-editbar {
  flex: none; display: flex; flex-direction: column; align-items: center;
  gap: 8px; padding: 10px 18px 14px;
  background: linear-gradient(rgba(8, 10, 13, 0), rgba(8, 10, 13, .85));
}
.mg-editbar[hidden] { display: none; }
.mg-editbar input, .mg-editbar textarea {
  width: min(520px, 100%); font: inherit; font-size: 14px;
  color: #e8ecf1; background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .22); border-radius: 8px;
  padding: 8px 10px; resize: vertical;
}
.mg-editbar input::placeholder, .mg-editbar textarea::placeholder { color: #6b7683; }
.mg-edit-actions { display: flex; gap: 8px; }
.mg-edit-actions button {
  border: none; border-radius: 999px; padding: 7px 16px; font-size: 13px;
  cursor: pointer; background: rgba(255, 255, 255, .12); color: #e8ecf1;
}
.mg-edit-actions button:hover { background: rgba(255, 255, 255, .22); }
.mg-edit-actions .mg-edit-save, .mg-edit-actions .mg-edit-save:hover {
  background: #e53935; color: #fff;
}
.mg-stage { position: relative; flex: 1; min-height: 0; }
/* Per-page content (wiped on every page swap); the globe button below
   is a stage sibling so swaps can't destroy it. */
.mg-content {
  position: absolute; inset: 0;
  /* Flex, not grid: a grid's implicit auto row makes percentage
     max-heights on the child meaningless, so tall photos overflowed
     the viewport instead of shrinking (Jeroen, 2026-08-16). */
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.mg-stage img, .mg-stage video {
  max-width: 100%; max-height: 100%;
  width: auto; height: auto;
  object-fit: contain; flex: none;
}
/* Standard video control bar (2026-08-15) — a slim dark translucent
   strip pinned to the stage bottom (so it sits ABOVE the caption bar,
   a stage sibling below): play/pause · elapsed · seek track ·
   duration · speaker. Gallery-chrome palette; video pages only. */
.mg-bar {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; align-items: center; gap: 8px;
  padding: 5px 12px;
  background: rgba(8, 10, 13, .62);
  color: #e8ecf1;
}
.mg-bar[hidden] { display: none; }
.mg-pp {
  flex: none; width: 34px; height: 34px; border: none; border-radius: 50%;
  background: none; color: #e8ecf1; padding: 0;
  display: grid; place-items: center; cursor: pointer;
}
.mg-pp:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.mg-pp svg { width: 22px; height: 22px; fill: currentColor; }
.mg-pp svg.pause { display: none; }
.mg-bar.is-playing .mg-pp svg.pause { display: block; }
.mg-bar.is-playing .mg-pp svg.play { display: none; }
.mg-time {
  flex: none; font-size: 12.5px; color: #c7ceda;
  font-variant-numeric: tabular-nums;
}
/* Seek track: full-height hit area with a slim centered rail; drag
   anywhere on it scrubs (pointer capture in media_gallery.js —
   touch-action: none keeps touch drags ours, not the page's). */
.mg-track {
  position: relative; flex: 1; height: 24px; cursor: pointer;
  touch-action: none;
}
.mg-track::before {
  content: ''; position: absolute; left: 0; right: 0; top: 50%;
  height: 4px; transform: translateY(-50%);
  border-radius: 2px; background: rgba(255, 255, 255, .22);
}
.mg-track-fill {
  position: absolute; left: 0; top: 50%; width: 0; height: 4px;
  transform: translateY(-50%); border-radius: 2px; background: #e53935;
}
.mg-track-thumb {
  position: absolute; left: 0; top: 50%; width: 12px; height: 12px;
  transform: translate(-50%, -50%); border-radius: 50%; background: #fff;
}
/* Video sound toggle — the control bar's right end (was a floating
   bottom-left button until 2026-08-15). Muted speaker by default;
   .is-on swaps the glyph (the .mg-cover on/off pattern). */
.mg-sound {
  flex: none; width: 34px; height: 34px; border: none; border-radius: 50%;
  background: none; color: #e8ecf1; padding: 0;
  display: grid; place-items: center; cursor: pointer;
}
.mg-sound svg { width: 20px; height: 20px; fill: currentColor; }
.mg-sound:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.mg-sound svg.on { display: none; }
.mg-sound.is-on svg.on { display: block; }
.mg-sound.is-on svg.off { display: none; }
.mg-sound[hidden] { display: none; }
/* Globe-to-map jump (share pages pass onLocate; the main site never
   does, so it never renders there) — bottom-right over the media,
   just above the caption bar, clear of the ›-nav at mid-height. */
.mg-locate {
  position: absolute; right: 14px; bottom: 12px; z-index: 2;
  width: 38px; height: 38px; border: none; border-radius: 50%;
  background: rgba(255, 255, 255, .12); color: #e8ecf1;
  display: grid; place-items: center; cursor: pointer;
}
.mg-locate svg { width: 20px; height: 20px; fill: currentColor; }
.mg-locate:hover { background: rgba(255, 255, 255, .22); color: #fff; }
.mg-locate[hidden] { display: none; }
/* With the control bar up (video pages) the globe rises above it. */
.mg-bar:not([hidden]) ~ .mg-locate { bottom: 56px; }
.mg-missing {
  color: #6b7683; font-size: 14px; padding: 24px; text-align: center;
}
/* Undecodable video (HEVC uploads predating the app's H.264
   transcoding — no H.265 decoder in Chrome/Brave/Firefox). */
.mg-nodecode svg { width: 40px; height: 40px; fill: #6b7683; }
.mg-nodecode-sub { margin-top: 4px; font-size: 13px; color: #58616c; }
.mg-download {
  display: inline-block; margin-top: 16px; padding: 7px 16px;
  border-radius: 999px; background: rgba(255, 255, 255, .12);
  color: #e8ecf1; font-size: 13px; text-decoration: none;
}
.mg-download:hover { background: rgba(255, 255, 255, .22); }
.mg-wait {
  width: 28px; height: 28px; border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .25); border-top-color: #e8ecf1;
  animation: mg-spin 1s linear infinite;
}
@keyframes mg-spin { to { transform: rotate(360deg); } }
.mg-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; border: none; border-radius: 50%;
  background: rgba(255, 255, 255, .12); color: #e8ecf1;
  font-size: 24px; line-height: 1; cursor: pointer; z-index: 1;
}
.mg-nav:hover { background: rgba(255, 255, 255, .22); }
.mg-nav[hidden] { display: none; }
.mg-prev { left: 12px; }
.mg-next { right: 12px; }
/* Title (bold) + caption bar under the media (M2 media text) — only
   present when the item carries words; same palette as .mg-top. */
.mg-info {
  flex: none; padding: 10px 18px 14px; text-align: center;
  background: linear-gradient(rgba(8, 10, 13, 0), rgba(8, 10, 13, .85));
  color: #e8ecf1;
}
.mg-info[hidden] { display: none; }
.mg-title { font-weight: 700; font-size: 15px; }
.mg-title[hidden] { display: none; }
.mg-text { font-size: 13.5px; color: #c7ceda; margin-top: 2px; }
.mg-text[hidden] { display: none; }
/* Paused-frame play glyph (tap anywhere toggles, like the app). */
.mg-play {
  position: absolute; inset: 0; display: grid; place-items: center;
  cursor: pointer; color: rgba(255, 255, 255, .75); font-size: 64px;
}
.mg-play::before { content: '▶'; }
.mg-play[hidden] { display: none; }

/* --- notice (errors) --- */
#notice {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: grid;
  place-items: center;
  text-align: center;
  padding: 2rem;
  background: #10141a;
  font-size: 1.05rem;
  line-height: 1.6;
  color: #aeb8c4;
}
#notice code { color: #e8ecf1; }
/* An id selector beats the UA's [hidden] rule — restate it explicitly. */
#notice[hidden] { display: none; }
.panel[hidden], .chip-btn[hidden] { display: none; }

@media (max-width: 480px) {
  .top-panel { left: 10px; right: 10px; top: 60px; } /* below brand+menu on phones */
}
:root { color-scheme: light dark; }
