:root {
  --bg: #f4f5f7;
  --surface: #ffffff;
  --surface-2: #f0f2f5;
  --border: #e1e4e9;
  --text: #16191f;
  --muted: #5d6573;
  --faint: #8d95a3;
  --accent: #d0021b;
  --accent-soft: #fde8ea;
  --ok: #138a4a;
  --warn: #b7791f;
  --bad: #c62828;
  --early: #2563eb;
  --shadow: 0 2px 10px rgba(20, 25, 35, .12), 0 1px 3px rgba(20, 25, 35, .08);
  --radius: 14px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0f1115; --surface: #191c22; --surface-2: #22262e; --border: #2e333d;
    --text: #eceef2; --muted: #a3abb8; --faint: #6f7785; --accent: #ff4d5e; --accent-soft: #3a1c21;
    --ok: #3ccf7e; --warn: #f0b429; --bad: #ff6b6b; --early: #6ea8ff;
    --shadow: 0 2px 12px rgba(0, 0, 0, .5), 0 1px 3px rgba(0, 0, 0, .4);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #0f1115; --surface: #191c22; --surface-2: #22262e; --border: #2e333d;
  --text: #eceef2; --muted: #a3abb8; --faint: #6f7785; --accent: #ff4d5e; --accent-soft: #3a1c21;
  --ok: #3ccf7e; --warn: #f0b429; --bad: #ff6b6b; --early: #6ea8ff;
  --shadow: 0 2px 12px rgba(0, 0, 0, .5), 0 1px 3px rgba(0, 0, 0, .4);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body { background: var(--bg); color: var(--text); font: 15px/1.4 var(--font); -webkit-tap-highlight-color: transparent; }
button { font: inherit; color: inherit; }
a { color: inherit; }

/* ---------- line badges, delays ---------- */
.badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2em; height: 1.6em; padding: 0 .4em; border-radius: .45em;
  background: var(--c); color: #fff; font-weight: 700; font-size: .9em; line-height: 1;
  font-variant-numeric: tabular-nums; flex-shrink: 0;
}
.badge.bus { border-radius: 99px; }
.badge.lg { font-size: 1.2em; }
.delay { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.d-ok { color: var(--ok); } .d-warn { color: var(--warn); } .d-bad { color: var(--bad); } .d-early { color: var(--early); } .d-none { color: var(--faint); }
.chip { display: inline-flex; align-items: center; gap: .35em; padding: .2em .6em; border-radius: 99px; background: var(--surface-2); font-size: .85em; color: var(--muted); }
.chip.d-ok { background: color-mix(in srgb, var(--ok) 14%, transparent); }
.chip.d-warn { background: color-mix(in srgb, var(--warn) 16%, transparent); }
.chip.d-bad { background: color-mix(in srgb, var(--bad) 14%, transparent); }
.chip.d-early { background: color-mix(in srgb, var(--early) 14%, transparent); }
.muted { color: var(--muted); } .faint { color: var(--faint); }
.icon { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- map page layout ---------- */
#map { position: fixed; inset: 0; background: var(--bg); }
.leaflet-container { font: inherit; background: var(--bg); }
.topbar {
  position: fixed; z-index: 1000; top: 12px; left: 12px; right: 12px;
  display: flex; gap: 8px; align-items: flex-start; pointer-events: none;
}
.topbar > * { pointer-events: auto; }
.search {
  flex: 1; max-width: 400px; position: relative;
  background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow);
}
.search-row { display: flex; align-items: center; gap: 8px; padding: 0 12px; height: 46px; }
.logo { font-weight: 800; letter-spacing: -.02em; white-space: nowrap; display: flex; align-items: center; gap: 6px; }
.logo .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.search input {
  flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--text);
  font: inherit; font-size: 16px; height: 100%;
}
.search input::placeholder { color: var(--faint); }
.results { border-top: 1px solid var(--border); max-height: 50vh; overflow: auto; }
.results:empty { display: none; }
.result { display: flex; align-items: center; gap: 10px; padding: 10px 12px; cursor: pointer; }
.result:hover, .result.active { background: var(--surface-2); }
.result .lines { display: flex; gap: 3px; flex-wrap: wrap; margin-left: auto; justify-content: flex-end; }
.result .lines .badge { font-size: .7em; }
.tools { display: flex; gap: 8px; margin-left: auto; }
.btn {
  width: 46px; height: 46px; display: grid; place-items: center; border: 0; cursor: pointer;
  background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); color: var(--text);
  text-decoration: none;
}
.btn:hover { background: var(--surface-2); }
.btn.on { color: var(--accent); }

