/* SWB Departure Board — styled to mimic the physical "Bus und Bahn" sign. */

:root {
  --swb-red: #c0392b;
  --swb-red-2: #9b271b;
  --frame: #eceae3;
  --frame-edge: #cfccc2;
  --screen-bg: #dfe3e6;
  --screen-panel: #eef1f2;
  --ink: #2b2f45;
  --muted: #8a8f9c;
  --divider: #c3c8cc;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* Sign display font — Fira Sans (a free Frutiger-like humanist sans) is the
     default; overridden per body[data-font] via the font switcher. */
  --sign-font: "Fira Sans", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}

/* Font switcher: mapped from the ?font= param via <body data-font>. */
body[data-font="system"] { --sign-font: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif; }
body[data-font="roboto"] { --sign-font: "Roboto Condensed", system-ui, sans-serif; }
body[data-font="inter"]  { --sign-font: "Inter", system-ui, sans-serif; }
body[data-font="fira"]   { --sign-font: "Fira Sans", system-ui, sans-serif; }


* { box-sizing: border-box; }


body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding: 1.5rem 1rem 3rem;
  background: #4a4f57;
  color: #e7e9ee;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}

.status {
  margin: 0;
  font-size: 0.9rem;
  color: #cfd3da;
  text-align: center;
}

/* --- Stop picker --------------------------------------------------------- */
.board-search {
  display: flex;
  gap: 0.5rem;
  width: min(520px, 100%);
}
.board-search[hidden] { display: none; }
.board-search input {
  flex: 1;
  padding: 0.6rem 0.75rem;
  border: 1px solid #2f333b;
  border-radius: 8px;
  font-size: 1rem;
}
.board-search button {
  border: none;
  background: var(--swb-red);
  color: #fff;
  border-radius: 8px;
  padding: 0 1.1rem;
  font-weight: 700;
  cursor: pointer;
}
.board-search button:hover { background: var(--swb-red-2); }

.board-search-results {
  list-style: none;
  margin: 0;
  padding: 0;
  width: min(520px, 100%);
}
.board-hit {
  width: 100%;
  text-align: left;
  border: 1px solid #2f333b;
  background: #3c414a;
  color: #e7e9ee;
  border-radius: 8px;
  padding: 0.5rem 0.7rem;
  margin: 0.25rem 0;
  cursor: pointer;
  font-size: 0.95rem;
}
.board-hit:hover { border-color: var(--swb-red); }
.board-hit:disabled { opacity: 0.5; cursor: not-allowed; }

/* --- Journey picker (From / To + swap) ----------------------------------- */
.jb-picker {
  width: min(520px, 100%);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.jb-picker[hidden] { display: none; }

.jb-field { display: flex; flex-direction: column; gap: 0.3rem; }
.jb-field > label {
  font-size: 0.8rem;
  font-weight: 700;
  color: #cfd3da;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.jb-field input {
  padding: 0.6rem 0.75rem;
  border: 1px solid #2f333b;
  border-radius: 8px;
  font-size: 1rem;
}

/* Chosen From/To chip with clear (×) button */
.jb-chosen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  border: 1px solid var(--swb-red);
  background: #3c414a;
  border-radius: 8px;
  padding: 0.5rem 0.7rem;
  font-size: 0.95rem;
}
.jb-chosen[hidden] { display: none; }
.jb-chosen .jb-clear {
  border: none;
  background: transparent;
  color: #e7e9ee;
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.2rem;
}
.jb-chosen .jb-clear:hover { color: var(--swb-red); }

.jb-swap-row { display: flex; justify-content: center; }
.jb-swap {
  border: 1px solid #2f333b;
  background: #3c414a;
  color: #e7e9ee;
  border-radius: 999px;
  width: 2.4rem;
  height: 2.4rem;
  font-size: 1.2rem;
  cursor: pointer;
}
.jb-swap:hover { border-color: var(--swb-red); }
.jb-swap:disabled { opacity: 0.4; cursor: not-allowed; }

.jb-show {
  border: none;
  background: var(--swb-red);
  color: #fff;
  border-radius: 8px;
  padding: 0.6rem 1rem;
  font-weight: 700;
  cursor: pointer;
}
.jb-show:hover { background: var(--swb-red-2); }
.jb-show:disabled { opacity: 0.4; cursor: not-allowed; }

