/* Great Trains — map + marking UI. Builds on the great-apps framework.css. */

:root {
  --visited: #35c46e;
  --visited-glow: rgba(53, 196, 110, 0.35);
  --station: #f2f4ff;
  --station-ring: #0b0c12;
  --water: #0a0f1c;
  --land: #171821;
  --land-edge: #262735;
}

/* ── Land / water background ────────────── */
.land {
  fill: var(--land);
  stroke: var(--land-edge);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  stroke-linejoin: round;
  fill-rule: evenodd;
}

/* ── Header ─────────────────────────────── */
.header-actions {
  display: flex;
  gap: 8px;
}

.progress-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}

.progress {
  flex: 1;
  height: 7px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 5px;
  overflow: hidden;
}

.progress > i {
  display: block;
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--visited), #6fe6a0);
  transition: width 0.35s ease;
}

.progress-text {
  font-size: 0.8rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.progress-text b {
  color: var(--visited);
  font-weight: 700;
}

/* ── Search results ────────────────────── */
.search-wrap {
  position: relative;
  margin-top: 10px;
}

.search-wrap[hidden] { display: none; }

.search-results {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  max-height: 46vh;
  overflow-y: auto;
  z-index: 30;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5);
}

.search-results:empty { display: none; }

.result-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  cursor: pointer;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.result-row:last-child { border-bottom: none; }
.result-row:hover, .result-row.active { background: var(--bg-hover); }

.result-info { flex: 1; min-width: 0; }
.result-name {
  font-size: 0.92rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.result-sub { font-size: 0.74rem; color: var(--text-muted); }

.result-check {
  flex-shrink: 0;
  color: var(--visited);
  opacity: 0;
}
.result-row.is-visited .result-check { opacity: 1; }

/* ── Map ───────────────────────────────── */
.map-wrap {
  flex: 1;
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(1400px 1000px at 55% 28%, #0e1526 0%, var(--water) 72%);
  background-color: var(--water);
}

svg#map {
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  cursor: grab;
  user-select: none;
}
svg#map.grabbing { cursor: grabbing; }

/* Promote #scene to its own GPU layer ONLY during an active pan/pinch. A
   persistent promotion makes iOS back the entire scaled scene with a single
   composited layer whose size grows with zoom; past WebKit's max layer size it
   stops re-rasterizing and freezes on a stale image. See app.js promoteScene(). */
#scene.panning { will-change: transform; }

.route-line {
  fill: none;
  stroke-linejoin: round;
  stroke-linecap: round;
  stroke-width: 4;
  opacity: 1;
}

/* Station markers: a white capsule/pill (rounded rect) with a thin dark edge,
   matching the official diagram's white transfer dots. A single-line stop is a
   small circle (a square with full corner radius); a transfer complex stretches
   the capsule across the parallel lines it serves. */
.station {
  fill: var(--station);
  stroke: var(--station-ring);
  stroke-width: 1;
}
.station.visited {
  fill: var(--visited);
  stroke: #04220f;
  filter: drop-shadow(0 0 3px var(--visited-glow));
}
.station.selected {
  stroke: var(--accent);
  stroke-width: 2.4;
}
/* Connector between a transfer complex's separate line clusters. */
.st-connector {
  stroke: var(--station);
  fill: none;
  stroke-linecap: round;
  opacity: 0.9;
}
.st-connector.visited { stroke: var(--visited); }

.station-label {
  fill: var(--text);
  font-size: 10px;
  font-weight: 600;
  paint-order: stroke;
  stroke: var(--water);
  stroke-width: 3px;
  stroke-linejoin: round;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
}
#scene.show-labels .station-label { opacity: 0.95; }
#scene.show-labels .station-label.hide { opacity: 0; }
.station-label.always { opacity: 0.95; }

/* Zoom controls */
.map-controls {
  position: absolute;
  right: 12px;
  bottom: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 20;
}
.map-controls button {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: rgba(26, 26, 36, 0.9);
  color: var(--text);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(6px);
  -webkit-tap-highlight-color: transparent;
}
.map-controls button:active { background: var(--bg-active); }
.map-controls .locate svg { width: 20px; height: 20px; }

/* ── Route bullets ─────────────────────── */
.bullet {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-weight: 800;
  font-size: 0.82rem;
  flex-shrink: 0;
  font-family: 'Helvetica Neue', Arial, sans-serif;
}
.bullet.sm { width: 19px; height: 19px; font-size: 0.7rem; }
.bullet-row { display: flex; flex-wrap: wrap; gap: 5px; }

/* ── Bottom sheet ──────────────────────── */
.sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  background: var(--bg-surface);
  border-top: 1px solid var(--border);
  border-radius: 18px 18px 0 0;
  padding: 16px 18px calc(16px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -12px 40px rgba(0, 0, 0, 0.55);
  transform: translateY(110%);
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.sheet.open { transform: translateY(0); }

/* The station action sheet: when collapsed it must be fully hidden (its upward
   box-shadow was bleeding onto the map) and must not intercept touches meant for
   the map. Gate both on .open. (The stats sheet lives inside .overlay and is
   scoped separately below, so these #sheet rules don't affect it.) */
#sheet {
  box-shadow: none;
  pointer-events: none;
  visibility: hidden;
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear 0.28s;
}
#sheet.open {
  box-shadow: 0 -12px 40px rgba(0, 0, 0, 0.55);
  pointer-events: auto;
  visibility: visible;
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s;
}