.status {
  position: fixed; z-index: 900; left: 12px; bottom: 24px;
  background: var(--surface); box-shadow: var(--shadow); border-radius: 99px; padding: 6px 12px;
  font-size: .82em; color: var(--muted); display: flex; align-items: center; gap: 8px; cursor: pointer;
}
.status .pulse { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 0 var(--ok); animation: pulse 2s infinite; }
.status.schedule .pulse { background: var(--warn); animation: none; }
.status.error .pulse { background: var(--bad); animation: none; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 60%, transparent); } 70% { box-shadow: 0 0 0 8px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }

.leaflet-control-zoom { border: 0 !important; box-shadow: var(--shadow) !important; border-radius: 12px !important; overflow: hidden; }
.leaflet-control-zoom a { background: var(--surface) !important; color: var(--text) !important; border-color: var(--border) !important; width: 40px !important; height: 40px !important; line-height: 40px !important; }
.leaflet-control-attribution { background: color-mix(in srgb, var(--surface) 80%, transparent) !important; color: var(--muted) !important; font-size: 10px; }
.leaflet-control-attribution a { color: var(--muted) !important; }
.leaflet-bottom.leaflet-right .leaflet-control-zoom { margin-bottom: 24px; }

/* ---------- vehicle markers ---------- */
.leaflet-marker-icon.veh { position: absolute; }
.veh .vw { position: absolute; inset: 0; }
.veh .body {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  min-width: 26px; height: 26px; padding: 0 5px; border-radius: 8px;
  background: var(--c); color: #fff; font-weight: 800; font-size: 12px; line-height: 26px; text-align: center;
  border: 2px solid var(--surface); box-shadow: 0 1px 4px rgba(0,0,0,.35); white-space: nowrap;
}
.veh.bus .body { border-radius: 99px; }
.veh .arrow {
  position: absolute; left: 50%; top: 50%; width: 0; height: 0;
  transform-origin: 0 0;
}
.veh .arrow::before {
  content: ""; position: absolute; left: -6px; top: -25px;
  border: 6px solid transparent; border-bottom: 9px solid var(--c); border-top: 0;
}
.veh .ring { position: absolute; left: 50%; top: 50%; width: 11px; height: 11px; margin: -17px 0 0 var(--rx, 8px); border-radius: 50%; border: 2px solid var(--surface); }
.veh .ring.d-ok { background: var(--ok); } .veh .ring.d-warn { background: var(--warn); } .veh .ring.d-bad { background: var(--bad); } .veh .ring.d-early { background: var(--early); } .veh .ring.d-none { display: none; }
.veh.sched .body { border-style: dashed; }
.veh.small .body { min-width: 12px; width: 12px; height: 12px; padding: 0; font-size: 0; border-width: 1.5px; border-radius: 3px; }
.veh.small.bus .body { border-radius: 50%; }
.veh.small .arrow, .veh.small .ring { display: none; }
.veh.dim { opacity: .25; }
.veh.sel .body { box-shadow: 0 0 0 3px var(--c), 0 2px 10px rgba(0,0,0,.4); }
.leaflet-tooltip { background: var(--surface); color: var(--text); border: 0; box-shadow: var(--shadow); border-radius: 8px; font: inherit; font-size: 13px; }
.leaflet-tooltip-top::before { border-top-color: var(--surface); }

