/* Train Times — Eleven Sports Media brand: colours, Winner Sans + Aeonik, on a flat dark ground */
@font-face { font-family: 'Winner Sans Extended'; src: url('/brand/winner-sans-extended-extrabold.woff2') format('woff2'), url('/brand/winner-sans-extended-extrabold.ttf') format('truetype'); font-weight: 800; font-display: swap; }
@font-face { font-family: 'Winner Sans'; src: url('/brand/winner-sans-bold.woff2') format('woff2'), url('/brand/winner-sans-bold.ttf') format('truetype'); font-weight: 700; font-display: swap; }
@font-face { font-family: 'Aeonik'; src: url('/brand/aeonik-vf.woff2') format('woff2'), url('/brand/aeonik-vf.ttf') format('truetype'); font-weight: 100 900; font-display: swap; }

:root {
  --blue: #2CCCD3;
  --purple: #8A69D4;
  --yellow: #EDFF00;
  --black: #101820;
  --mid: #7C878E;
  --soft: #9AA4AA; /* secondary text: clears 4.5:1 on the panels */
  --light: #D0D3D4;
  --white: #FFFFFF;

  --panel: #161D24;
  --plat: #2A3139;
  --line: rgba(208, 211, 212, 0.15);
  --head: 'Winner Sans Extended', 'Arial Black', sans-serif;
  /* Narrower Winner Sans for times and numbers: bigger in the same space, easier to read across a room. */
  --num: 'Winner Sans', 'Arial Narrow', sans-serif;
  --body: 'Aeonik', 'Helvetica Neue', Arial, sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { width: 100%; height: 100%; overflow: hidden; background: var(--black); }
body { color: var(--white); font-family: var(--body); -webkit-font-smoothing: antialiased; }

#stage {
  position: absolute; left: 0; top: 0;
  width: 1920px; height: 1080px;
  transform-origin: 0 0;
  padding: 44px 60px 36px;
  display: grid;
  grid-template-rows: 84px minmax(0, 1fr) 64px;
  grid-template-columns: minmax(0, 1fr);
  grid-row-gap: 32px;
  background: var(--black);
  overflow: hidden;
}

.card { background: var(--panel); border-radius: 6px; overflow: hidden; position: relative; }

.h-label {
  font-family: var(--head); font-size: 17px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--light);
}

/* ---------- header ---------- */
/* (Spacing uses margins rather than flex gap: BrightSign's Chromium predates it.) */
.top { display: flex; align-items: center; }
.brand { flex: 1 1 0; display: flex; align-items: center; min-width: 0; }
.brand-icon { flex: 0 0 auto; display: block; height: 50px; width: auto; margin-right: 16px; }
.brand-title { font-family: var(--head); font-weight: 800; font-size: 30px; line-height: 1; text-transform: uppercase; white-space: nowrap; letter-spacing: 0.01em; }

/* Weather in one line: just now. */
.weather { flex: 0 0 auto; display: flex; align-items: center; white-space: nowrap; }
.wx-icon { width: 52px; height: 52px; flex: 0 0 52px; }
.wx-icon svg { width: 100%; height: 100%; }
.wx-temp { font-family: var(--num); font-size: 56px; line-height: 1; margin: 0 18px 0 14px; }
.wx-text { font-size: 25px; font-weight: 600; color: var(--light); }

.clock { flex: 1 1 0; text-align: right; }
.clock-time { font-family: var(--num); font-size: 74px; line-height: 1; white-space: nowrap; }
/* Flip-clock digits: the new digit drops down from the top like a flap. */
.clock .dg { display: inline-block; }
.clock .fd { animation: flipDown 0.42s cubic-bezier(0.3, 0.7, 0.4, 1); transform-origin: 50% 0; }
.clock-date { font-size: 20px; font-weight: 600; color: var(--soft); margin-top: 4px; }

/* ---------- main ---------- */
/* Two full-height boards side by side, then the map column, with room between them. */
.main { display: grid; grid-template-columns: minmax(0, 1fr) 420px; grid-column-gap: 40px; min-height: 0; }
.boards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: minmax(0, 1fr); grid-column-gap: 40px; min-height: 0; }

