:root {
  --bg: #0a0e14;
  --bg-elev: #141b26;
  --bg-sheet: #161d29;
  --line: #263243;
  --text: #eef2f7;
  --text-dim: #8b98a9;
  --red: #DA291C;
  --orange: #ED8B00;
  --green: #00843D;
  --blue: #2f6bff; /* brightened from #003DA5 for dark-bg legibility */
  --commuter: #C264B0; /* commuter-rail purple, brightened for dark bg */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
  margin: 0; height: 100%; overflow: hidden;
  background: var(--bg); color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  overscroll-behavior: none;
}
body { display: flex; flex-direction: column; }

/* --- Top bar --- */
.topbar {
  position: relative; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  padding: calc(var(--safe-top) + 8px) 14px 8px;
  background: linear-gradient(180deg, rgba(10,14,20,.96), rgba(10,14,20,.82) 70%, transparent);
  backdrop-filter: blur(8px);
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark {
  width: 30px; height: 30px; border-radius: 50%;
  background: #fff; color: #0a0e14; font-weight: 800; font-size: 18px;
  display: grid; place-items: center; letter-spacing: -.5px;
  box-shadow: 0 2px 8px rgba(0,0,0,.4);
}
.brand-status { display: flex; flex-direction: column; line-height: 1.15; }
.status-text { font-size: 13px; font-weight: 600; color: var(--text); }
.brand-status { flex-direction: row; align-items: center; gap: 7px; }
.status-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--text-dim); flex: none; }
.status-live { background: #35d07f; box-shadow: 0 0 0 0 rgba(53,208,127,.6); animation: pulse 2.4s infinite; }
.status-loading { background: #f4c04f; }
.status-error { background: #f0554f; }
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(53,208,127,.5); }
  70% { box-shadow: 0 0 0 7px rgba(53,208,127,0); }
  100% { box-shadow: 0 0 0 0 rgba(53,208,127,0); }
}
.topbar-actions { display: flex; gap: 6px; }
.icon-btn {
  width: 38px; height: 38px; border-radius: 50%; border: none;
  background: var(--bg-elev); color: var(--text); display: grid; place-items: center;
  cursor: pointer; transition: background .15s;
}
.icon-btn:active { background: #1f2937; }

/* --- Map --- */
.map-container { position: relative; flex: 1; min-height: 0; touch-action: none; }
.map { width: 100%; height: 100%; display: block; }

.line-stroke { stroke-width: 7; stroke-linecap: round; stroke-linejoin: round; }
.line-dashed { stroke-width: 5; stroke-dasharray: 2 10; }
.line-commuter { stroke-width: 5; } /* commuter rail sits visually behind subway */

.station-hit { fill: transparent; }
.station-dot { fill: #0a0e14; stroke: #cfd8e3; stroke-width: 2.5; }
.station-transfer { fill: #fff; stroke: #0a0e14; stroke-width: 2.5; r: 7; }
.station-cr .station-dot { r: 3.5; stroke: var(--commuter); stroke-width: 2; }
.station.is-active .station-dot { fill: #fff; stroke: #35d07f; stroke-width: 3.5; }
.station { cursor: pointer; }

/* --- Layer toggle (subway / cr / both) ---
   Elements are tagged only-sub / only-cr; the active mode class on the <svg>
   hides whichever layer is off. mode-both shows everything. */
.map.mode-subway .only-cr { display: none; }
.map.mode-cr .only-sub { display: none; }

.label {
  fill: var(--text-dim); font-size: 11px; font-weight: 600;
  paint-order: stroke; stroke: #0a0e14; stroke-width: 3px; stroke-linejoin: round;
  pointer-events: none; font-family: inherit;
}
.label--major { fill: #d6deea; font-size: 12px; }
.label--minor { display: none; }
.map.is-zoomed .label--minor { display: block; }

/* --- Geographic underlay (OpenStreetMap, warped to the schematic) ---
   Deliberately near-threshold: enough to orient by water and green space,
   never enough to compete with the lines. Non-interactive so taps pass to
   stations and trains. */
.basemap { pointer-events: none; }
.bm-water { fill: #10233a; }
.bm-park { fill: #12291d; }
.bm-runway { fill: none; stroke: #1c2634; stroke-width: 2.5; stroke-linecap: round; }
.map.no-basemap .basemap, .map.no-basemap .landmarks { display: none; }
/* Drawn to the subway diagram's proportions. The commuter-rail layer is
   radially compressed onto the same canvas, which lands North Shore and South
   Shore stations out where open water belongs — so the underlay only shows in
   the view it was designed for. */
.map:not(.mode-subway) .basemap,
.map:not(.mode-subway) .landmarks { display: none; }

/* --- Landmarks (warped OSM footprints) --- */
.landmarks { pointer-events: none; }
.lm-shape { fill: #1c2432; }
.lm-stadium, .lm-museum, .lm-monument { fill: #26303f; }  /* the ones you steer by */
.lm-label {
  fill: #7d8899; font-size: 8.5px; font-weight: 600;
  paint-order: stroke; stroke: rgba(10,14,20,.85); stroke-width: 2.5;
  stroke-linejoin: round;
}
.lm-label--major { font-size: 9.5px; fill: #93a0b4; }
/* Minor landmarks would pile onto downtown at full-network zoom; they appear
   with the minor station labels instead. */
.lm-label--minor { display: none; }
.map.is-zoomed .lm-label--minor { display: block; }
/* Culled by the collision pass — visibility, not display, so it can still be
   measured on the next pass. */
.lm-collide { visibility: hidden; }

/* --- Trains (forward-pointing triangles) --- */
.train { cursor: pointer; }
.train-halo { fill: rgba(10,14,20,.6); }
.train-body { stroke: #fff; stroke-width: 1.5; stroke-linejoin: round; }
/* Two honest state signals, so every icon reads at a glance without faking
   position: stopped trains pulse a glow in their line's colour; moving trains
   stream a flowing dashed wake behind them (real inter-station motion is only
   ~1 SVG unit/s — truthful, but too slow for the eye to call "moving"). */
.train-glow { opacity: 0; }
.train.is-dwelling .train-glow { animation: dwell-glow 2.4s ease-in-out infinite; }
@keyframes dwell-glow { 0%, 100% { opacity: .25; } 50% { opacity: .9; } }
.train-wake {
  fill: none; stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 3 5; opacity: 0; transition: opacity .4s;
}
.train.is-moving .train-wake { opacity: .55; animation: wake-flow 1.1s linear infinite; }
/* one full dash period (3+5) per cycle => seamless loop, streaming backward */
@keyframes wake-flow { to { stroke-dashoffset: -8; } }
@media (prefers-reduced-motion: reduce) {
  .train.is-dwelling .train-glow { animation: none; opacity: .5; }
  .train.is-moving .train-wake { animation: none; opacity: .3; }
}
.train.is-active .train-body { stroke: #35d07f; stroke-width: 2.4; }
.train.is-active .train-halo { fill: rgba(53,208,127,.3); }

/* --- Layer toggle (segmented pill under the top bar) --- */
.layer-toggle {
  position: absolute; top: calc(var(--safe-top) + 52px); left: 50%;
  transform: translateX(-50%); z-index: 16;
  display: flex; gap: 2px; padding: 3px;
  background: rgba(20,27,38,.92); backdrop-filter: blur(8px);
  border: 1px solid var(--line); border-radius: 999px;
  box-shadow: 0 3px 12px rgba(0,0,0,.45);
}
.lt-btn {
  border: none; background: transparent; color: var(--text-dim);
  font-family: inherit; font-size: 12.5px; font-weight: 700;
  padding: 6px 15px; border-radius: 999px; cursor: pointer;
  transition: background .15s, color .15s;
}
.lt-btn.is-active { background: var(--text); color: var(--bg); }

/* --- Floating controls --- */
.fab {
  position: absolute; right: 14px; bottom: calc(var(--safe-bottom) + 74px);
  width: 46px; height: 46px; border-radius: 50%; border: none;
  background: var(--bg-elev); color: var(--text);
  display: grid; place-items: center; cursor: pointer; z-index: 15;
  box-shadow: 0 4px 14px rgba(0,0,0,.45);
}
.fab:active { background: #1f2937; }

.legend {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 15;
  display: flex; gap: 14px; justify-content: center; flex-wrap: wrap;
  padding: 10px 14px calc(var(--safe-bottom) + 10px);
  background: linear-gradient(0deg, rgba(10,14,20,.95), transparent);
  font-size: 12px; color: var(--text-dim); pointer-events: none;
}
.legend-item { display: flex; align-items: center; gap: 5px; font-weight: 600; }
.legend-item i { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }

/* OSM attribution — required by the ODbL wherever that geometry renders. Sits
   above the legend gradient, out of the way but always legible. */
/* Quiet note that the geography is stylised, so nobody reads the underlay as
   survey data. Hidden whenever the underlay itself is. */
.geo-note {
  position: absolute; left: 10px; z-index: 16;
  bottom: calc(var(--safe-bottom) + 34px);
  font-size: 10px; color: var(--text-dim); opacity: .7;
}
.geo-note a { color: inherit; }
.map-container.no-basemap ~ .geo-note { display: none; }

/* --- Bottom sheet --- */
.sheet {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 30;
  background: var(--bg-sheet);
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -8px 30px rgba(0,0,0,.5);
  padding: 8px 18px calc(var(--safe-bottom) + 22px);
  transform: translateY(110%); transition: transform .28s cubic-bezier(.2,.8,.2,1);
  max-height: 62%; overflow-y: auto;
}
.sheet.open { transform: translateY(0); }
.sheet-grip { width: 38px; height: 4px; border-radius: 2px; background: #3a4657; margin: 4px auto 12px; }
.sheet-close {
  position: absolute; right: 12px; top: 12px; z-index: 2;
  width: 30px; height: 30px; border-radius: 50%; border: none;
  background: #232c3a; color: var(--text-dim); font-size: 14px; cursor: pointer;
}
.sheet-head { display: flex; gap: 12px; align-items: center; margin-bottom: 14px; padding-right: 34px; }
.sheet-head h2 { margin: 0; font-size: 20px; font-weight: 700; }
.sheet-sub { margin: 2px 0 0; font-size: 13px; color: var(--text-dim); }

.pred-list { display: flex; flex-direction: column; gap: 2px; }
.pred-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 4px; border-top: 1px solid var(--line);
}
.pred-row:first-child { border-top: none; }
.pred-badge {
  flex: none; min-width: 26px; height: 26px; padding: 0 7px; border-radius: 7px;
  font-weight: 800; font-size: 14px; display: grid; place-items: center;
}
.pred-dest { flex: 1; font-weight: 600; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pred-times { color: var(--text-dim); font-size: 14px; display: flex; align-items: baseline; gap: 4px; }
.pred-times b { color: var(--text); font-size: 17px; font-weight: 700; }
.pred-times .dot { opacity: .5; margin: 0 2px; }
.loading-row { padding: 20px 4px; color: var(--text-dim); text-align: center; }

/* Disambiguation list, shown when several trains/stations share a fingertip. */
.pick-list { display: flex; flex-direction: column; gap: 2px; padding-bottom: 4px; }
.pick-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 10px 8px; border: none; border-radius: 12px;
  background: transparent; color: var(--text); font: inherit; text-align: left;
}
.pick-row:active { background: var(--bg-elev); }
.pick-badge {
  flex: none; min-width: 32px; height: 27px; border-radius: 8px;
  display: grid; place-items: center; color: #fff;
  font-size: 13px; font-weight: 800;
}
.pick-badge--station { background: var(--bg-elev); color: var(--text-dim); font-size: 11px; }
.pick-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pick-main b { font-size: 15px; font-weight: 700; }
.pick-main i {
  font-style: normal; font-size: 12px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.train-meta { display: flex; gap: 24px; padding: 4px; }
.train-meta > div { display: flex; flex-direction: column; }
.train-meta span { font-size: 12px; color: var(--text-dim); }
.train-meta b { font-size: 17px; font-weight: 700; margin-top: 2px; }

.field { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 12px; }
.field span { font-size: 13px; color: var(--text-dim); font-weight: 600; }
.field-row { flex-direction: row; align-items: center; justify-content: space-between; }
.field-row input[type="checkbox"] { width: 22px; height: 22px; accent-color: #35d07f; }
.field input {
  background: #0d131c; border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 14px; color: var(--text); font-size: 15px; font-family: inherit;
}
.hint { font-size: 12.5px; color: var(--text-dim); line-height: 1.5; margin: 0 0 16px; }
.btn-primary {
  width: 100%; padding: 13px; border: none; border-radius: 12px;
  background: #35d07f; color: #06231a; font-size: 15px; font-weight: 700; cursor: pointer;
}
