/* PULSE: a full-size map with compact control surfaces, in the Better Places
   Lab house style (TEAM's team.css, section for section). Interface colours
   are here; data colours live in js/palette.js and repeat here only as the
   --mode-* tokens that labels, chips and keys use.
   Feature styles go in now.css, trends.css, network.css and anim.css. */

:root {
  color-scheme: light;
  --navy: #0c0c48;
  --ink: #15252e;
  --ink-soft: #3b4d56;
  --muted: #55646c;
  --paper: #f7f3ea;
  --surface: #ffffff;
  --wash: #f3f4f1;
  --line: rgba(18, 52, 67, 0.14);
  --line-strong: rgba(18, 52, 67, 0.28);
  --accent: #1f6178;            /* links, text buttons, focus ring (house teal) */
  --track: #ecebe6;
  --bar: #2a78d6;
  --radius: 14px;
  --shadow: 0 6px 24px rgba(12, 12, 72, 0.12);
  --shadow-soft: 0 2px 12px rgba(12, 12, 72, 0.08);
  --font: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  /* PULSE's own accent: heartbeat red. Sparingly: the mark, the active tab,
     the "now" marker, the current-year line. Never a data category. */
  --pulse: #c8102e;
  --pulse-wash: #fbe7ea;
  --pulse-ink: #9b0c23;

  /* Mode colours (js/palette.js MODE_COLOURS; each ≥ 4.5:1 on white). */
  --mode-cycle: #0e7490;
  --mode-walk: #b45309;
  --mode-bus: #1d4ed8;
  --mode-train: #0c0c48;
  --mode-ferry: #86198f;
  --mode-pt: #1d4ed8;

  /* Counted, estimated, live, scheduled: the four kinds of number. */
  --counted-bg: #dbe8f8;
  --counted-fg: #184f95;
  --estimated-bg: #fff6e0;
  --estimated-fg: #7a4600;
  --estimated-line: #c99a3d;
  --live-bg: #ddf1e6;
  --live-fg: #145c3e;
  --live-dot: #1a7f5a;
  --scheduled-bg: #ecebe6;
  --scheduled-fg: #3b4d56;

  --panel-w: 364px;
  --card-w: 340px;
  --sheet-h: 0px;
  --inset: max(12px, env(safe-area-inset-left));
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: #e6e6e3;
  color: var(--ink);
  font: 14px/1.45 var(--font);
  -webkit-font-smoothing: antialiased;
}
[hidden] { display: none !important; }
button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; touch-action: manipulation; }
a { color: var(--accent); }
a:hover { color: var(--navy); }
abbr[title] { text-decoration: none; cursor: help; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* A table grows to fit its rows whatever its height, so block it to keep the 1px box. */
table.visually-hidden { display: block; }
.skip-link { position: absolute; top: -60px; left: 12px; z-index: 50; padding: 8px 12px; background: var(--navy); color: #fff; border-radius: 0 0 8px 8px; text-decoration: none; }
.skip-link:focus { top: 0; color: #fff; }
.noscript { position: absolute; top: 40%; left: 50%; z-index: 60; max-width: 340px; padding: 14px 16px; background: #fff; border-radius: 10px; box-shadow: var(--shadow); transform: translateX(-50%); }

#map { position: absolute; inset: 0; }
body[data-map="none"] #map { background: repeating-linear-gradient(135deg, #e6e6e3 0 14px, #e0e0dc 14px 28px); }

/* ------------------------------------------------------------------ panel */

.panel {
  position: absolute;
  top: max(12px, env(safe-area-inset-top));
  left: max(12px, env(safe-area-inset-left));
  z-index: 10;
  display: flex;
  flex-direction: column;
  width: var(--panel-w);
  max-height: calc(100% - 24px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
/* The skip link's target: a mouse click inside draws no ring (STAND). */
.panel:focus, .view:focus, .place:focus { outline: none; }
.panel:focus-visible, .place:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: var(--radius); }
.brand { display: flex; align-items: center; gap: 8px; padding: 14px 12px 12px 14px; border-bottom: 1px solid var(--line); }
.brand-mark { flex: 0 0 auto; width: 36px; height: 36px; }
.brand-text { flex: 1 1 auto; min-width: 0; }
.brand h1 { margin: 0; color: var(--navy); font-size: 22px; font-weight: 800; letter-spacing: 0.08em; line-height: 1; }
.brand p { margin: 3px 0 0; font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The tagline is a sentence, not the expansion (that is in the abbr), so it
   wraps rather than lose its end (STAND), even with wider text spacing. */
.brand .tagline { color: var(--muted); line-height: 1.3; white-space: normal; text-wrap: balance; }
/* The key number when the panel is folded: allowed two lines. */
.brand .mini {
  display: none;
  color: var(--navy);
  font-weight: 600;
  white-space: normal;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
body[data-panel="collapsed"] .brand .tagline { display: none; }
body[data-panel="collapsed"] .brand .mini { display: -webkit-box; }
body[data-panel="collapsed"] .brand { border-bottom: 0; }
.text-button { padding: 6px 4px; border: 0; background: none; color: var(--accent); font-size: 13px; font-weight: 600; }
.text-button:hover { color: var(--navy); text-decoration: underline; }
.icon-button { display: inline-grid; flex: none; place-items: center; width: 34px; height: 34px; padding: 0; border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--muted); }
.icon-button:hover { background: var(--wash); color: var(--navy); }
.panel-toggle svg { transition: transform 160ms ease; }
body[data-panel="collapsed"] .panel-toggle svg { transform: rotate(180deg); }
body[data-panel="collapsed"] .panel-body, body[data-panel="collapsed"] .panel-foot { display: none; }

.panel-body { display: flex; flex-direction: column; gap: 14px; min-height: 0; padding: 12px 14px 8px; overflow-y: auto; overscroll-behavior: contain; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field-head { display: flex; align-items: baseline; gap: 8px; }
.field-label { color: var(--muted); font-size: 12px; font-weight: 600; letter-spacing: 0.01em; }
.field-value { color: var(--navy); font-size: 13px; font-weight: 700; }
.field-head .text-button { margin-left: auto; font-size: 12px; }
input[type="range"] { width: 100%; accent-color: var(--navy); }

/* Chips: the primary picker. Mode chips carry the mode's colour as a dot,
   so the colour is learned here before it is met on the map. */
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 5px 11px; border: 1px solid var(--line-strong); border-radius: 999px; background: #fff; color: var(--ink); font-size: 13px; font-weight: 500; white-space: nowrap; }
.chip:hover { border-color: var(--navy); }
.chip[aria-checked="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }
.chips-compact .chip { min-height: 30px; padding: 4px 10px; font-size: 12.5px; }
.modes { gap: 4px; }
.modes .chip { min-height: 30px; padding: 4px 8px; gap: 5px; font-size: 12.5px; }
.chip-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--dot, var(--navy)); }
.chip-dot.is-all { display: none; }
.chip[aria-checked="true"] .chip-dot { box-shadow: 0 0 0 1.5px #fff; }

/* Tabs: three equal columns; the active one is underlined in the PULSE red. */
.tabs { display: grid; grid-template-columns: repeat(3, 1fr); margin: 0 -14px; padding: 0 8px; border-bottom: 1px solid var(--line); }
.tabs button { min-height: 42px; padding: 8px 6px; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; background: none; color: var(--muted); font-size: 13px; font-weight: 600; white-space: nowrap; }
.tabs button[aria-selected="true"] { border-bottom-color: var(--pulse); color: var(--navy); }
.tabs button:hover { color: var(--navy); }
.tabs button:focus-visible { outline-offset: -3px; }

.view { display: flex; flex-direction: column; gap: 14px; }
.view[aria-busy="true"] { min-height: 120px; }

/* Hero: the number first, then one plain sentence. */
.hero { display: flex; flex-direction: column; }
.hero-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 6px; }
.hero-label { color: var(--muted); font-size: 12px; font-weight: 600; }
.hero-figure { color: var(--navy); font-size: 48px; font-weight: 700; letter-spacing: -0.02em; line-height: 1; }
.hero-text { margin: 6px 0 0; font-size: 15px; line-height: 1.4; }
.hero-sub { margin: 6px 0 0; color: var(--ink-soft); font-size: 13px; }
.note { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.45; }
.notice { margin: 0; padding: 9px 11px; background: #fff6e0; border: 1px solid #e9cf8c; border-radius: 10px; color: var(--ink); font-size: 12.5px; line-height: 1.45; }
.notice strong { color: var(--ink); }

/* Counted / estimated / live / scheduled. Solid for counted, dashed for estimated. */
.badge { display: inline-flex; align-items: center; gap: 4px; padding: 0 7px; border: 1px solid transparent; border-radius: 999px; font-size: 11px; font-weight: 700; line-height: 17px; letter-spacing: 0.01em; white-space: nowrap; vertical-align: 1px; }
.badge.is-counted { background: var(--counted-bg); color: var(--counted-fg); }
.badge.is-estimated { background: var(--estimated-bg); color: var(--estimated-fg); border: 1px dashed var(--estimated-line); }
.badge.is-live { background: var(--live-bg); color: var(--live-fg); }
.badge.is-live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--live-dot); animation: live-dot 2s ease-in-out infinite; }
.badge.is-scheduled { background: var(--scheduled-bg); color: var(--scheduled-fg); }
.badge.is-scheduled::before { content: ""; width: 6px; height: 6px; border: 1.5px solid currentColor; border-radius: 50%; }
.badge.is-replay { background: var(--pulse-wash); color: var(--pulse-ink); }
.badge.is-assumed { background: #fff; color: var(--ink-soft); border: 1px dashed var(--line-strong); }
@keyframes live-dot { 50% { opacity: 0.35; } }

/* A titled block with a hairline above it. */
.block { display: flex; flex-direction: column; gap: 8px; padding-top: 12px; border-top: 1px solid var(--line); }
.block-title { margin: 0; color: var(--navy); font-size: 13px; font-weight: 700; }

/* Weather and other factors: small quiet chips. */
.factor-row { display: flex; flex-wrap: wrap; gap: 5px; }
.factor { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border: 1px solid var(--line); border-radius: 999px; background: var(--wash); color: var(--ink-soft); font-size: 12px; font-variant-numeric: tabular-nums; }

/* Nothing to show (yet): say so plainly. */
.empty { display: flex; flex-direction: column; gap: 3px; padding: 14px 12px; border: 1px dashed var(--line-strong); border-radius: 10px; background: var(--wash); text-align: center; }
.empty strong { color: var(--navy); font-size: 13px; }
.empty span { color: var(--muted); font-size: 12px; line-height: 1.45; }
.loading-line { margin: 0; color: var(--muted); font-size: 12.5px; }
.loading-line::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 8px; border: 2px solid var(--track); border-top-color: var(--navy); border-radius: 50%; vertical-align: -1px; animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.legend { display: flex; flex-direction: column; gap: 6px; }
.legend-title { color: var(--muted); font-size: 12px; font-weight: 600; }
.legend-scale { display: grid; gap: 2px; }
.legend-step { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.legend-swatch-step { display: block; height: 12px; }
.legend-step:first-child .legend-swatch-step { border-radius: 3px 0 0 3px; }
.legend-step:last-child .legend-swatch-step { border-radius: 0 3px 3px 0; }
.legend-scale.is-dashed .legend-swatch-step { -webkit-mask: repeating-linear-gradient(90deg, #000 0 7px, transparent 7px 10px); mask: repeating-linear-gradient(90deg, #000 0 7px, transparent 7px 10px); }
.legend-label { color: var(--muted); font-size: 11px; line-height: 1.2; font-variant-numeric: tabular-nums; }
.legend-note { color: var(--muted); font-size: 11px; }

.check { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; cursor: pointer; }
.check input { flex: none; width: 16px; height: 16px; margin: 2px 0 0; accent-color: var(--navy); }
.check-text { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; white-space: normal; }
.check-note { flex-basis: 100%; color: var(--muted); font-size: 11.5px; }
.check input:disabled + .check-text { color: var(--muted); }

/* Method notes: a line anyone can open, and most people will not. */
.method { margin: 8px 0 2px; border-top: 1px solid var(--line); padding-top: 8px; }
.method > summary { display: flex; gap: 7px; align-items: center; min-height: 24px; cursor: pointer; color: var(--muted); font-size: 12px; list-style: none; }
.method > summary::-webkit-details-marker { display: none; }
.method > summary:hover { color: var(--accent); }
.method-mark { display: inline-grid; place-items: center; width: 15px; height: 15px; flex: none; border: 1px solid currentColor; border-radius: 50%; font-size: 10px; font-style: italic; font-weight: 700; line-height: 1; }
.method[open] > summary { color: var(--ink); font-weight: 600; }
.method-text { margin: 8px 0 0; color: var(--ink-soft); font-size: 12px; line-height: 1.5; }

.panel-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 2px 10px; padding: 9px 14px; border-top: 1px solid var(--line); color: var(--muted); font-size: 11.5px; }
.lab-link { display: inline-flex; align-items: center; gap: 6px; min-height: 24px; color: var(--navy); font-weight: 600; text-decoration: none; white-space: nowrap; }
.lab-link:hover { color: var(--navy); text-decoration: underline; }
.share-button { flex: 0 0 auto; margin-left: auto; font-size: 12px; }
.foot-note { flex: 1 0 100%; font-size: 11px; line-height: 1.4; }

/* ------------------------------------------------------------------ detail card */

.place {
  position: absolute;
  top: calc(max(12px, env(safe-area-inset-top)) + 52px);
  right: max(12px, env(safe-area-inset-right));
  z-index: 11;
  display: flex;
  flex-direction: column;
  width: var(--card-w);
  max-height: calc(100% - 118px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.place-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 14px 14px 10px; border-bottom: 1px solid var(--line); }
.eyebrow { margin: 0 0 2px; color: var(--accent); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.place-head h2 { margin: 0; color: var(--navy); font-size: 18px; line-height: 1.2; }
.place-sub { margin: 4px 0 0; color: var(--muted); font-size: 12px; }
.place-body { display: flex; flex-direction: column; padding: 4px 14px 14px; overflow-y: auto; overscroll-behavior: contain; }
.place-body > .empty { margin-top: 12px; }
.place-section { padding: 12px 0; border-bottom: 1px solid var(--line); }
.place-section:last-child { border-bottom: 0; }
.place-section h3 { margin: 0 0 8px; font-size: 13px; }
.kv { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 3px 0; font-size: 12.5px; }
.kv-key { color: var(--ink-soft); }
.kv-value { text-align: right; font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ map tools */

/* The tools row is as tall as its tallest child (the open key), so the row
   itself lets the pointer through to the map; only its children take it. */
.map-tools { position: absolute; top: max(12px, env(safe-area-inset-top)); right: max(12px, env(safe-area-inset-right)); z-index: 12; display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: flex-start; gap: 8px; max-width: calc(100% - var(--panel-w) - 48px); pointer-events: none; }
.map-tools > * { pointer-events: auto; }
.segmented { display: inline-flex; padding: 3px; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow-soft); }
.segmented button { min-height: 30px; padding: 4px 10px; border: 0; border-radius: 7px; background: none; color: var(--ink-soft); font-size: 12.5px; font-weight: 600; }
.segmented button:hover { color: var(--navy); background: var(--wash); }
.segmented button[aria-pressed="true"] { background: var(--navy); color: #fff; }
.layers { position: relative; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow-soft); }
/* The list drops down over the map rather than pushing the tools row down. */
.layers[open] { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.layers summary { display: flex; align-items: center; gap: 6px; min-height: 36px; padding: 8px 12px; color: var(--ink-soft); font-size: 12.5px; font-weight: 600; list-style: none; cursor: pointer; }
.layers summary::-webkit-details-marker { display: none; }
.layers summary::after { content: ""; width: 7px; height: 7px; margin: -3px 0 0 2px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); }
.layers[open] summary::after { margin-top: 3px; transform: rotate(225deg); }
.layers summary:hover { color: var(--navy); }
.layer-list { position: absolute; top: calc(100% - 1px); right: -1px; z-index: 2; display: flex; flex-direction: column; gap: 10px; width: 260px; max-height: min(75vh, 620px); padding: 10px 12px 12px; overflow-y: auto; border: 1px solid var(--line); border-radius: 10px 0 10px 10px; box-shadow: var(--shadow);
  /* A shade at the top or bottom edge while there is more to scroll to there. */
  background:
    linear-gradient(#fff 30%, rgba(255, 255, 255, 0)) top / 100% 28px no-repeat local,
    linear-gradient(rgba(255, 255, 255, 0), #fff 70%) bottom / 100% 28px no-repeat local,
    radial-gradient(farthest-side at 50% 0, rgba(12, 12, 72, 0.16), transparent) top / 100% 12px no-repeat scroll,
    radial-gradient(farthest-side at 50% 100%, rgba(12, 12, 72, 0.16), transparent) bottom / 100% 12px no-repeat scroll,
    #fff; }
.layer-group { display: flex; flex-direction: column; gap: 7px; min-width: 0; margin: 0; padding: 0; border: 0; }
.layer-group-title { margin-bottom: 2px; padding: 0; color: var(--muted); font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }
.layer-empty { margin: 0; color: var(--muted); font-size: 12px; }

/* A key that fills itself from whatever layers are switched on (TEAM). It
   folds like Layers: open on a desktop, closed on a phone, and it scrolls
   rather than running under the time bar. With a detail card open it stands
   left of the card (and app.js folds it when there is no room for that). */
.map-key { flex: 0 0 auto; max-width: 230px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); box-shadow: var(--shadow-soft); }
.map-key-summary { display: flex; align-items: center; gap: 6px; min-height: 36px; padding: 8px 12px; color: var(--ink-soft); font-size: 12.5px; font-weight: 600; list-style: none; cursor: pointer; }
.map-key-summary::-webkit-details-marker { display: none; }
.map-key-summary::after { content: ""; width: 7px; height: 7px; margin: -3px 0 0 2px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); }
.map-key[open] > .map-key-summary { min-height: 30px; padding-bottom: 4px; }
.map-key[open] > .map-key-summary::after { margin-top: 3px; transform: rotate(225deg); }
.map-key-summary:hover { color: var(--navy); }
.map-key-body { display: grid; gap: 5px; max-height: calc(100dvh - 170px); padding: 2px 11px 10px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
@media (min-width: 761px) {
  body[data-place="open"] .map-key { margin-right: calc(var(--card-w) + 8px); }
}
.map-key.is-tucked { visibility: hidden; }
.key-title { margin-top: 3px; color: var(--muted); font-size: 11px; font-weight: 700; }
.key-title:first-child { margin-top: 0; }
/* A heading with a badge ({title, badge} rows): the badge sits at the right. */
.key-title.has-badge { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.key-title .badge { padding: 0 6px; font-size: 10px; font-weight: 700; line-height: 15px; }
.key-row { display: flex; gap: 8px; align-items: center; }
.key-label { color: var(--ink-soft); font-size: 12px; line-height: 1.3; }
.key-swatch { flex: none; }
.key-line { width: 18px; height: 0; border-top: 3px solid var(--swatch); border-radius: 2px; }
.key-dash { width: 18px; height: 0; border-top: 2px dashed var(--swatch); }
.key-dot { width: 9px; height: 9px; margin: 0 4.5px; border-radius: 50%; background: var(--swatch); }
.key-ring { width: 10px; height: 10px; margin: 0 4px; border: 1.5px solid var(--swatch); border-radius: 50%; background: #fff; }
.key-ramp { width: 28px; height: 8px; border-radius: 2px; background: var(--ramp, var(--swatch)); }
.key-bar { width: 12px; height: 10px; margin: 0 3px; border-radius: 2px; background: var(--swatch); }
.key-pulse { position: relative; width: 9px; height: 9px; margin: 0 4.5px; border-radius: 50%; background: var(--swatch); }
.key-pulse::after { content: ""; position: absolute; inset: -4px; border: 1.5px solid var(--swatch); border-radius: 50%; opacity: 0; animation: key-pulse 1.6s ease-out infinite; }
@keyframes key-pulse { 0% { transform: scale(0.5); opacity: 0.8; } 100% { transform: scale(1.3); opacity: 0; } }
.key-vehicle { width: 12px; height: 7px; margin: 0 3px; border-radius: 2px; background: var(--swatch); box-shadow: 0 0 0 1px #fff; }

.tooltip { position: absolute; top: 0; left: 0; z-index: 30; display: flex; flex-direction: column; gap: 1px; max-width: 260px; padding: 8px 10px; background: rgba(12, 12, 72, 0.94); color: #fff; border-radius: 8px; font-size: 12px; pointer-events: none; font-variant-numeric: tabular-nums; }
.tooltip strong { font-size: 12.5px; }
.tooltip-hint { margin-top: 3px; color: rgba(255, 255, 255, 0.72); font-size: 11.5px; }

/* Waiting for the map: a pill above the time bar, in the open map. */
.loading { position: absolute; left: calc((var(--panel-w) + 24px + 100%) / 2); bottom: 96px; z-index: 40; padding: 10px 14px; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); transform: translateX(-50%); font-size: 13px; white-space: nowrap; }

/* The time bar slot, bottom centre of the open map (filled by js/anim/timebar.js). */
.timebar {
  position: absolute;
  left: calc((var(--panel-w) + 24px + 100%) / 2);
  bottom: max(20px, calc(env(safe-area-inset-bottom) + 12px));
  z-index: 12;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100% - var(--panel-w) - 120px);
  min-height: 40px;
  padding: 6px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
  transform: translateX(-50%);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.timebar:empty { display: none; }
/* Trends is monthly and daily: no clock, so no time bar, card open or not
   (the id outranks the time bar's own layout rules in anim.css). */
body[data-view="trends"] #timebar { display: none; }
body[data-panel="collapsed"] .timebar, body[data-panel="collapsed"] .loading { left: 50%; }
.timebar-clock { color: var(--navy); font-weight: 600; white-space: nowrap; }

/* MapLibre controls in the house size; the scale sits right of the panel (STAND). */
.maplibregl-ctrl-bottom-right { bottom: env(safe-area-inset-bottom); }
.maplibregl-ctrl-bottom-left { left: calc(max(12px, env(safe-area-inset-left)) + var(--panel-w)); }
body[data-panel="collapsed"] .maplibregl-ctrl-bottom-left { left: 0; }
/* On narrower desktops the centred time bar reaches the scale bar's corner:
   lift the scale above it (--timebar-h is 0px while the bar is hidden). */
@media (min-width: 761px) and (max-width: 1279px) {
  body:not([data-view="trends"]) .maplibregl-ctrl-bottom-left { bottom: calc(var(--timebar-h, 50px) + 30px); }
}
/* While the time bar shows (not in Trends; with a card open it stands left of
   the card instead), the zoom buttons and credits stand above it, and the open
   key still stops above the zoom buttons. The bar is one to three rows tall:
   js/anim/timebar.js puts its height in --timebar-h (0px while hidden); the
   fallbacks are its one- and two-row heights. */
@media (min-width: 761px) {
  body:not([data-view="trends"]):not([data-place="open"]) .maplibregl-ctrl-bottom-right { bottom: calc(max(20px, calc(env(safe-area-inset-bottom) + 12px)) + var(--timebar-h, 50px)); }
  body:not([data-view="trends"]):not([data-place="open"]) .map-key-body { max-height: calc(100dvh - 190px - var(--timebar-h, 50px)); }
}
@media (min-width: 761px) and (max-width: 1180px) {
  body:not([data-view="trends"]):not([data-place="open"]) .maplibregl-ctrl-bottom-right { bottom: calc(max(20px, calc(env(safe-area-inset-bottom) + 12px)) + var(--timebar-h, 86px)); }
  body:not([data-view="trends"]):not([data-place="open"]) .map-key-body { max-height: calc(100dvh - 190px - var(--timebar-h, 86px)); }
}
/* Under about 1000px the map tools wrap and the key starts a row lower. */
@media (min-width: 761px) and (max-width: 1023px) {
  body:not([data-view="trends"]):not([data-place="open"]) .map-key-body { max-height: calc(100dvh - 240px - var(--timebar-h, 86px)); }
  body[data-view="trends"]:not([data-place="open"]) .map-key-body { max-height: calc(100dvh - 220px); }
}
/* With a card open on a desktop, the card covers the right edge, so the zoom
   buttons stand just left of it (the credits stay below it), above the time
   bar beside the card; the open key stops above them (app.js folds it where
   even that does not fit). */
@media (min-width: 761px) {
  body[data-place="open"] .maplibregl-ctrl-bottom-right .maplibregl-ctrl-group { margin-right: calc(var(--card-w) + 22px); }
  body[data-place="open"]:not([data-view="trends"]) .maplibregl-ctrl-bottom-right .maplibregl-ctrl-group { margin-bottom: max(10px, calc(var(--timebar-h, 86px) - 2px)); }
  body[data-place="open"]:not([data-view="trends"]) .map-key-body { max-height: calc(100dvh - 164px - var(--timebar-h, 86px)); }
}
/* The map takes keyboard focus (arrows pan, + and - zoom): draw its ring inside the window. */
.maplibregl-canvas:focus-visible { outline-offset: -4px; border-radius: 0; }
.maplibregl-ctrl-group button { width: 36px; height: 36px; }
.maplibregl-ctrl-scale { border-color: var(--ink-soft); color: var(--ink-soft); background: rgba(255, 255, 255, 0.8); font-family: var(--font); font-size: 10.5px; }
.maplibregl-ctrl-attrib { font-family: var(--font); font-size: 11px; }
.maplibregl-ctrl-attrib a { color: var(--ink-soft); }

.point-popup .maplibregl-popup-content { padding: 9px 26px 10px 11px; border-radius: 10px; box-shadow: var(--shadow); font-family: var(--font); }
.point-card { display: grid; gap: 2px; }
.point-card strong { color: var(--navy); font-size: 13px; }
.point-card span { color: var(--ink-soft); font-size: 12px; }

/* ------------------------------------------------------------------ charts (js/charts.js) */

.chart { position: relative; display: flex; flex-direction: column; gap: 6px; margin: 0; min-width: 0; }
.chart-caption { margin: 0; color: var(--muted); font-size: 12px; font-weight: 600; }
.chart svg { display: block; max-width: 100%; height: auto; overflow: visible; }
.chart svg:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.chart-grid line { stroke: var(--line); stroke-width: 1; shape-rendering: crispEdges; }
.chart-grid line.chart-baseline { stroke: var(--line-strong); }
.chart-axis { fill: var(--muted); font-size: 10px; font-variant-numeric: tabular-nums; }
.chart-axis.is-highlight { fill: var(--ink); font-weight: 700; }
.chart-path { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart-series.is-estimated .chart-path, .chart-path.is-estimated { stroke-dasharray: 5 4; }
.chart-series.is-emphasis .chart-path { stroke-width: 2.6; }
.chart-dot { stroke: #fff; stroke-width: 2; }
.chart-extreme { fill: var(--muted); }
.chart-band { opacity: 0.13; stroke: none; }
.chart-value { fill: var(--ink); font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; }
.chart-value.is-minor { fill: var(--ink-soft); font-size: 10px; font-weight: 600; }
.chart-value.has-halo { paint-order: stroke; stroke: #fff; stroke-width: 3px; stroke-linejoin: round; }
.chart-marker line { stroke: var(--ink-soft); stroke-width: 1; stroke-dasharray: 3 3; }
.chart-marker.is-accent line { stroke: var(--pulse); stroke-dasharray: none; stroke-width: 1.5; }
.chart-marker-label { fill: var(--ink-soft); font-size: 10px; font-weight: 600; }
.chart-now line { stroke: var(--pulse); stroke-width: 1.5; }
.chart-now text { fill: var(--pulse); font-size: 10px; font-weight: 700; }
.chart-col.is-later { opacity: 0.5; }
.chart-compare { fill: none; stroke: var(--navy); stroke-width: 1.5; stroke-linecap: round; }
.chart-whiskers line { stroke: var(--navy); stroke-width: 1; opacity: 0.55; }
.chart-crosshair { stroke: var(--ink-soft); stroke-width: 1; pointer-events: none; }
.chart-tip { position: absolute; top: 24px; z-index: 3; display: flex; flex-direction: column; gap: 2px; min-width: 96px; max-width: 220px; padding: 6px 9px; background: rgba(12, 12, 72, 0.94); color: #fff; border-radius: 8px; font-size: 11.5px; line-height: 1.35; pointer-events: none; font-variant-numeric: tabular-nums; }
.chart-tip-title { color: rgba(255, 255, 255, 0.78); font-size: 11px; }
.chart-tip-row { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.chart-tip-row strong { font-size: 12px; }
.chart-tip-key { flex: none; width: 12px; height: 0; border-top: 2px solid var(--key); }
.chart-tip-key.is-dashed { border-top-style: dashed; }
.chart-empty { margin: 0; color: var(--muted); font-size: 12px; }
.chart-note { margin: 0; color: var(--muted); font-size: 11.5px; line-height: 1.4; }
.chart-callouts { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; color: var(--ink-soft); font-size: 12.5px; }
.chart-change { padding: 0 7px; border-radius: 999px; background: var(--pulse); color: #fff; font-size: 12px; font-weight: 700; line-height: 19px; font-variant-numeric: tabular-nums; }
.chart-record { color: var(--navy); font-weight: 700; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; color: var(--ink-soft); font-size: 11.5px; }
.chart-legend.is-vertical { flex-direction: column; }
.legend-item { display: inline-flex; align-items: center; gap: 6px; }
.legend-swatch { display: inline-block; flex: none; }
.legend-swatch.is-line { width: 16px; height: 0; border-top: 2px solid var(--swatch); border-radius: 1px; }
.legend-swatch.is-dash { width: 16px; height: 0; border-top: 2px dashed var(--swatch); }
.legend-swatch.is-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--swatch); }
.legend-swatch.is-ring { width: 10px; height: 10px; border: 1.5px solid var(--swatch); border-radius: 50%; background: #fff; }
.legend-swatch.is-bar { width: 10px; height: 10px; border-radius: 2px; background: var(--swatch); }
.legend-swatch.is-hatch { width: 10px; height: 10px; border-radius: 2px; background: repeating-linear-gradient(45deg, var(--swatch) 0 1.6px, transparent 1.6px 3.6px); box-shadow: inset 0 0 0 1px var(--swatch); }
.legend-swatch.is-whisker { width: 2px; height: 12px; margin: 0 4px; background: var(--swatch); opacity: 0.6; }
.legend-swatch.is-area { width: 14px; height: 10px; background: var(--swatch); opacity: 0.18; }

.bars { display: flex; flex-direction: column; gap: 5px; }
.bar-row { display: grid; grid-template-columns: 124px 1fr minmax(42px, auto); align-items: center; gap: 8px; font-size: 12.5px; }
.bar-label { overflow: hidden; color: var(--ink-soft); text-overflow: ellipsis; white-space: nowrap; }
.bar-track { height: 10px; background: var(--track); border-radius: 2px; }
.bar-fill { display: block; height: 100%; background: var(--bar-colour, var(--bar)); border-radius: 0 4px 4px 0; opacity: 0.55; }
.bar-row.is-emphasis .bar-fill { opacity: 1; }
.bar-row.is-emphasis .bar-label { color: var(--ink); font-weight: 600; }
.bar-row.is-estimated .bar-fill { background: repeating-linear-gradient(45deg, var(--bar-colour, var(--bar)) 0 2.5px, transparent 2.5px 5px); box-shadow: inset 0 0 0 1px var(--bar-colour, var(--bar)); opacity: 0.9; }
.bar-value { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.bar-detail { color: var(--muted); font-weight: 400; }

.chart-spark { display: inline-flex; flex-direction: row; align-items: center; gap: 6px; vertical-align: middle; }
.chart-spark svg { width: auto; }
.chart-spark-value { color: var(--navy); font-size: 12.5px; font-weight: 700; font-variant-numeric: tabular-nums; }

.chart-stack-key { display: flex; flex-direction: column; gap: 3px; }
.chart-stack-item { display: grid; grid-template-columns: 12px 1fr auto 3em; align-items: center; gap: 8px; font-size: 12.5px; }
.chart-stack-item.is-total { grid-template-columns: 12px 1fr auto 3em; padding-top: 3px; border-top: 1px solid var(--line); }
.chart-stack-item.is-total .chart-stack-label { grid-column: 2; }
.chart-stack-label { color: var(--ink-soft); }
.chart-stack-value { color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
.chart-stack-share { color: var(--muted); text-align: right; font-size: 11.5px; font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ about */

.about { width: min(640px, 94vw); max-height: 88dvh; padding: 26px 28px; border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow); color: var(--ink); overflow-y: auto; }
.about::backdrop { background: rgba(12, 12, 72, 0.45); }
.about h2 { margin: 0 0 10px; color: var(--navy); font-size: 22px; line-height: 1.25; }
.about h3 { margin: 20px 0 6px; color: var(--ink); font-size: 14px; }
.about p, .about li { font-size: 14px; line-height: 1.55; }
.about li + li { margin-top: 4px; }
.about ul { padding-left: 18px; }
.about strong { color: var(--navy); }
.about-close-form { position: sticky; top: 0; z-index: 1; float: right; margin: -8px -10px 0 0; }
/* Room for the close button, which stays at the top right as About scrolls. */
#about-body { padding-right: 30px; }
.about-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.about-table th, .about-table td { padding: 6px 8px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; line-height: 1.45; }
.about-table th { color: var(--muted); font-weight: 600; }
.about-table td:first-child { color: var(--navy); font-weight: 700; white-space: nowrap; }
.about-links a { color: var(--accent); font-weight: 600; }
.about-contact { color: var(--ink-soft); }

/* ------------------------------------------------------------------ welcome (first visit)

   TEAM's start overlay, lighter: a navy scrim with a blur, one card with the
   mark and name, a lede, three ways in and a quiet way out. */

.welcome { width: min(720px, calc(100vw - 32px)); max-height: min(90dvh, 720px); padding: 24px 26px 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); color: var(--ink); overflow-y: auto; overscroll-behavior: contain; }
.welcome::backdrop { background: rgba(12, 12, 72, 0.35); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
.welcome-head { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 12px; }
.welcome-mark { display: block; width: 46px; height: 46px; }
.welcome-titles h2 { margin: 0; color: var(--navy); font-size: 28px; font-weight: 800; letter-spacing: 0.08em; line-height: 1; }
.welcome-tagline { margin: 5px 0 0; color: var(--muted); font-size: 13px; line-height: 1.2; }
.welcome-close { align-self: start; }
.welcome-lede { max-width: 62ch; margin: 16px 0 16px; color: var(--ink); font-size: 16px; line-height: 1.5; }
.welcome-entries { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 0; padding: 0; list-style: none; }
.welcome-entries > li { display: flex; }
.welcome-entry { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; width: 100%; padding: 12px 12px 12px; border: 1px solid var(--line); border-radius: 12px; background: #fff; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.welcome-entry:hover { border-color: var(--navy); box-shadow: var(--shadow); }
.welcome-dots { display: inline-flex; gap: 4px; min-height: 10px; }
.welcome-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--dot, var(--navy)); }
.welcome-entry-title { color: var(--navy); font-size: 16px; font-weight: 700; line-height: 1.25; }
.welcome-entry-text { color: var(--ink-soft); font-size: 12.5px; line-height: 1.45; }
.welcome-go { margin-top: auto; padding-top: 4px; color: var(--accent); font-size: 13px; font-weight: 600; }
.welcome-go::after { content: " →"; transition: margin-left 0.15s; }
.welcome-entry:hover .welcome-go { color: var(--navy); text-decoration: underline; }
.welcome-entry:hover .welcome-go::after { margin-left: 3px; }
.welcome-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 14px; margin: 14px 0 0; font-size: 12.5px; }
.welcome-foot .text-button { padding-left: 0; }
.welcome-lab { color: var(--muted); font-size: 12px; font-weight: 600; text-decoration: none; }
.welcome-lab:hover { color: var(--navy); text-decoration: underline; }

/* ------------------------------------------------------------------ small screens */

@media (max-width: 1100px) {
  :root { --card-w: 320px; }
}

@media (max-width: 760px) {
  .panel {
    top: auto;
    left: 8px;
    right: 8px;
    bottom: max(8px, env(safe-area-inset-bottom));
    width: auto;
    max-height: 62vh;
    max-height: 62dvh;
    border-radius: 16px;
  }
  body[data-place="open"] .panel { display: none; }
  /* A bottom sheet opens upwards, so the arrow points up while it is folded. */
  .panel-toggle svg { transform: rotate(180deg); }
  body[data-panel="collapsed"] .panel-toggle svg { transform: none; }
  body[data-panel="collapsed"] .brand { cursor: pointer; }
  .brand { padding: 10px 10px 8px 12px; }
  .brand h1 { font-size: 19px; }
  .brand-mark { width: 32px; height: 32px; }
  .hero-figure { font-size: 40px; }
  .place { top: auto; left: 8px; right: 8px; bottom: max(8px, env(safe-area-inset-bottom)); width: auto; max-height: 62vh; max-height: 62dvh; }
  .map-tools { left: 8px; right: 8px; max-width: none; justify-content: flex-start; gap: 6px; }
  .basemaps button { padding: 4px 8px; }
  .layers summary, .map-key-summary { padding: 8px 10px; }
  .map-key { max-width: 170px; }
  .map-key-body { max-height: max(120px, calc(100dvh - var(--sheet-h) - 200px)); padding: 2px 9px 8px; }
  .key-label { font-size: 11px; }
  .layer-list { width: min(250px, calc(100vw - 40px)); }
  input[type="search"], select { font-size: 16px; }
  .maplibregl-ctrl-bottom-right { bottom: calc(var(--sheet-h) + 8px); }
  .maplibregl-ctrl-bottom-left { display: none; }
  /* The time bar rides above the folded sheet, and the zoom buttons and
     credits above the time bar (as on a desktop; --timebar-h is its height,
     two rows or three); an open key stops above the credits. */
  .timebar { left: 8px; right: 8px; bottom: calc(var(--sheet-h) + 8px); max-width: none; transform: none; justify-content: center; }
  body[data-panel="collapsed"] .timebar { left: 8px; }
  body[data-panel="collapsed"]:not([data-place="open"]):not([data-view="trends"]) .maplibregl-ctrl-bottom-right { bottom: calc(var(--sheet-h) + 8px + var(--timebar-h, 86px)); }
  body[data-panel="collapsed"]:not([data-place="open"]):not([data-view="trends"]) .map-key-body { max-height: max(120px, calc(100dvh - var(--sheet-h) - 154px - var(--timebar-h, 86px))); }
  body:not([data-panel="collapsed"]) .timebar, body[data-place="open"] .timebar { display: none; }
  .loading, body[data-panel="collapsed"] .loading { left: 50%; bottom: calc(var(--sheet-h) + 64px); }
  .about { padding: 20px 18px; }
  .welcome { width: calc(100vw - 16px); max-height: calc(100dvh - 24px); padding: 18px 16px 12px; }
  .welcome-titles h2 { font-size: 24px; }
  .welcome-mark { width: 40px; height: 40px; }
  .welcome-lede { margin: 12px 0; font-size: 15px; }
  .welcome-entries { grid-template-columns: 1fr; gap: 8px; }
  .welcome-entry { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 10px; row-gap: 2px; align-items: center; padding: 10px 12px; }
  .welcome-dots { grid-row: 1; flex-wrap: wrap; width: 24px; }
  .welcome-entry-title { grid-column: 2; font-size: 15px; }
  .welcome-entry-text { grid-column: 2; }
  .welcome-go { display: none; }
}

/* A short window (a phone on its side, or a page zoomed to 200-400%): the
   panel scrolls as a whole, so the view keeps most of it, the sheets may
   grow, and the tagline gives way. */
@media (max-height: 520px) {
  .panel { overflow-y: auto; overscroll-behavior: contain; }
  .panel-body { flex: none; overflow: visible; }
  .brand .tagline { display: none; }
}
@media (max-width: 760px) and (max-height: 520px) {
  .panel, .place { max-height: calc(100dvh - 64px); }
}
/* Under about 400px the map tools take two rows. */
@media (max-width: 402px) and (max-height: 520px) {
  .panel, .place { max-height: calc(100dvh - 104px); }
}

/* No map in this browser (no WebGL): the map's own controls go, and the
   notice says so without taking taps meant for the time bar. On a phone it
   stands at the top, where the map tools were. */
body[data-map="none"] #basemaps, body[data-map="none"] #layers, body[data-map="none"] #map-key { display: none; }
body[data-map="none"] .loading { max-width: calc(100vw - 32px); white-space: normal; text-align: center; pointer-events: none; }
@media (max-width: 760px) {
  body[data-map="none"] .loading { top: max(12px, env(safe-area-inset-top)); bottom: auto; }
}

/* Windows High Contrast and other forced colours: the selected chip, button
   and tab keep a visible mark, and key and chart swatches keep their data
   colours (they are the only thing that tells the rows apart). */
@media (forced-colors: active) {
  .chip[aria-checked="true"], .segmented button[aria-pressed="true"] { outline: 2px solid Highlight; outline-offset: 1px; }
  .tabs button[aria-selected="true"] { border-bottom-color: Highlight; }
  .chip-dot, .key-swatch, .key-swatch::after, .legend-swatch, .legend-swatch-step, .welcome-dot, .bar-fill, .chart-tip-key { forced-color-adjust: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}
/* The same when the page is opened with ?reduced-motion or motion is paused. */
body[data-motion="off"] *, body[data-motion="off"] *::before, body[data-motion="off"] *::after { transition: none !important; animation: none !important; }
