/* Dark is the default. An explicit choice wins via [data-theme]; with no
   choice the system preference decides. Every colour that JS derives (line and
   destination swatches) is recomputed against --board when the theme flips. */
:root{
  --board:#0f1216; --panel:#161b21; --edge:#252c34;
  --ink:#eef2f5; --dim:#8b96a0; --amber:#ffb200;
  --scrim:rgba(0,0,0,.5); --hover:rgba(255,255,255,.05);
  --shadow:rgba(0,0,0,.5); --hairline:rgba(255,255,255,.055);
  /* set from JS per line, always contrast-checked against --board */
  --line:#4d8fe0; --line-deep:#2f6fbe; --line-ink:#0f1216;
}
:root[data-theme="light"]{
  --board:#f5f7fa; --panel:#ffffff; --edge:#d3dae1;
  --ink:#15191d; --dim:#59646e; --amber:#9a6600;
  --scrim:rgba(20,26,32,.42); --hover:rgba(0,0,0,.045);
  --shadow:rgba(15,25,35,.16); --hairline:rgba(0,0,0,.07);
}
@media (prefers-color-scheme:light){
  :root:not([data-theme="dark"]){
    --board:#f5f7fa; --panel:#ffffff; --edge:#d3dae1;
    --ink:#15191d; --dim:#59646e; --amber:#9a6600;
    --scrim:rgba(20,26,32,.42); --hover:rgba(0,0,0,.045);
    --shadow:rgba(15,25,35,.16); --hairline:rgba(0,0,0,.07);
  }
}
*{box-sizing:border-box}
html,body{margin:0;background:var(--board);color:var(--ink);
  font-family:"Helvetica Neue",Helvetica,Arial,system-ui,sans-serif;-webkit-font-smoothing:antialiased}

/* ---- header ---- */
header{display:flex;align-items:center;gap:14px;padding:16px clamp(14px,4vw,28px) 10px;flex-wrap:wrap}
.title{min-width:0}
h1{font-size:clamp(17px,4vw,24px);margin:0;font-weight:700;letter-spacing:.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sub{color:var(--dim);font-size:13px;margin-top:2px;display:flex;align-items:center;gap:7px}
.live{width:8px;height:8px;border-radius:50%;background:var(--amber);flex:0 0 auto;
  animation:pulse 2.4s ease-out infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(255,178,0,.5)}70%{box-shadow:0 0 0 7px rgba(255,178,0,0)}100%{box-shadow:0 0 0 0 rgba(255,178,0,0)}}
@media (prefers-reduced-motion:reduce){
  .live{animation:none}
  .cd i,.train .lbl{transition:none}
  *{scroll-behavior:auto}
}

.controls{margin-left:auto;display:flex;gap:14px;align-items:flex-end;flex-wrap:wrap}
.ctl{display:flex;flex-direction:column;gap:4px}
.ctl-label{color:var(--dim);font-size:11px;text-transform:uppercase;letter-spacing:.06em}
select{background:var(--panel);color:var(--ink);border:1px solid var(--edge);border-radius:7px;
  padding:7px 10px;font-size:13px;min-width:170px;font-family:inherit}
select:focus-visible,button:focus-visible,input:focus-visible{outline:2px solid var(--line);outline-offset:2px}
.zoom-row{display:flex;align-items:center;gap:6px}
.zoom-row button{width:26px;height:26px;border-radius:6px;border:1px solid var(--edge);
  background:var(--panel);color:var(--ink);font-size:15px;line-height:1;cursor:pointer;flex:0 0 auto}
.zoom-row button:hover{border-color:var(--line)}
.theme-btn{display:flex;align-items:center;gap:6px;height:32px;padding:0 11px;
  border:1px solid var(--edge);border-radius:7px;background:var(--panel);
  color:var(--ink);font-size:13px;font-family:inherit;cursor:pointer}
.theme-btn:hover{border-color:var(--line)}
.theme-icon{font-size:14px;line-height:1}
input[type=range]{width:104px;accent-color:var(--line)}