/* Boards sit straight on the ground: only the leave panel and the pinned tiles are boxed. */
.board { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.board.card { background: transparent; border-radius: 0; }
.board-head { flex: 0 0 56px; display: flex; align-items: center; padding: 0 4px; }
/* The station ring from the map. */
.board-head .mark { flex: 0 0 auto; box-sizing: border-box; width: 24px; height: 24px; border-radius: 50%; background: var(--black); border: 5px solid var(--white); margin: 0 14px 0 0; }
.board-name { font-family: var(--head); font-size: 28px; text-transform: uppercase; letter-spacing: 0.02em; white-space: nowrap; }
.walk { margin-left: auto; padding-left: 16px; font-size: 19px; font-weight: 600; color: var(--soft); white-space: nowrap; }
.board-error { margin-left: auto; padding-left: 16px; color: var(--yellow); font-weight: 700; font-size: 19px; white-space: nowrap; }

/* The one thing people need: when to leave, and for which train. */
.leave { flex: 0 0 118px; margin: 4px 0 18px; border-radius: 4px; background: var(--accent); color: var(--black); display: flex; flex-direction: column; justify-content: center; padding: 0 26px; overflow: hidden; }
.leave-big { font-family: var(--num); font-size: 60px; line-height: 1; letter-spacing: 0.01em; text-transform: uppercase; white-space: nowrap; }
.leave-for { font-size: 21px; font-weight: 600; margin-top: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.leave-for b { font-weight: 800; }
.leave.now .leave-big { animation: pulse 1.6s ease-in-out infinite; }
/* Nothing you can still walk to: same space, quieter. */
.leave.none { background: transparent; border: 2px solid var(--line); color: var(--soft); }
.leave.none .leave-big { font-size: 36px; }

/* Pinned destinations (NEXT_TRAINS): the next two trains to each, at the foot of
   the board. The destination sits on the left, its trains stacked on the right. */
.next-to { flex: 0 0 auto; display: flex; }
.nt { flex: 1 1 0; min-width: 0; display: flex; align-items: center; padding: 8px 16px; border-radius: 4px; background: var(--panel); border-left: 4px solid var(--accent); }
.nt + .nt { margin-left: 12px; }
.nt-label { flex: 0 0 160px; min-width: 0; font-size: 16px; font-weight: 600; color: var(--soft); }
.nt-label b { display: block; margin-top: 2px; font-size: 23px; font-weight: 800; line-height: 1.12; color: var(--white); }
.nt-trains { flex: 1 1 0; min-width: 0; min-height: 89px; display: flex; flex-direction: column; justify-content: center; } /* room for two trains, so tiles line up across the boards */
.nt-row { display: flex; align-items: center; height: 44px; }
.nt-row + .nt-row { border-top: 1px solid var(--line); }
.nt .time { flex: 0 0 96px; font-family: var(--num); font-size: 32px; line-height: 1; }
.nt .time.late { color: var(--yellow); }
.nt .plat { min-width: 40px; height: 34px; margin-left: 12px; padding: 0 5px; display: flex; align-items: center; justify-content: center; border-radius: 3px; border: 2px solid rgba(208, 211, 212, 0.22); font-family: var(--num); font-size: 23px; }
/* Platform not announced yet: a quiet dash rather than a box. */
.nt .plat.tbc { border-color: transparent; font-size: 0; }
.nt .plat.tbc::after { content: '\2013'; font-size: 23px; color: var(--mid); }
.nt-arr { flex: 1 1 0; min-width: 0; margin-left: 16px; font-size: 19px; font-weight: 600; color: var(--soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nt .in { padding-left: 12px; font-size: 24px; font-weight: 700; color: var(--accent); white-space: nowrap; }
.nt-row + .nt-row .in { color: var(--soft); font-weight: 600; }
.nt-none { font-size: 20px; font-weight: 600; color: var(--soft); }
/* Two destinations to a board: each just shows its next train. */
.nt:not(:only-child) { display: block; }
.nt:not(:only-child) .nt-label b { display: inline; margin-left: 6px; font-size: 19px; }
.nt:not(:only-child) .nt-row + .nt-row, .nt:not(:only-child) .nt-arr { display: none; }

.rows { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 0 0 18px; }
/* Six trains with air between them, split by hairlines. */
.row { display: grid; grid-template-columns: 112px minmax(0, 1fr) 52px 92px; grid-column-gap: 16px; align-items: center; padding: 0 4px; height: 78px; position: relative; border-top: 1px solid rgba(208, 211, 212, 0.08); }
.row:first-child { border-top: 0; }
.row.enter { animation: rowIn 0.7s ease-out backwards; }
.row .time { font-family: var(--num); font-size: 35px; line-height: 1; }
.row .dest { min-width: 0; display: flex; align-items: baseline; }
.row .dest-name { flex: 0 1 auto; min-width: 0; font-size: 28px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* "+14", "Cancelled", "Bus": on the same line as the destination. */
.row .note { flex: 0 0 auto; margin-left: 10px; font-size: 19px; font-weight: 700; color: var(--yellow); white-space: nowrap; }
.row .note.bus { color: var(--light); }
.row .plat { justify-self: center; min-width: 48px; height: 42px; padding: 0 5px; display: flex; align-items: center; justify-content: center; border-radius: 3px; border: 2px solid var(--plat); font-family: var(--num); font-size: 28px; }
/* Platform not announced yet: a quiet dash rather than a box. */
.row .plat.tbc { border-color: transparent; font-size: 0; }
.row .plat.tbc::after { content: '\2013'; font-size: 28px; color: var(--mid); }
.row .in { text-align: right; font-size: 25px; font-weight: 600; color: var(--soft); white-space: nowrap; }

.row.is-late .time { color: var(--yellow); }
.row.is-cancelled .time, .row.is-cancelled .dest-name, .row.is-cancelled .plat, .row.is-cancelled .in { color: var(--mid); }
.row.is-cancelled .time, .row.is-cancelled .dest-name { text-decoration: line-through; }
.row.is-cancelled .plat { border-color: transparent; }
/* The train the leave panel is for, in the station colour. */
.row.catch .time, .row.catch .dest-name, .row.catch .in { color: var(--accent); }
.row.catch .in { font-weight: 700; }
.empty { padding: 30px 24px; font-size: 23px; color: var(--soft); }
.no-data { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; padding: 40px 48px; text-align: center; }
.no-data .nd-icon { width: 72px; height: 72px; margin-bottom: 24px; color: var(--accent); opacity: 0.8; }
.no-data .nd-icon svg { width: 100%; height: 100%; }
.no-data .nd-title { font-size: 34px; font-weight: 700; color: var(--light); line-height: 1.2; }
.no-data .nd-text { margin-top: 14px; max-width: 620px; font-size: 23px; line-height: 1.4; color: var(--soft); }

/* ---------- map + phone ---------- */
.side { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) 120px; grid-row-gap: 24px; min-height: 0; }
.map-card { display: flex; flex-direction: column; min-height: 0; }
.map-head { display: flex; align-items: center; justify-content: space-between; flex: 0 0 56px; padding: 0 22px; white-space: nowrap; }
.map-head .h-label { font-size: 15px; }
.map { flex: 1; min-height: 0; background: var(--black); }

.qr-card { display: flex; align-items: center; padding: 0 20px; white-space: nowrap; }
/* White tile, dark modules: scans reliably from a distance. */
.qr { flex: 0 0 96px; width: 96px; height: 96px; margin-right: 20px; background: var(--white); padding: 6px; border-radius: 4px; }
.qr img { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.qr-text { font-size: 21px; font-weight: 600; line-height: 1.3; }
.qr-text b { color: var(--yellow); font-weight: 600; white-space: nowrap; }

/* Recolour standard OSM tiles to sit on the dark brand palette. */
.tiles-dark { filter: invert(1) hue-rotate(180deg) saturate(0.25) brightness(0.72) contrast(1.15); }
.leaflet-container { background: var(--black); font-family: var(--body); }
.leaflet-control-attribution { background: rgba(16, 24, 32, 0.7) !important; color: var(--mid) !important; font-size: 10px !important; }
.leaflet-control-attribution a { color: var(--light) !important; }

.train { position: relative; }
/* Train badge: a train front on a disc in the station colour (yellow when late). */
.train .loco { z-index: 2; position: absolute; left: -12px; top: -12px; width: 24px; height: 24px; border-radius: 50%; background: var(--c); border: 2px solid var(--black); box-shadow: 0 0 0 2px var(--c), 0 2px 6px rgba(0, 0, 0, 0.5); color: var(--black); display: flex; align-items: center; justify-content: center; }
.train .loco svg { width: 16px; height: 16px; }
.train .ring { z-index: 1; position: absolute; left: -12px; top: -12px; width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--c); animation: ring 2.2s ease-out infinite; }
/* The label tucks in behind its dot so the two read as one marker. */
.train .tag { z-index: 0; position: absolute; left: 0; top: -11px; white-space: nowrap; background: rgba(16, 24, 32, 0.92); color: var(--white); font-size: 14px; font-weight: 700; padding: 3px 9px 3px 19px; border-radius: 0 3px 3px 0; }
.train .tag.late { color: var(--yellow); font-weight: 800; }

.hub { position: relative; }
.hub .sq { position: absolute; left: -9px; top: -9px; width: 18px; height: 18px; background: var(--c); border: 3px solid var(--black); transform: rotate(45deg); }
.hub .lbl { position: absolute; top: -13px; white-space: nowrap; font-family: var(--head); font-size: 12px; text-transform: uppercase; color: var(--white); background: rgba(16, 24, 32, 0.85); padding: 4px 7px; }
.hub .lbl.r { left: 16px; }
.hub .lbl.l { right: 16px; }

.town { white-space: nowrap; font-size: 12px; font-weight: 700; color: var(--soft); text-transform: uppercase; letter-spacing: 0.06em; text-shadow: 0 0 4px var(--black), 0 0 4px var(--black); position: absolute; left: 8px; top: -8px; }
.town.l { left: auto; right: 8px; }
.town.on { color: var(--white); }

/* Tube-style map: a fixed schematic with the train badges laid over it. */
.map.tube { position: relative; overflow: hidden; }
.tube-svg { position: absolute; left: 0; top: 0; width: 100%; height: 100%; }
.tube-svg .tl { fill: none; stroke-width: 5; stroke-linejoin: round; }
.tube-svg .tl.idle { stroke-width: 4; stroke-dasharray: 0.1 8; stroke-linecap: round; }
.tube-svg .tk { fill: none; stroke-width: 3; }
.tube-svg .xr { fill: var(--black); stroke: var(--white); stroke-width: 3; }
.tube-svg .xr.hub { stroke-width: 4.5; }
.tube-svg text { font-family: var(--body); }
.tube-svg .stn { font-size: 14px; font-weight: 600; fill: var(--soft); }
.tube-svg .stn.major { font-weight: 700; fill: var(--white); }
.tube-svg .term { font-size: 15px; font-weight: 700; fill: var(--white); }
.tube-svg .term.idle { fill: var(--mid); }
.tube-svg .hubl { font-size: 16px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; fill: var(--white); }
.tube-trains { position: absolute; left: 0; top: 0; right: 0; bottom: 0; }
.tube-train { position: absolute; width: 0; height: 0; transition: left 1s linear, top 1s linear; }

/* Live status and data credits, along the bottom of the map card. */
.map-foot { flex: 0 0 44px; display: flex; align-items: center; justify-content: space-between; padding: 0 16px; font-size: 12px; font-weight: 600; line-height: 1.35; color: var(--soft); white-space: nowrap; overflow: hidden; }
.status { flex: 0 0 auto; display: flex; align-items: center; margin-right: 12px; }
/* Live indicator: the same train badge as the map, pulsing (yellow when data is delayed). */
.status .dot { --c: var(--blue); flex: 0 0 18px; width: 18px; height: 18px; border-radius: 50%; background: var(--c); color: var(--black); display: flex; align-items: center; justify-content: center; margin-right: 8px; animation: pulse 2s ease-in-out infinite; }
.status .dot svg { width: 12px; height: 12px; }
.status.warn .dot { --c: var(--yellow); }
.status.warn { color: var(--yellow); }
.credit { min-width: 0; text-align: right; color: var(--mid); }

/* ---------- footer ---------- */
/* Service updates, full width, one message at a time over up to two lines:
   a label on the left, where it applies, the message, and which one of how many. */
.foot { min-width: 0; }
.ticker { height: 100%; position: relative; overflow: hidden; display: flex; align-items: stretch; border-radius: 4px; background: var(--panel); border-left: 4px solid var(--yellow); }
.tk-label { flex: 0 0 auto; display: flex; align-items: center; padding: 0 26px 0 20px; border-right: 1px solid var(--line); font-family: var(--head); font-size: 15px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--yellow); white-space: nowrap; }
.tk-label svg { width: 34px; height: 34px; margin-right: 14px; }
.tk-body { flex: 1 1 auto; min-width: 0; height: 56px; margin: auto 0; padding: 0 26px; overflow: hidden; display: flex; align-items: center; }
.tk-body.long { align-items: flex-start; }
.tk-item { width: 100%; font-size: 21px; font-weight: 600; line-height: 28px; color: var(--light); transform-origin: 50% 0; }
.tk-item b { font-weight: 800; color: var(--white); }
.tk-tag { display: inline-block; vertical-align: 2px; margin-right: 12px; padding: 0 10px; height: 28px; line-height: 28px; border-radius: 3px; border: 1.5px solid var(--soft); font-size: 16px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: var(--light); }
.tk-tag.hot { border: 0; background: var(--yellow); color: var(--black); }
/* Each message drops down into view like a flap. */
.tk-in { animation: flipDown 0.5s cubic-bezier(0.3, 0.7, 0.4, 1); }
/* One dot per message (or "2/12" when there are lots). */
.tk-dots { flex: 0 0 auto; display: flex; align-items: center; padding: 0 24px 0 8px; font-family: var(--num); font-size: 22px; color: var(--soft); }
.tk-dots i { width: 12px; height: 12px; margin-left: 9px; border-radius: 50%; background: var(--plat); }
.tk-dots i.on { background: var(--yellow); }
/* Nothing to report: the same band, calm. */
.ticker.good { border-left-color: var(--blue); }
.ticker.good .tk-label { color: var(--blue); }
.ticker.good .tk-item { color: var(--soft); }

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
@keyframes ring { 0% { transform: scale(1); opacity: 0.9; } 100% { transform: scale(3.2); opacity: 0; } }
@keyframes rowIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* A platform, time or status that changes flips over. */
.flip { animation: flip 0.45s ease-in-out 2; transform-origin: 50% 50%; }
@keyframes flip { 0% { transform: perspective(240px) rotateX(0); } 50% { transform: perspective(240px) rotateX(-90deg); } 100% { transform: perspective(240px) rotateX(0); } }
@keyframes flipDown { 0% { transform: perspective(300px) rotateX(85deg); opacity: 0.3; } 100% { transform: perspective(300px) rotateX(0); opacity: 1; } }
/* Loading: a train on a stretch of track. */
.track-loader { display: flex; align-items: center; }
.track-loader span { margin-left: 18px; }
.track { position: relative; width: 260px; height: 26px; overflow: hidden; }
.track .rails { position: absolute; left: 0; right: 0; top: 50%; height: 10px; margin-top: -5px; border-top: 2px solid rgba(208, 211, 212, 0.35); border-bottom: 2px solid rgba(208, 211, 212, 0.35); background: repeating-linear-gradient(90deg, rgba(208, 211, 212, 0.22) 0 3px, transparent 3px 12px); }
.track .loco { --c: var(--blue); position: absolute; top: 1px; left: -30px; width: 24px; height: 24px; border-radius: 50%; background: var(--c); color: var(--black); display: flex; align-items: center; justify-content: center; animation: run 2.6s linear infinite; }
.track .loco svg { width: 16px; height: 16px; }
@keyframes run { from { transform: translateX(0); } to { transform: translateX(300px); } }

/* ---------- phone app reminder ---------- */
/* Covers the whole stage for a short while, every so often (see showPromo in app.js). */
.promo { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; z-index: 50; background: rgba(16, 24, 32, 0.94); display: flex; align-items: center; justify-content: center; opacity: 0; visibility: hidden; transition: opacity 0.6s ease, visibility 0s linear 0.6s; }
.promo.show { opacity: 1; visibility: visible; transition: opacity 0.6s ease; }
.promo-card { position: relative; width: 1600px; height: 900px; background: var(--panel); border-radius: 10px; display: flex; overflow: hidden; }
/* A soft blue glow behind the phone. */
.promo-card::after { content: ''; position: absolute; right: -160px; top: 50%; width: 900px; height: 900px; margin-top: -450px; border-radius: 50%; background: radial-gradient(closest-side, rgba(44, 204, 211, 0.22), rgba(44, 204, 211, 0)); }

.promo-copy { flex: 1 1 auto; padding: 72px 30px 64px 90px; display: flex; flex-direction: column; }
.promo-kicker { color: var(--blue); font-size: 20px; }
.promo-title { margin-top: 22px; font-family: var(--head); font-size: 60px; line-height: 1.05; text-transform: uppercase; }
.promo-feats { margin-top: 44px; }
.promo-feat { display: flex; align-items: flex-start; margin-bottom: 28px; }
.promo-num { flex: 0 0 52px; height: 52px; margin-right: 26px; border-radius: 50%; background: var(--blue); color: var(--black); font-family: var(--num); font-size: 28px; display: flex; align-items: center; justify-content: center; }
.promo-feat b { display: block; font-size: 32px; font-weight: 700; }
.promo-feat span { display: block; margin-top: 6px; font-size: 23px; color: var(--soft); line-height: 1.3; max-width: 620px; }
.promo-scan { margin-top: auto; display: flex; align-items: center; padding-top: 30px; border-top: 1px solid var(--line); }
.promo-qr { flex: 0 0 180px; width: 180px; height: 180px; margin-right: 34px; background: var(--white); padding: 10px; border-radius: 6px; }
.promo-qr img { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.promo-scan-title { font-family: var(--head); font-size: 30px; text-transform: uppercase; color: var(--yellow); }
.promo-scan-sub { margin-top: 10px; font-size: 23px; color: var(--light); line-height: 1.3; max-width: 470px; }

/* The phone: a hand-built mock-up of /m/, in the same styling. */
.promo-phone { position: relative; z-index: 1; flex: 0 0 560px; display: flex; align-items: center; justify-content: center; }
.phone { position: relative; width: 390px; height: 790px; border-radius: 58px; background: #05080B; padding: 14px; box-shadow: 0 0 0 2px #3A434C, 0 40px 80px rgba(0, 0, 0, 0.55); transform: rotate(-3deg); }
.phone-notch { position: absolute; left: 50%; top: 26px; width: 110px; height: 32px; margin-left: -55px; border-radius: 16px; background: #05080B; z-index: 3; }
.phone-screen { position: relative; width: 100%; height: 100%; border-radius: 45px; background: var(--black); overflow: hidden; padding: 0 20px; }
.ph-status { display: flex; justify-content: space-between; align-items: center; height: 56px; padding: 6px 14px 0; font-size: 15px; font-weight: 600; }
.ph-bars { width: 26px; height: 12px; border: 2px solid var(--white); border-radius: 4px; position: relative; }
.ph-bars::after { content: ''; position: absolute; left: 2px; top: 2px; bottom: 2px; width: 12px; background: var(--white); border-radius: 1px; }
.ph-top { display: flex; align-items: center; margin: 6px 0 14px; }
.ph-top img { width: 40px; height: auto; margin-right: 12px; }
.ph-brand { font-family: var(--head); font-size: 18px; text-transform: uppercase; }
.ph-sub { font-size: 12px; color: var(--soft); margin-top: 2px; }
.ph-journey { background: var(--panel); border-radius: 10px; padding: 14px 16px 12px; }
.ph-route { font-family: var(--num); font-size: 22px; text-transform: uppercase; display: flex; align-items: center; line-height: 1.15; }
.ph-dot { width: 12px; height: 12px; border: 3px solid var(--blue); border-radius: 50%; margin: 0 12px 0 2px; }
.ph-arrow { font-style: normal; color: var(--blue); width: 16px; margin-right: 10px; font-family: var(--body); font-size: 18px; }
.ph-walk { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); font-size: 13px; color: var(--soft); }
.ph-leave { margin-top: 12px; background: var(--blue); color: var(--black); border-radius: 10px 10px 0 0; padding: 12px 16px 10px; font-family: var(--num); font-size: 32px; text-transform: uppercase; white-space: nowrap; }
.ph-train { background: var(--panel); border-radius: 0 0 10px 10px; padding: 12px 16px 14px; }
.ph-next { font-family: var(--head); font-size: 10px; letter-spacing: 0.06em; white-space: nowrap; text-transform: uppercase; color: var(--light); }
.ph-row { display: flex; justify-content: space-between; align-items: flex-end; margin-top: 4px; }
.ph-time { font-family: var(--num); font-size: 60px; line-height: 1; }
.ph-plat { text-align: center; }
.ph-plat span { display: block; font-family: var(--head); font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--soft); margin-bottom: 4px; }
.ph-plat b { display: block; width: 50px; height: 50px; line-height: 50px; border-radius: 6px; background: var(--white); color: var(--black); font-family: var(--num); font-size: 30px; }
.ph-plat b.is-tbc { background: none; border: 2px dashed var(--mid); color: var(--soft); font-size: 15px; line-height: 46px; }
.ph-op { margin-top: 8px; font-size: 14px; color: var(--light); }
.ph-late { margin-top: 6px; font-size: 15px; font-weight: 700; color: var(--yellow); }
.ph-late.is-ok { color: var(--blue); }
.ph-late.is-cancelled { color: var(--yellow); }
.ph-time.is-cancelled { text-decoration: line-through; color: var(--soft); }
.ph-stops { position: relative; margin-top: 14px; padding-left: 4px; }
.ph-stops::before { content: ''; position: absolute; left: 66px; top: 15px; bottom: 15px; width: 4px; background: var(--blue); border-radius: 2px; }
.ph-stop { position: relative; display: flex; align-items: center; height: 30px; font-size: 15px; color: var(--light); }
.ph-stop span { width: 48px; margin-right: 34px; font-family: var(--num); font-size: 15px; color: var(--soft); }
.ph-stop::before { content: ''; position: absolute; left: 66px; top: 50%; width: 10px; height: 4px; margin-top: -2px; background: var(--blue); }
.ph-stop.is-end { font-family: var(--num); text-transform: uppercase; color: var(--white); }
.ph-stop.is-end span { color: var(--white); }
.ph-stop.is-end::before { left: 58px; width: 14px; height: 14px; margin-top: -10px; border: 3px solid var(--blue); border-radius: 50%; background: var(--black); }

.ph-later { margin-top: 16px; background: var(--panel); border-radius: 10px; padding: 12px 16px 4px; }
.ph-later-row { display: flex; align-items: center; height: 36px; border-top: 1px solid var(--line); font-size: 15px; }
.ph-next + .ph-later-row { margin-top: 8px; }
.ph-later-row b { width: 64px; font-family: var(--num); font-size: 19px; font-weight: 700; }
.ph-later-row span { flex: 1 1 auto; color: var(--light); }
.ph-later-row i { font-style: normal; font-size: 13px; color: var(--blue); }
.ph-later-row i.is-late { color: var(--yellow); }

/* The delay alert drops in from the top a moment after the reminder appears. */
.ph-alert { position: absolute; left: -46px; right: -46px; top: 74px; z-index: 4; display: flex; align-items: flex-start; padding: 16px 18px; border-radius: 22px; background: rgba(236, 239, 241, 0.97); color: var(--black); box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45); opacity: 0; transform: translateY(-40px) scale(0.96); }
.promo.show .ph-alert { animation: alertIn 0.7s cubic-bezier(0.2, 0.9, 0.3, 1.15) 1.6s forwards; }
.ph-alert img { width: 44px; height: 44px; border-radius: 10px; margin-right: 14px; }
.ph-alert > div { flex: 1 1 auto; }
.ph-alert-head { display: flex; justify-content: space-between; font-size: 14px; color: #4A535B; }
.ph-alert-head b { font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.ph-alert-title { margin-top: 3px; font-size: 19px; font-weight: 700; }
.ph-alert-body { margin-top: 2px; font-size: 16px; color: #2A3139; }
@keyframes alertIn { to { opacity: 1; transform: none; } }

