/* ============================================================
   Transit boards — shared theme
   One source of truth for the palette, typeface, and header
   city-tabs used by every page (DC/Philly/NYC boards, the
   stencil template, the sky view, and the departure board).
   This file loads BEFORE each page's inline <style>, so a page
   can still override a token for its own aesthetic (the sky
   view's night palette, the departure board's split-flap look).
   ============================================================ */

:root{
  /* Core palette — richer blues than the old near-black navy */
  --bg:#081020; --panel:#111d36; --panel2:#0c1628; --line:#22345a; --bg-glow:#152a52;
  --text:#eef3ff; --muted:#93a5cf; --accent:#4ea1ff; --good:#33d17a; --late:#ff5a5a;
  --warn:#ffcc33; --live:#33d17a; --sched:#7f93c4; --plane:#ffd166; --amtrak:#3ad0c8; --busveh:#6aa9ff;
  --row-bg:#0d1830; --row-line:#1c2c4e; --sched-b:#b3c3e8; --scrim:rgba(5,10,22,.86);
  /* blue depth range: bright for highlights (clock ink, row sheen, labels),
     deep for floors (header/footer washes) — flipped per theme below */
  --blue-bright:#7cc0ff; --blue-deep:#0a1a3d;
  /* row density -- "Trains per box" in Settings overrides these (see [data-rows]).
     Smaller rows -> more trains fit each box; larger -> fewer, bigger.
     The default is deliberately compact (what used to be the "More" size,
     shifted one notch) so more vehicles fit on screen out of the box. */
  --row-gap:3px; --row-pad:4px 8px; --badge-h:22px; --dest-fs:13px; --sub-fs:11px; --live-fs:15px;
  /* WMATA line colors (DC board) */
  --RD:#BF0D3E; --BL:#009CDE; --YL:#FFD100; --OR:#ED8B00; --GR:#00B140; --SV:#919D9D;
}
:root[data-rows="more"]{ --row-gap:2px; --row-pad:3px 7px; --badge-h:19px; --dest-fs:12px; --sub-fs:10px; --live-fs:13px; }
:root[data-rows="fewer"]{ --row-gap:5px; --row-pad:7px 9px; --badge-h:26px; --dest-fs:15px; --sub-fs:12px; --live-fs:18px; }
:root[data-theme="black"]{
  --bg:#000000; --panel:#060910; --panel2:#000000; --line:#1a2338; --bg-glow:#0a0f1a;
  --text:#eef2fa; --muted:#8d99b5; --row-bg:#04070d; --row-line:#141c2e; --sched-b:#c6d0e4;
  --blue-bright:#6fb4ff; --blue-deep:#050a18;
}
:root[data-theme="day"]{
  --bg:#e9eefb; --panel:#ffffff; --panel2:#f1f5fd; --line:#d0dcf2; --bg-glow:#d7e3fa;
  --text:#13203e; --muted:#54648c; --row-bg:#ffffff; --row-line:#dde6f7; --sched-b:#334a78;
  --scrim:rgba(165,185,225,.55);
  /* light theme: "bright" = a saturated darker blue (reads on white), "deep" = pale wash */
  --blue-bright:#1e63c4; --blue-deep:#dbe6fa;
}

/* One typeface everywhere: the native system UI font (San Francisco on
   Apple devices, Segoe on Windows), same stack the boards always used */
body{ font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif; }

/* City switcher — dropdown in each board's header (replaced the segmented
   tab row once the city list outgrew it). The <select> carries the kiosk
   fullscreen flag in its onchange, same as the old tab links did. */
.city-picker select{
  -webkit-appearance:none; appearance:none;
  background:var(--panel) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='%2393a5cf' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>") no-repeat right 11px center;
  color:var(--text); border:1px solid var(--line); border-radius:10px;
  padding:8px 30px 8px 12px; font-family:inherit; font-size:13px; font-weight:700;
  letter-spacing:.2px; cursor:pointer;
}
.city-picker select:hover{ border-color:var(--accent); }
.city-picker select:focus{ outline:none; border-color:var(--accent); }