/* ---- refresh bar ---- */
.bar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:0 clamp(14px,4vw,28px) 12px;color:var(--dim);font-size:12px}
.refresh{display:flex;align-items:center;gap:8px}
.refresh b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.dot{opacity:.5}
.cd{display:inline-block;width:54px;height:4px;border-radius:2px;background:var(--edge);overflow:hidden}
.cd i{display:block;height:100%;width:100%;background:var(--line);
  transform-origin:left center;transition:transform .25s linear}
.hint{margin-left:auto;opacity:.75}

/* ---- layout ---- */
main{padding:0 clamp(14px,4vw,28px) 40px;position:relative}
.track{position:relative;margin:0 auto;max-width:760px;
  /* one finger still scrolls the page; two fingers are ours to pinch */
  touch-action:pan-y}
.skip{position:absolute;left:-9999px;top:0;background:var(--panel);color:var(--ink);
  padding:10px 14px;border:1px solid var(--edge);border-radius:8px;z-index:20}
.skip:focus{left:12px;top:12px}

/* ---- rails ---- */
.rail{position:absolute;width:4px;margin-left:-2px;
  background:linear-gradient(var(--line-deep),var(--line));border-radius:2px}
.forks{position:absolute;left:0;top:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.forks line{stroke:var(--line);stroke-width:4;stroke-linecap:round}

/* ---- stations ---- */
.station{position:absolute;transform:translate(-50%,-50%);display:flex;
  align-items:center;gap:9px;white-space:nowrap;cursor:pointer;
  padding:4px;border-radius:8px;border:0;background:transparent;
  font-family:inherit;color:inherit;line-height:1}
.station:hover{background:var(--hover)}
/* the station mark now bridges the two directional tracks */
.station .tick{height:5px;border-radius:3px;background:var(--line);flex:0 0 auto}
/* offsets are set inline from the track gap; 50% is the station mark's centre,
   so the label clears a train marker sitting on the outer rail */
.station .nm{position:absolute;color:var(--dim);font-size:12px;transform:translateY(-1px);
  overflow:hidden;text-overflow:ellipsis}
.station.left .nm{text-align:right;direction:rtl}
.station:hover .nm{color:var(--ink)}
.station.active .tick{box-shadow:0 0 0 3px var(--ink)}
.station.active .nm{color:var(--ink);font-weight:600}

/* repeating direction reminders down the trunk — deliberately faint so they
   read as a watermark, not as map furniture */
.edge-note{position:absolute;transform:translateY(-50%);white-space:nowrap;
  font-size:9px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--dim);opacity:.45;pointer-events:none;user-select:none}
.edge-note.l{transform:translate(-100%,-50%)}

/* which side of the rail is which direction of travel */
.key .tracks{display:flex;justify-content:space-between;gap:10px;margin:7px 0 0;
  padding-top:7px;border-top:1px solid var(--edge);color:var(--dim);font-size:10px}

/* ---- trains: one rectangle, sitting on the rail, numbered ---- */
.train{position:absolute;left:50%;will-change:transform;z-index:3;
  display:flex;align-items:center;justify-content:center;
  min-width:30px;height:15px;padding:0 4px;border-radius:3px;
  font-size:9.5px;font-weight:700;letter-spacing:.02em;
  color:var(--line-ink);background:var(--line);
  box-shadow:0 1px 3px var(--shadow);cursor:pointer}
.train .num{pointer-events:none}
.train::after{content:"";position:absolute;top:1px;bottom:1px;width:2px;border-radius:1px;
  background:currentColor;opacity:.35}
.train.down::after{right:2px}
.train.up::after{left:2px}
.train .lbl{position:absolute;left:calc(100% + 8px);top:50%;transform:translateY(-50%);
  font-size:10px;line-height:1.35;color:var(--ink);background:var(--panel);
  border:1px solid var(--edge);padding:4px 7px;border-radius:6px;
  opacity:0;transition:opacity .12s;white-space:nowrap;pointer-events:none;z-index:5;
  box-shadow:0 3px 12px var(--shadow)}