/* The stop→stop screen label + filter note */
.screen-route { display: flex; align-items: baseline; gap: 0.35rem; min-width: 0; }
.screen-route .screen-arrow { color: var(--swb-red); font-weight: 800; }
.screen-route .screen-to { color: #4a4f63; opacity: 0.85; }
.jb-note {
  padding: 0 0.4rem 0.4rem;
  font-size: 0.8rem;
  color: #6a6f7d;
}


/* --- The sign ------------------------------------------------------------ */
.sign { width: min(680px, 100%); }
.sign[hidden] { display: none; }

.sign-frame {
  background: var(--frame);
  border: 1px solid var(--frame-edge);
  border-radius: 22px;
  padding: 14px;
  box-shadow:
    0 10px 30px rgba(0, 0, 0, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

/* Red branded header with halftone dots */
.sign-head {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: linear-gradient(180deg, var(--swb-red), var(--swb-red-2));
  border-radius: 14px 14px 4px 4px;
  padding: 0.7rem 1.1rem 1.4rem;
  color: #fff;
  overflow: hidden;
}

/* Control buttons living in the red header (Change stop / ⇅ Swap). */
.sign-head-btn {
  z-index: 1;
  border: 1px solid rgba(255, 255, 255, 0.7);
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  border-radius: 999px;
  padding: 0.35rem 0.75rem;
  min-height: 34px;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.sign-head-btn:hover { background: rgba(255, 255, 255, 0.28); }
.sign-head-btn:active { background: rgba(255, 255, 255, 0.4); }

.sign-info {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-weight: 700;
  font-size: 2.1rem;
  line-height: 1;
  width: 1.6rem;
  text-align: center;
}
.sign-brand {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  z-index: 1;
}
.sign-brand-mark { font-size: 2rem; line-height: 1; }
.sign-brand-text { display: flex; flex-direction: column; line-height: 1; }
.sign-brand-text strong { font-size: 1.7rem; letter-spacing: 0.06em; }
.sign-brand-text small { font-size: 0.85rem; opacity: 0.95; }

/* Halftone dot band along the bottom of the red header */
.sign-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1.1rem;
  background-image: radial-gradient(rgba(255, 255, 255, 0.9) 34%, transparent 36%);
  background-size: 12px 12px;
  background-position: 0 6px;
  opacity: 0.8;
}

/* Display panel */
.sign-screen {
  background: var(--screen-bg);
  border-radius: 4px 4px 12px 12px;
  padding: 10px;
  border: 2px solid #b9bdc0;
  border-top: none;
}

.screen-topbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 0.4rem 0.35rem;
  color: var(--ink);
}
.screen-stop { font-weight: 700; font-size: 0.95rem; color: #4a4f63; }
.screen-clock {
  font-family: var(--sign-font);
  font-weight: 700;
  font-size: 1.6rem;
  color: var(--ink);
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}


.board {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--screen-panel);
  border-radius: 6px;
}

.board-row {
  display: grid;
  grid-template-columns: 4.5rem 1fr auto;
  align-items: center;
  gap: 0.75rem;
  height: 3.4rem;
  padding: 0 0.8rem;
  border-top: 1px solid var(--divider);
}
.board-row:first-child { border-top: none; }
.board-row-empty { background: transparent; }

.board-line {
  font-family: var(--sign-font);
  font-weight: 700;
  font-size: 1.9rem;
  color: var(--ink);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.board-dest {
  font-family: var(--sign-font);
  font-weight: 700;
  font-size: 1.6rem;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.board-when {
  font-family: var(--sign-font);
  font-weight: 700;
  font-size: 1.9rem;
  color: var(--ink);
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.board-min-num { font-size: 1.9rem; }
/* "min"/"h" unit — small, lowercase, lighter, aligned to the big number's
   baseline (as on the physical sign). */
.board-min-unit {
  font-size: 0.85rem;
  font-weight: 400;
  color: #4a4f63;
  margin: 0 0.15rem;
}


/* Delay badge (real-time vs scheduled) */
.board-when { display: inline-flex; align-items: center; gap: 0.4rem; }
.board-delay {
  font-size: 0.8rem;
  font-weight: 800;
  border-radius: 6px;
  padding: 0.1rem 0.4rem;
  line-height: 1.2;
  white-space: nowrap;
}
.board-delay.late { color: #fff; background: #d64545; }
.board-delay.early { color: #fff; background: #2e9e5b; }
.board-delay.ontime { color: #2e9e5b; background: rgba(46, 158, 91, 0.14); }

/* Cancelled departures */
.board-row.cancelled .board-line,
.board-row.cancelled .board-dest,
.board-row.cancelled .board-when {
  color: var(--muted);
  text-decoration: line-through;
}


/* --- Mobile --------------------------------------------------------------- */

@media (max-width: 520px) {
  /* Phone layout: fill the screen exactly (no page scroll) and split the
     vertical space 50/50 between the sign and the map. Only applies once a
     board is showing (body.board-live, set by the JS). */
  body.board-live {
    height: 100dvh;
    min-height: 0;
    padding: 0.5rem 0.6rem;
    gap: 0.5rem;
    overflow: hidden;
  }
  body.board-live .status { display: none; }
  body.board-live .sign {
    flex: 1 1 50%;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  body.board-live .sign-frame {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  body.board-live .sign-screen {
    flex: 1;
    min-height: 0;
    /* Column so the topbar (From→To + clock) stays pinned while the list below
       it scrolls. */
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }
  body.board-live .screen-topbar { flex: none; }
  /* When there are more departures than fit, the list scrolls inside its pane
     instead of being clipped. overscroll-behavior stops the page/map behind it
     from scrolling too. */
  body.board-live .board {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }

  body.board-live .board-map {
    flex: 1 1 45%;
    height: auto;
    /* Must be able to shrink to 0 so it can't steal height from the sign and
       break the board list's scroll. The calc() min-height below (240px) only
       applies when NOT in the board-live flex layout. */
    min-height: 0;
  }


  body { padding: 1rem 0.6rem 2.5rem; }

  .sign-frame { padding: 10px; border-radius: 18px; }

  .sign-head { padding: 0.5rem 0.8rem 1.1rem; gap: 0.5rem; }
  .sign-info { font-size: 1.6rem; width: 1.2rem; }
  .sign-brand-mark { font-size: 1.5rem; }
  .sign-brand-text strong { font-size: 1.3rem; }
  .sign-brand-text small { font-size: 0.72rem; }

  .board-row {
    grid-template-columns: 3.2rem 1fr auto;
    gap: 0.5rem;
    height: 3rem;
    padding: 0 0.55rem;
  }
  .board-line, .board-when, .board-min-num { font-size: 1.4rem; }
  .board-dest { font-size: 1.2rem; }
  .board-min-unit { font-size: 0.75rem; }
  .board-delay { font-size: 0.7rem; padding: 0.08rem 0.3rem; }
  .screen-clock { font-size: 1.3rem; }

  /* From → To must never push the clock off-screen. */
  .screen-route { flex: 1; overflow: hidden; }
  .screen-route #screen-from,
  .screen-route #screen-to {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 45%;
  }

}

/* Very small phones */
@media (max-width: 360px) {
  .board-row { grid-template-columns: 2.8rem 1fr auto; gap: 0.4rem; padding: 0 0.45rem; }
  .board-line, .board-when, .board-min-num { font-size: 1.2rem; }
  .board-dest { font-size: 1.05rem; }
  .sign-brand-text strong { font-size: 1.15rem; }
}

/* --- Live line map -------------------------------------------------------- */
/* Sits directly under the sign; shows line paths + live vehicle positions. */
.board-map {
  width: min(680px, 100%);
  /* Grow to fill the space under the sign (the bottom controls bar is gone).
     Falls back to 480px on browsers without dvh. */
  height: 480px;
  height: calc(100dvh - 340px);
  min-height: 320px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
  background: #e7e9ee;
}
.board-map[hidden] { display: none; }


/* Leaflet tiles/controls inherit the page font; keep readable ink colour. */
.board-map .leaflet-container { font: inherit; background: #dfe3e6; }

/* Vehicle marker: a circle badge showing the line number (--veh-color is the
   line colour). Direction is encoded by INVERTED styling:
     • direction 1 (default): coloured background, white text + white border,
     • direction 2 (.inverted): white background, coloured text + coloured border. */
.veh-icon { background: none; border: none; }
.veh-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--veh-color, #039cdd);
  color: #fff;
  font-weight: 800;
  font-size: 12px;
  line-height: 1;
  border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
}
.veh-badge.inverted {
  background: #fff;
  color: var(--veh-color, #039cdd);
  border-color: var(--veh-color, #039cdd);
}
/* Vehicles running the OTHER way (not toward the board's destination) fade
   back so the relevant direction stands out. */
.veh-badge.dimmed {
  opacity: 0.35;
  box-shadow: none;
}



/* Bottom-right legend: line badge + its two directions (colour = direction). */
.map-legend {
  background: rgba(255, 255, 255, 0.92);
  border-radius: 8px;
  padding: 0.5rem 0.6rem;
  font: 12px/1.35 system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  color: #2b2f45;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.35);
  max-width: 260px;
  max-height: 40%;
  overflow: auto;
}
.map-legend .legend-title { font-weight: 700; margin-bottom: 0.3rem; }
.map-legend .legend-row { display: flex; align-items: flex-start; gap: 0.4rem; margin: 0.15rem 0; }
.map-legend .legend-badge {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--veh-color, #039cdd);
  color: #fff;
  font-weight: 800;
  font-size: 11px;
  border: 1.5px solid #fff;
}
.map-legend .legend-dirs { display: flex; flex-direction: column; gap: 0.1rem; }
.map-legend .legend-dir { display: flex; align-items: center; gap: 0.3rem; }
.map-legend .legend-dir i.sw {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex: none;
}
/* Filled swatch = direction 1; inverted swatch = direction 2 (matches markers). */
.map-legend .legend-dir i.sw.filled {
  background: var(--veh-color, #039cdd);
  border: 1.5px solid #fff;
  box-shadow: 0 0 0 1px var(--veh-color, #039cdd);
}
.map-legend .legend-dir i.sw.inverted {
  background: #fff;
  border: 1.5px solid var(--veh-color, #039cdd);
}


@media (max-width: 520px) {
  /* On phones let the map fill whatever's left below the sign so the board +
     map share the screen. dvh accounts for the mobile browser chrome. */
  .board-map {
    height: 320px;
    height: calc(100dvh - 300px);
    min-height: 240px;
    border-radius: 10px;
  }
  /* In the live 50/50 layout the map must be allowed to shrink so the sign
     keeps its half and the departures list can scroll. Repeat here (after the
     rule above) so this wins the cascade regardless of source order. */
  body.board-live .board-map {
    height: auto;
    min-height: 0;
  }
  .map-legend { max-width: 190px; font-size: 11px; }
  .veh-badge { width: 24px; height: 24px; font-size: 11px; }
}