/* Legacy segmented tabs (kept for any page still using them).
   The current city is a non-clickable <span class="active">;
   the others are links to their boards. */
.city-tabs{ display:flex; align-items:center; gap:2px; padding:3px;
  background:var(--panel2); border:1px solid var(--line); border-radius:11px; }
.city-tabs a, .city-tabs span{ padding:6px 13px; border-radius:8px; color:var(--muted);
  text-decoration:none; font-weight:700; font-size:13px; letter-spacing:.2px; white-space:nowrap; }
.city-tabs a:hover{ color:var(--text); }
.city-tabs .active{ background:var(--accent); color:#04101f; }

/* View links (Sky, Board) beside the city tabs */
.view-links{ display:flex; gap:8px; }
.view-links a{ background:var(--panel); color:var(--text); border:1px solid var(--line);
  border-radius:10px; padding:8px 12px; font-size:13px; font-weight:600;
  text-decoration:none; white-space:nowrap; }
.view-links a:hover{ border-color:var(--accent); }

@media (max-width:760px){
  header{ flex-wrap:wrap; row-gap:8px; }
  .city-tabs a, .city-tabs span{ padding:5px 10px; font-size:12px; }
  .view-links a{ padding:6px 10px; font-size:12px; }
}

/* Follow-a-vehicle: the click popup's Follow button + the "Following …" banner
   over the map. Shared by every board (all link this file). */
.follow-pop{ font:600 12.5px/1.4 "Helvetica Neue",Helvetica,Arial,sans-serif; text-align:center; color:#111; }
.follow-pop button{ margin-top:7px; padding:6px 11px; border:0; border-radius:8px;
  background:var(--accent); color:#04101f; font-weight:800; font-size:12.5px; cursor:pointer; }
#followBanner{ position:absolute; top:10px; left:50%; transform:translateX(-50%); z-index:1000;
  display:none; align-items:center; gap:9px; padding:7px 9px 7px 13px; border-radius:11px;
  background:var(--panel); border:1px solid var(--accent); box-shadow:0 6px 20px rgba(0,0,0,.5);
  font:600 13px/1 "Helvetica Neue",Helvetica,Arial,sans-serif; color:var(--text); max-width:92%; }
#followBanner .fb-dot{ width:8px; height:8px; border-radius:50%; background:var(--accent);
  box-shadow:0 0 8px var(--accent); flex:none; }
#followBanner .fb-txt{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#followBanner .fb-txt b{ font-weight:800; }
#followBanner .fb-stop{ border:0; border-radius:8px; padding:5px 9px; background:var(--row-line);
  color:var(--text); font-weight:700; font-size:12px; cursor:pointer; flex:none; }
#followBanner .fb-stop:hover{ background:var(--late); color:#fff; }