/* ---------- panel (sidebar on desktop, bottom sheet on mobile) ---------- */
.panel {
  position: fixed; z-index: 1100; background: var(--surface); box-shadow: var(--shadow);
  display: flex; flex-direction: column; overflow: hidden;
  top: 70px; left: 12px; bottom: 12px; width: 400px; border-radius: var(--radius);
  transition: transform .25s ease, opacity .2s;
}
.panel[hidden] { display: flex; transform: translateX(-110%); opacity: 0; pointer-events: none; }
.panel .grab { display: none; }
.panel-head { display: flex; align-items: flex-start; gap: 10px; padding: 14px 14px 10px; border-bottom: 1px solid var(--border); }
.panel-head h2 { margin: 0; font-size: 1.15em; line-height: 1.25; }
.panel-head .sub { color: var(--muted); font-size: .88em; margin-top: 2px; }
.panel-head .close { margin-left: auto; width: 34px; height: 34px; border: 0; border-radius: 10px; background: var(--surface-2); cursor: pointer; display: grid; place-items: center; flex-shrink: 0; }
.panel-body { overflow: auto; flex: 1; overscroll-behavior: contain; padding-bottom: env(safe-area-inset-bottom); }
.section { padding: 12px 14px; border-bottom: 1px solid var(--border); }
.section:last-child { border-bottom: 0; }
.section h3 { margin: 0 0 8px; font-size: .78em; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700; }
.kv { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 8px; }
.kv > div { background: var(--surface-2); border-radius: 10px; padding: 8px 10px; }
.kv b { display: block; font-size: 1.15em; font-variant-numeric: tabular-nums; }
.kv span { font-size: .78em; color: var(--muted); }
.actions { display: flex; gap: 8px; flex-wrap: wrap; }
.act { border: 1px solid var(--border); background: var(--surface); padding: 7px 12px; border-radius: 10px; cursor: pointer; font-size: .9em; display: inline-flex; align-items: center; gap: 6px; }
.act:hover { background: var(--surface-2); }
.act.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.notice { background: color-mix(in srgb, var(--warn) 14%, transparent); border-radius: 10px; padding: 8px 10px; font-size: .88em; margin-bottom: 6px; }

.deps { list-style: none; margin: 0; padding: 0; }
.dep { display: grid; grid-template-columns: auto 1fr auto; gap: 4px 10px; align-items: center; padding: 9px 14px; cursor: pointer; border-bottom: 1px solid var(--border); }
.dep:hover { background: var(--surface-2); }
.dep .dir { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dep .meta { grid-column: 2; font-size: .8em; color: var(--muted); }
.dep .when { text-align: right; grid-row: span 2; font-variant-numeric: tabular-nums; }
.dep .when b { display: block; font-size: 1.1em; }
.dep.cancelled .dir, .dep.cancelled .when b { text-decoration: line-through; color: var(--faint); }

.timeline { list-style: none; margin: 0; padding: 4px 0; }
.tl { display: grid; grid-template-columns: 46px 18px 1fr auto; align-items: center; gap: 0 8px; padding: 0 14px; min-height: 38px; cursor: pointer; }
.tl:hover { background: var(--surface-2); }
.tl .t { font-variant-numeric: tabular-nums; font-size: .9em; text-align: right; }
.tl .t s { color: var(--faint); font-size: .85em; display: block; line-height: 1; }
.tl .rail { position: relative; align-self: stretch; }
.tl .rail::before { content: ""; position: absolute; left: 7px; top: 0; bottom: 0; width: 4px; background: var(--c); }
.tl:first-child .rail::before { top: 50%; } .tl:last-child .rail::before { bottom: 50%; }
.tl .rail::after { content: ""; position: absolute; left: 3px; top: 50%; width: 12px; height: 12px; margin-top: -6px; border-radius: 50%; background: var(--surface); border: 3px solid var(--c); box-sizing: border-box; }
.tl.past { color: var(--faint); }
.tl.past .rail::before, .tl.past .rail::after { filter: grayscale(1) opacity(.5); }
.tl.cur .rail::after { background: var(--c); width: 16px; height: 16px; left: 1px; margin-top: -8px; }
.tl.cur .name { font-weight: 700; }
.tl.cancelled .name { text-decoration: line-through; }
.tl .name { padding: 8px 0; }

.tabs { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 4px; }
.tab { border: 1px solid var(--border); background: var(--surface); border-radius: 99px; padding: 5px 12px; cursor: pointer; white-space: nowrap; font-size: .88em; }
.tab.on { background: var(--text); color: var(--surface); border-color: var(--text); }
.vlist { display: flex; flex-direction: column; }
.vrow { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px dashed var(--border); cursor: pointer; }
.vrow:last-child { border-bottom: 0; }
.mini-table { width: 100%; border-collapse: collapse; font-size: .88em; }
.mini-table td, .mini-table th { padding: 5px 4px; text-align: left; border-bottom: 1px solid var(--border); }
.mini-table th { color: var(--muted); font-weight: 600; font-size: .9em; }
.mini-table td.n { text-align: right; font-variant-numeric: tabular-nums; }

.filters .grid { display: flex; flex-wrap: wrap; gap: 6px; }
.lchip { border: 2px solid transparent; padding: 0; background: none; cursor: pointer; border-radius: 9px; }
.lchip.off { opacity: .3; }
.lchip .badge { font-size: .95em; height: 1.9em; min-width: 2.4em; }
.toggle { display: flex; align-items: center; justify-content: space-between; padding: 6px 0; gap: 10px; }
.seg { display: inline-flex; background: var(--surface-2); border-radius: 10px; padding: 3px; }
.seg button { border: 0; background: none; padding: 5px 10px; border-radius: 8px; cursor: pointer; font-size: .88em; color: var(--muted); }
.seg button.on { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,.12); }
.skeleton { padding: 24px 14px; color: var(--faint); text-align: center; }