.train .lbl b{font-variant-numeric:tabular-nums;letter-spacing:.02em}
.train .lbl i{font-style:normal;color:var(--dim)}
/* trains on the left-hand rail open their detail leftwards */
.train.up .lbl{left:auto;right:calc(100% + 8px)}
.train:hover,.train.pinned{z-index:7}
.train:hover .lbl,.train.pinned .lbl{opacity:1}
.train.pinned{outline:2px solid var(--ink);outline-offset:1px}
.train{border:0;font-family:inherit}
.train{cursor:pointer}

/* ---- destination key ---- */
.key{position:sticky;top:10px;float:right;margin:0 0 12px 12px;
  background:var(--panel);border:1px solid var(--edge);border-radius:9px;
  padding:9px 11px;font-size:11px;max-width:200px;z-index:4}
.key h3{margin:0 0 6px;font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--dim);font-weight:600}
.key ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.key li{display:flex;align-items:center;gap:7px;color:var(--ink)}
.key .sw{width:14px;height:9px;border-radius:2px;flex:0 0 auto}
.key .ct{margin-left:auto;color:var(--dim);font-variant-numeric:tabular-nums}

/* ---- station detail panel ---- */
.scrim{position:fixed;inset:0;background:var(--scrim);z-index:9}
.panel{position:fixed;top:0;right:0;bottom:0;width:min(380px,92vw);z-index:10;
  background:var(--panel);border-left:1px solid var(--edge);
  display:flex;flex-direction:column;box-shadow:-8px 0 28px var(--shadow)}
/* the class sets display:flex, which outranks the UA [hidden] rule — without
   this the panel is permanently on screen, covering the map */
.panel[hidden],.scrim[hidden]{display:none}
.panel-head{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--edge)}
.panel-head h2{margin:0;font-size:15px;font-weight:700;flex:1;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#panel-close{width:30px;height:30px;border-radius:7px;border:1px solid var(--edge);
  background:transparent;color:var(--ink);font-size:17px;line-height:1;cursor:pointer;flex:0 0 auto}
#panel-close:hover{border-color:var(--line)}
.panel-body{overflow:auto;padding:12px 16px 20px}
.pf{margin:0 0 14px}
.pf-head{display:flex;align-items:baseline;gap:8px;margin-bottom:6px}
.pf-num{font-size:12px;font-weight:700;color:var(--line-ink);background:var(--line);
  border-radius:4px;padding:1px 7px}
.pf-dir{font-size:11px;color:var(--dim)}
.pf table{width:100%;border-collapse:collapse;font-size:12px}
.pf td{padding:4px 0;border-bottom:1px solid var(--hairline);vertical-align:middle}
.pf td.d{color:var(--ink)}
.pf td.v{color:var(--dim);width:44px;font-variant-numeric:tabular-nums}
.pf td.t{text-align:right;color:var(--ink);font-weight:600;width:56px;font-variant-numeric:tabular-nums}
.pf tr:last-child td{border-bottom:0}
.pf .swatch{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:6px}
.empty{color:var(--dim);font-size:12px}

footer{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;
  color:var(--dim);font-size:12px;padding:0 clamp(14px,4vw,28px) 28px}
.err{color:var(--amber)}

/* ---- phones ---- */
@media (max-width:560px){
  html,body{overflow-x:hidden}
  header{gap:10px;padding-bottom:8px}
  .controls{margin-left:0;width:100%;gap:10px}
  select{min-width:0;flex:1}
  .ctl:first-child{flex:1}
  .hint{display:none}
  .station .nm{font-size:10px;max-width:86px;overflow:hidden;text-overflow:ellipsis}
  .key{position:static;float:none;max-width:none;margin:0 0 14px;
    display:flex;align-items:flex-start;gap:10px}
  .key ul{flex-direction:row;flex-wrap:wrap;gap:6px 12px}
  .key .ct{margin-left:4px}
  .panel{top:auto;left:0;right:0;bottom:0;width:auto;height:72vh;
    border-left:0;border-top:1px solid var(--edge);border-radius:14px 14px 0 0}
  .train{min-width:26px;height:14px;font-size:9px}
}