/* rich vehicle click-detail popup (Boston: crowding/speed + live next stops) */
.veh-pop{ font:600 12px/1.35 "Helvetica Neue",Helvetica,Arial,sans-serif; color:#111; min-width:180px; }
.veh-pop .vp-title{ font-weight:800; font-size:13px; margin-bottom:2px; }
.veh-pop .vp-sub{ color:#444; font-weight:600; margin-bottom:5px; }
.veh-pop .vp-load{ color:#777; font-style:italic; }
.veh-pop .vp-hd{ color:#777; font-weight:700; text-transform:uppercase; letter-spacing:.05em; font-size:10px; margin:4px 0 2px; }
.veh-pop .vp-stop{ display:flex; justify-content:space-between; gap:14px; padding:1px 0; }
.veh-pop .vp-stop b{ font-variant-numeric:tabular-nums; }
.veh-pop .vp-follow{ margin-top:8px; width:100%; padding:6px 10px; border:0; border-radius:8px;
  background:var(--accent); color:#04101f; font-weight:800; font-size:12.5px; cursor:pointer; }
/* a departure row you can click to follow that train on the map */
.row.followable{ cursor:pointer; }
.row.followable:hover{ border-color:var(--accent); }

/* ---- Service alerts card (replaced the bottom scrolling ticker) ----
   Alerts are ranked by severity and sit still so they can actually be read
   from across a room. Severity is carried by a WORD as well as a colour (and a
   left bar), never colour alone. The whole card is hidden when nothing is
   wrong, so its mere presence means "something is up". */
.alert-row{ display:grid; grid-template-columns:auto 1fr; gap:9px; align-items:start;
  padding:var(--row-pad); border-radius:4px; background:var(--row-bg);
  border:1px solid var(--row-line); border-left:3px solid var(--sev,var(--accent)); }
.alert-row .sev{ font:800 9px/1.6 var(--mono,ui-monospace,Menlo,monospace); letter-spacing:.1em;
  text-transform:uppercase; color:var(--sev,var(--accent)); white-space:nowrap; padding-top:1px; }
/* one line, ellipsised: some feeds put a whole sentence in the "affected" label
   (MBTA names both stop directions), which would wrap into a very tall row and
   push every other alert out of the card */
.alert-row .who{ font-weight:800; font-size:var(--sub-fs,11px); color:var(--text);
  display:block; letter-spacing:.02em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.alert-row .msg{ font-size:var(--sub-fs,11px); color:var(--muted); line-height:1.45;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
#alertCard .list{ gap:var(--row-gap); }

/* ---- Map-only full screen (every board) ----
   The button pinned top-right on the map pins #map over the whole viewport:
   just the map + its vehicles, no cards/header/ticker. position needs
   !important because Leaflet writes an inline position:relative on the
   container at init; z-index 800 covers the page (ticker is 70) while the
   settings overlay (9999) and toasts stay above. */
/* #map must ALWAYS be positioned from the stylesheet: Leaflet only writes its
   own inline position:relative when the container is static at init, so a board
   that BOOTS in map-full mode (container fixed at init) would otherwise drop
   back to static on exit — and the absolutely-positioned map panes would anchor
   to the page and paint over the whole board. */
#map{ position:relative; }
#mapFsBtn{ position:absolute; top:10px; right:10px; z-index:1001; width:36px; height:36px;
  display:flex; align-items:center; justify-content:center; padding:0;
  background:var(--panel); color:var(--text); border:1px solid var(--line); border-radius:10px;
  cursor:pointer; box-shadow:0 4px 14px rgba(0,0,0,.35); }
#mapFsBtn:hover{ border-color:var(--accent); }
body.map-full #map{ position:fixed !important; inset:0; z-index:800; border-radius:0; border:none; }

/* ---- Display size + edge fit (Settings → Display) ----------------------------
   For kiosk screens you can't adjust: TVs overscan (they crop a few percent off
   every edge, so tiles and card text fall off the sides), and a panel's reported
   viewport is often bigger than what you can actually see.
     --ui-zoom   scales the WHOLE board. `zoom` (not transform) so the layout
                 genuinely reflows -- cards refit, fitList re-trims -- instead of
                 being visually squashed.
     --safe-pad  insets the board from every edge, to sit inside a TV's crop.
   #app's own height/width must be divided by the zoom: it's sized in CSS pixels
   (100dvh), and zoom multiplies what those pixels occupy, so without this a
   zoom>1 overflows and a zoom<1 leaves dead space. Selector is `body #app` so it
   beats each board's own plain `#app{height:100dvh}` rule regardless of order. */
:root{ --ui-zoom:1; --safe-pad:0px; }
body{ padding:var(--safe-pad); }
body #app{
  zoom:var(--ui-zoom);
  height:calc((100dvh - var(--safe-pad) * 2) / var(--ui-zoom));
  width:calc((100vw - var(--safe-pad) * 2) / var(--ui-zoom));
}

/* Reclaim vertical space inside a card: the stop + direction labels were using
   ~45px of a ~95px list on a small screen, leaving no room for the departures
   they label. Higher specificity than each board's own rule, so one edit covers
   every board. */
.list .stop-label{ margin:3px 2px 1px; }
.list .dir-label{ margin:2px 2px 1px 8px; }

/* ---- space efficiency inside a card -----------------------------------------
   Three savings, worth ~45px per card (roughly two extra departures on a small
   kiosk screen):
   1. `.dir-label` printed "→ Headsign" and then every row beneath it repeated
      that same headsign as its own title -- a whole line per direction for zero
      new information. Gone.
   2. The statline sits on the header's baseline instead of owning a line.
   3. Slightly tighter row padding + a shorter stop label.
   All of it is layout only: no departure, time or status is dropped. */
.card h2{ position:relative; }
.card .statline{ margin:0 0 3px; font-size:10px; opacity:.85; }
.list .dir-label{ display:none; }
.list .stop-label{ margin:2px 2px 1px; font-size:10px; }
.list .row{ padding:2px 8px; }
.list .row .dest{ line-height:1.1; }
.list .row .sub{ line-height:1.15; }

/* A long destination ("Center City Philadelphia") wrapped to two lines in a
   narrow card, making rows ~50px instead of ~33px -- that wrapping, not the
   chrome, was what kept boxes down to one departure. One line + ellipsis. */
.list .row .dest, .list .row .sub{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
.list .row{ align-items:center; }

/* ---- new-alert toasts -------------------------------------------------------
   A board is a glance device: if an alert appears while you're standing there,
   the card quietly gaining a row is easy to miss. These slide in only for alerts
   that are genuinely NEW since the page has been up (the first load seeds
   silently, or you'd get a stack of toasts every boot), and they leave on their
   own. Top-right, clear of the map's fullscreen button. */
#alertToasts{ position:fixed; top:12px; right:12px; z-index:1200; display:flex;
  flex-direction:column; gap:8px; max-width:min(380px, 42vw); pointer-events:none; }
.atoast{ pointer-events:auto; background:var(--panel); color:var(--text);
  border:1px solid var(--line); border-left:4px solid var(--sev,var(--accent));
  border-radius:8px; padding:9px 11px; box-shadow:0 10px 30px rgba(0,0,0,.45);
  opacity:0; transform:translateX(14px); transition:opacity .3s ease, transform .3s ease; }
.atoast.in{ opacity:1; transform:none; }
.atoast .at-hd{ display:flex; align-items:center; gap:8px; margin-bottom:3px; }
.atoast .at-sev{ font:800 9px/1.6 var(--mono,ui-monospace,Menlo,monospace); letter-spacing:.1em;
  text-transform:uppercase; color:var(--sev,var(--accent)); }
.atoast .at-new{ font:700 9px/1.6 var(--mono,ui-monospace,Menlo,monospace); letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted); }
.atoast .at-x{ margin-left:auto; background:none; border:0; color:var(--muted);
  font-size:13px; line-height:1; cursor:pointer; padding:2px 4px; }
.atoast .at-x:hover{ color:var(--text); }
.atoast .at-who{ font-weight:800; font-size:12px; }
.atoast .at-msg{ font-size:12px; color:var(--muted); line-height:1.45;
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }

/* A TV remote can't chase a hidden scrollbar: make the Settings panel's one
   visible and thick enough to see from across a room, and give focused controls
   a clear ring so you can tell where the D-pad is. */
#setup .box{ scrollbar-width:auto; scrollbar-color:var(--accent) var(--row-bg); }
#setup .box::-webkit-scrollbar{ width:12px; }
#setup .box::-webkit-scrollbar-track{ background:var(--row-bg); border-radius:8px; }
#setup .box::-webkit-scrollbar-thumb{ background:var(--accent); border-radius:8px; }
#setup .box :focus-visible{ outline:3px solid var(--accent); outline-offset:2px; border-radius:8px; }

/* ---- decluttering the board ------------------------------------------------
   Legend hidden unless asked for (Settings -> Map legend), and the header's
   view links stop shouting: they were five boxed buttons competing with the
   board's own title for attention. Quieter until hovered/focused. */
:root[data-legend="off"] .legend{ display:none; }
.view-links a{ background:transparent; border-color:transparent; color:var(--muted);
  padding:6px 9px; font-weight:600; }
.view-links a:hover, .view-links a:focus-visible{ color:var(--text); background:var(--panel);
  border-color:var(--line); }