.sheet-grip {
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  margin: -6px auto 12px;
}

.sheet-title {
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.25;
  margin-bottom: 6px;
}
.sheet-meta {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin-bottom: 12px;
}
.sheet-meta .ada { color: var(--visited); font-weight: 600; }

.sheet .bullet-row { margin-bottom: 16px; }

.visit-btn {
  width: 100%;
  padding: 14px;
  border-radius: 12px;
  border: 1px solid var(--visited);
  background: transparent;
  color: var(--visited);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  -webkit-tap-highlight-color: transparent;
}
.visit-btn.on {
  background: var(--visited);
  color: #04220f;
  border-color: var(--visited);
}

.sheet-close {
  position: absolute;
  top: 12px;
  right: 14px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text-muted);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
}

/* ── Stats overlay ─────────────────────── */
.overlay {
  position: absolute;
  inset: 0;
  z-index: 50;
  background: rgba(8, 8, 12, 0.72);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.overlay[hidden] { display: none; }
.sheet.stats-sheet {
  position: relative;
  max-width: 520px;
  width: 100%;
  transform: none;
  max-height: 82vh;
  overflow-y: auto;
}

.stat-group { margin-bottom: 18px; }
.stat-group h3 {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.stat-line {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.stat-line .label { width: 116px; font-size: 0.86rem; flex-shrink: 0; }
.stat-line .bar {
  flex: 1;
  height: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
}
.stat-line .bar > i {
  display: block;
  height: 100%;
  background: var(--visited);
}
.stat-line .num {
  font-size: 0.78rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  width: 58px;
  text-align: right;
}

.danger-btn {
  width: 100%;
  padding: 12px;
  border-radius: 10px;
  border: 1px solid #55344a;
  background: transparent;
  color: #ff7a9c;
  font-weight: 600;
  cursor: pointer;
  margin-top: 4px;
}

.map-hint { color: var(--text-muted); }

/* Enlarge the version-label tap target. It doubles as the hidden trigger for the
   diagnostics panel (triple-tap), and the bare text was too small to hit reliably
   on a phone. Padding grows the hitbox to a 44px touch target; matching negative
   margins keep the text visually in place so only the tappable area grows. */
#version-label {
  cursor: pointer;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  min-height: 44px;
  min-width: 88px;
  padding: 12px 10px 12px 30px;
  margin: -12px -10px -12px -30px;
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(122, 162, 255, 0.3);
}

@media (max-width: 768px) {
  .station-label { font-size: 11px; }
}