/* ---------- mobile ---------- */
@media (max-width: 720px) {
  .topbar { top: max(10px, env(safe-area-inset-top)); left: 10px; right: 10px; }
  .search { max-width: none; }
  .logo .txt { display: none; }
  .tools .btn.hide-m { display: none; }
  .btn { width: 44px; height: 44px; }
  .search-row { height: 44px; }
  .status { bottom: calc(14px + env(safe-area-inset-bottom)); left: 10px; }
  .leaflet-bottom.leaflet-right .leaflet-control-zoom { display: none; }
  .panel {
    top: auto; left: 0; right: 0; bottom: 0; width: auto; border-radius: 18px 18px 0 0;
    height: 88vh; height: 88dvh; transform: translateY(var(--sheet-y, 50%));
    transition: transform .28s cubic-bezier(.2,.8,.2,1);
  }
  .panel.dragging { transition: none; }
  .panel[hidden] { transform: translateY(100%); }
  .panel .grab { display: block; padding: 8px 0 2px; cursor: grab; touch-action: none; }
  .panel .grab::before { content: ""; display: block; width: 40px; height: 5px; border-radius: 3px; background: var(--border); margin: 0 auto; }
  .panel-head { padding-top: 4px; touch-action: none; }
}
.osm-dark { filter: invert(1) hue-rotate(180deg) brightness(.9) contrast(.9); }
.leaflet-gl-layer { z-index: 200; }
.tabs { flex-wrap: wrap; overflow: visible; }
.tab .badge { font-size: .8em; }
.tab:has(.badge) { padding: 3px 4px; }
.dep .meta { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.search { min-width: 0; }
@media (max-width: 720px) {
  .topbar { gap: 6px; }
  .tools { gap: 6px; }
  .btn { width: 42px; height: 42px; }
  .search-row { height: 42px; padding: 0 10px; }
}
.result > span:not(.lines):not(.badge) { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.result .lines { flex: 0 1 auto; max-width: 55%; }
.result .icon { flex-shrink: 0; }

/* ---------- theme variants (on top of the light / dark family) ---------- */
:root[data-variant="night"] {
  --bg: #0f1729; --surface: #16213a; --surface-2: #1e2c4a; --border: #2a3a5e;
  --text: #e6edf9; --muted: #a7b6d3; --faint: #6f80a3; --accent: #5ea3ff; --accent-soft: #1b3358;
  --ok: #4fd18b; --warn: #f5c451; --bad: #ff7a7a; --early: #8ab8ff;
}
:root[data-variant="sepia"] {
  --bg: #efe6d4; --surface: #fbf6ec; --surface-2: #f1e7d5; --border: #e0d2b8;
  --text: #3b2f22; --muted: #6e5a44; --faint: #9a8569; --accent: #a0522d; --accent-soft: #f3e1d2;
}
:root[data-variant="contrast"] {
  --bg: #ffffff; --surface: #ffffff; --surface-2: #eeeeee; --border: #000000;
  --text: #000000; --muted: #1f1f1f; --faint: #3d3d3d; --accent: #c00000; --accent-soft: #ffe0e0;
  --ok: #006b2f; --warn: #8a5a00; --bad: #b00000; --early: #0039a6;
  --shadow: 0 0 0 1.5px #000;
}
:root[data-variant="color"], :root[data-variant="bright"] { --accent: #c9302c; }
:root[data-variant="sepia"] .leaflet-gl-layer, :root[data-variant="sepia"] .leaflet-tile-pane { filter: sepia(.45) saturate(.85) brightness(1.02); }
:root[data-variant="contrast"] .leaflet-gl-layer { filter: contrast(1.25) saturate(.9); }

.theme-picks { display: flex; flex-wrap: wrap; gap: 6px; }
.theme-pick { padding: 2px; border-radius: 9px; border: 2px solid transparent; background: none; cursor: pointer; line-height: 0; }
.theme-pick.on { border-color: var(--accent); }
.theme-pick .sw { display: block; width: 30px; height: 30px; border-radius: 6px; border: 1px solid rgba(127,127,127,.45); position: relative; }
.theme-pick .sw i { position: absolute; right: 4px; bottom: 4px; width: 9px; height: 9px; border-radius: 50%; }
.theme-pick[data-t="auto"] .sw { background: linear-gradient(135deg, #ffffff 50%, #191c22 50%) !important; }

/* the hidden attribute always wins over component display rules */
[hidden] { display: none !important; }

/* ---------- more dark themes ---------- */
:root[data-variant="oled"] {
  --bg: #000000; --surface: #0b0b0c; --surface-2: #161618; --border: #26262a;
  --text: #f2f2f2; --muted: #a8a8ad; --faint: #6c6c72; --accent: #ff4d5e; --accent-soft: #2a0f13;
}
:root[data-variant="graphite"] {
  --bg: #1d1f23; --surface: #2a2d33; --surface-2: #33373e; --border: #41454d;
  --text: #f0f0f0; --muted: #b4b8c0; --faint: #7e838c; --accent: #e8e8e8; --accent-soft: #3d4149;
}
:root[data-variant="forest"] {
  --bg: #0d1611; --surface: #13201a; --surface-2: #1a2c23; --border: #24392e;
  --text: #e3f1e8; --muted: #a3c2ae; --faint: #6b8a76; --accent: #4fd18b; --accent-soft: #163626;
}
:root[data-variant="plum"] {
  --bg: #150e1b; --surface: #1e1526; --surface-2: #281d33; --border: #362845;
  --text: #f0e6f7; --muted: #c0aed0; --faint: #84739a; --accent: #c77dff; --accent-soft: #33204a;
}
:root[data-variant="ember"] {
  --bg: #16120c; --surface: #1f1912; --surface-2: #2a2219; --border: #3a2f22;
  --text: #f6ecdf; --muted: #cdb89d; --faint: #8f7c63; --accent: #ffb02e; --accent-soft: #3a2a12;
}
:root[data-variant="ocean"] {
  --bg: #08191d; --surface: #0d2329; --surface-2: #133038; --border: #1c4049;
  --text: #e1f4f4; --muted: #9fc9cb; --faint: #648f92; --accent: #2ec4c4; --accent-soft: #10393d;
}
:root[data-variant="oled"] .leaflet-gl-layer { filter: brightness(.7) contrast(1.15); }
:root[data-variant="graphite"] .leaflet-gl-layer { filter: grayscale(1) brightness(1.1); }
:root[data-variant="forest"] .leaflet-gl-layer { filter: sepia(.5) hue-rotate(70deg) saturate(1.4); }
:root[data-variant="plum"] .leaflet-gl-layer { filter: sepia(.5) hue-rotate(230deg) saturate(1.5); }
:root[data-variant="ember"] .leaflet-gl-layer { filter: sepia(.6) saturate(1.3); }
:root[data-variant="ocean"] .leaflet-gl-layer { filter: hue-rotate(-25deg) saturate(1.2); }
