:root { --a11y-scale:1; --a11y-display-scale:1; --ink:#13212b; --muted:#66747d; --line:#d8e0e3; --paper:#f7f9f8; --rail:#ffffff; --signal:#d2442e; --blue:#2e667b; --soft:#e8f0ef; }
.dispatch-marker.dispatch-marker--suspicious { background:#0f766e; } .dispatch-marker.dispatch-marker--missing { background:#7c3aed; } .dispatch-marker.dispatch-marker--weapon { background:#9f1239; } .dispatch-marker.dispatch-marker--theft { background:#a16207; }
body main > .view { display:none!important; } body main > .view.is-active { display:block!important; } .accessibility-panel[hidden] { display:none!important; } .overlay-close { position:absolute; top:8px; right:10px; z-index:1; display:grid; place-items:center; width:34px; height:34px; padding:0; border:0; border-radius:50%; color:var(--ink); background:var(--soft); font-size:calc(24px * var(--a11y-display-scale,1)); line-height:1; } .accessibility-panel { padding-top:48px!important; } .activity-rail { padding-top:48px!important; } .table-wrap { overscroll-behavior:contain; padding-bottom:24px; } .incident-list { overscroll-behavior:contain; padding-bottom:28px!important; } .recent-call { color:var(--muted); background:var(--soft); } @media (max-width:760px) { .header-actions { width:100%; justify-content:flex-end; } .header-actions .theme-toggle { font-size:calc(10px * var(--a11y-scale,1)); padding:6px; } .accessibility-panel { inset:8px 8px auto auto; max-height:calc(100% - 16px); overflow:auto; } }
.incident-popup { display:grid; gap:3px; font-size:calc(11px * var(--a11y-scale,1)); line-height:1.28; }
.popup-details { margin-top:6px; width:100%; padding:6px 8px; border:1px solid var(--line); border-radius:6px; background:transparent; color:inherit; cursor:pointer; font:inherit; font-size:calc(11px * var(--a11y-scale,1)); font-weight:700; letter-spacing:.04em; text-transform:uppercase; }
.popup-details:hover,.popup-details:focus-visible { background:var(--blue); color:var(--paper); border-color:var(--blue); }
 .incident-popup strong { font-size:calc(12px * var(--a11y-scale,1)); } .incident-popup span,.incident-popup small { color:var(--muted); } .map-link { padding:3px 5px; border:0; color:var(--blue); background:transparent; font-size:calc(11px * var(--a11y-scale,1)); text-decoration:underline; text-underline-offset:2px; }
main > .view { display:none!important; } main > .view.is-active { display:block!important; }
html,body { width:100%; height:100%; overflow:hidden; } body { min-height:100dvh; display:grid; grid-template-rows:auto minmax(0,1fr); } main { position:relative; min-height:0; overflow:hidden; } .view { display:none!important; height:100%; min-height:0!important; } .view.is-active { display:block!important; } .map-view.map-view { height:100%; min-height:0!important; } #map { height:100%; min-height:0!important; } .list-view,.about-view { overflow:hidden; } .list-shell,.about-shell { height:100%; max-width:none; padding:clamp(24px,4vw,56px); display:flex; flex-direction:column; } .table-wrap { flex:1; min-height:0; overflow:auto; scrollbar-width:none; } .table-wrap::-webkit-scrollbar { display:none; } .about-shell { overflow:auto; scrollbar-width:none; } .about-shell::-webkit-scrollbar { display:none; } .accessibility-panel { position:absolute; z-index:2000; top:12px; right:12px; display:grid; gap:10px; width:min(270px,calc(100% - 24px)); padding:16px; border:1px solid var(--line); color:var(--ink); background:var(--rail); box-shadow:0 12px 36px rgba(0,0,0,.28); } .accessibility-panel label { display:flex; gap:8px; align-items:center; }
.a11y-text-size { display:flex; gap:8px; align-items:center; justify-content:space-between; }
.a11y-text-buttons { display:flex; gap:4px; }
.a11y-text-buttons button { min-width:34px; min-height:34px; padding:2px 8px; border:1px solid var(--line); border-radius:6px; background:transparent; color:inherit; cursor:pointer; line-height:1; }
.a11y-text-buttons button:nth-child(2) { font-size:calc(13px * var(--a11y-scale,1)); }
.a11y-text-buttons button:nth-child(3) { font-size:calc(15px * var(--a11y-scale,1)); }
.a11y-text-buttons button[aria-pressed="true"] { background:var(--blue); color:var(--paper); border-color:var(--blue); }
 .accessibility-panel button { padding:8px; border:1px solid var(--line); color:inherit; background:transparent; } .skip-link { position:absolute; z-index:3000; top:-50px; left:12px; padding:9px 12px; color:#fff; background:#000; } .skip-link:focus { top:12px; } html[data-text-size="large"] { --a11y-scale:1.4; --a11y-display-scale:1.15; }
html[data-text-size="xlarge"] { --a11y-scale:2; --a11y-display-scale:1.3; } html[data-contrast="true"] { --ink:#000; --muted:#1a1a1a; --line:#111; --paper:#fff; --rail:#fff; --blue:#004e92; } html[data-contrast="true"] body[data-theme="dark"] { --ink:#fff; --muted:#fff; --line:#fff; --paper:#000; --rail:#000; --blue:#7dd3fc; } html[data-reduce-motion="true"] { scroll-behavior:auto; } html[data-reduce-motion="true"] *,html[data-reduce-motion="true"] *::before,html[data-reduce-motion="true"] *::after { transition-duration:0.01ms!important; animation-duration:0.01ms!important; }
.dispatch-marker.dispatch-marker { display:grid; place-items:center; width:42px!important; height:42px!important; border:3px solid #fff; border-radius:50%; box-shadow:0 4px 14px rgba(0,0,0,.55),0 0 0 2px rgba(10,16,19,.42); } .dispatch-marker.dispatch-marker svg { width:23px; height:23px; fill:#fff; filter:drop-shadow(0 1px 1px rgba(0,0,0,.28)); } .dispatch-marker.dispatch-marker--fire { background:#e53e3e; } .dispatch-marker.dispatch-marker--medical { background:#008db3; } .dispatch-marker.dispatch-marker--traffic { background:#e08700; } .dispatch-marker.dispatch-marker--safety { background:#7048c8; } .dispatch-marker.dispatch-marker--general { background:#475569; }
html { scroll-behavior:smooth; } .view { display:block !important; } .nav-button { display:flex; align-items:center; text-decoration:none; } .map-boundary-label { position:absolute; z-index:900; bottom:18px; left:18px; margin:0; padding:7px 10px; color:#fff; background:rgba(19,33,43,.9); box-shadow:0 2px 10px rgba(0,0,0,.2); font-size:calc(11px * var(--a11y-scale,1)); font-weight:750; letter-spacing:.04em; } @media (max-width:760px) { .map-boundary-label { bottom:14px; left:14px; font-size:calc(10px * var(--a11y-scale,1)); } }
.quality-summary { margin:10px 0 0; color:var(--muted); font-size:calc(12px * var(--a11y-scale,1)); line-height:1.45; } .marker-legend { display:flex; flex-wrap:wrap; gap:7px 10px; margin:14px 0 10px; color:var(--muted); font-size:calc(11px * var(--a11y-scale,1)); } .marker-legend span { display:inline-flex; align-items:center; gap:4px; } .legend-dot { width:9px; height:9px; border:1px solid rgba(255,255,255,.8); border-radius:50%; } .legend-dot.fire { background:#d85e42; } .legend-dot.medical { background:#3d8cab; } .legend-dot.traffic { background:#bd8d35; } .legend-dot.safety { background:#8654a3; } .legend-dot.general { background:#566d76; } tbody tr { cursor:pointer; } tbody tr:focus-visible { outline:3px solid var(--blue); outline-offset:-3px; }
body[data-theme="dark"] { --ink:#e6edef; --muted:#9aabb2; --line:#33434b; --paper:#0f171b; --rail:#172329; --signal:#f0644f; --blue:#7dc8dc; --soft:#24353d; color-scheme:dark; }
body[data-theme="dark"] .leaflet-tile-pane { filter:brightness(.52) saturate(.62) contrast(1.16) hue-rotate(165deg); }
.dispatch-marker { display:grid; place-items:center; width:28px!important; height:28px!important; border:2px solid rgba(255,255,255,.9); border-radius:50%; color:#fff; box-shadow:0 2px 8px rgba(0,0,0,.4); font:800 16px/1 system-ui; }.dispatch-marker--fire { background:#d85e42; }.dispatch-marker--medical { background:#3d8cab; }.dispatch-marker--traffic { background:#bd8d35; }.dispatch-marker--safety { background:#8654a3; }.dispatch-marker--general { background:#566d76; }
body[data-theme="dark"] .topbar { background:#0a1013; } body[data-theme="dark"] .incident,body[data-theme="dark"] .filter,body[data-theme="dark"] .search input,body[data-theme="dark"] .table-wrap { background:#172329; color:var(--ink); } body[data-theme="dark"] .incident:hover,body[data-theme="dark"] .incident:focus-visible,body[data-theme="dark"] .filter[aria-pressed="true"] { background:#24353d; } body[data-theme="dark"] dialog { color:var(--ink); background:#172329; } body[data-theme="dark"] .leaflet-popup-content-wrapper,body[data-theme="dark"] .leaflet-popup-tip { color:var(--ink); background:#172329; }
.topbar .nav-button { display:inline-flex; align-items:center; justify-content:center; color:#c4d1d5; text-decoration:none; } .topbar button.nav-button { cursor:pointer; } .accessibility-panel .overlay-close,.about-card .overlay-close { display:grid; place-items:center; padding:0; line-height:1; } .about-panel[hidden] { display:none!important; } .about-panel { position:absolute; z-index:2500; inset:0; display:grid; place-items:center; padding:18px; background:rgba(11,25,32,.55); } .about-card { position:relative; width:min(560px,100%); max-height:100%; overflow:auto; padding:42px 30px 30px; color:var(--ink); background:var(--rail); box-shadow:0 20px 80px rgba(0,0,0,.35); } .about-card p { color:var(--muted); line-height:1.65; } .calls-main { height:calc(100dvh - 70px); min-height:0; overflow:hidden; } .calls-shell { height:100%; max-width:1200px; margin:0 auto; padding:clamp(24px,4vw,52px); display:flex; flex-direction:column; } .calls-shell .table-wrap { flex:1; min-height:0; margin-top:20px; } .calls-page .topbar { flex-wrap:nowrap; } .map-utilities { position:absolute; z-index:900; top:18px; right:18px; display:flex; align-items:center; gap:7px; padding:7px; border:1px solid rgba(255,255,255,.24); background:rgba(10,16,19,.9); box-shadow:0 3px 12px rgba(0,0,0,.22); } .map-utilities .theme-toggle { color:#fff; } @media (max-width:760px) { .calls-main { height:calc(100dvh - 110px); } .calls-page .topbar { flex-wrap:wrap; } .calls-page .topbar nav { order:3; } .map-utilities { top:14px; right:14px; gap:3px; padding:4px; } .map-utilities .theme-toggle { font-size:calc(10px * var(--a11y-scale,1)); padding:6px; } }
/* Approved marker shape language: shape conveys event family, illustration conveys the call type. */
.dispatch-marker.dispatch-marker--traffic-hazard { clip-path:polygon(50% 0,100% 92%,50% 100%,0 92%); border-radius:0; background:#e08700; }
.dispatch-marker.dispatch-marker--property { border-radius:3px; background:#2563eb; }
.dispatch-marker.dispatch-marker--suspicious { clip-path:polygon(50% 0,98% 35%,80% 92%,20% 92%,2% 35%); border-radius:0; background:#7048c8; }
.dispatch-marker.dispatch-marker--police { clip-path:polygon(50% 0,90% 16%,95% 70%,50% 100%,5% 70%,10% 16%); border-radius:0; background:#1d4ed8; }
.dispatch-marker.dispatch-marker--assist { clip-path:polygon(25% 3%,75% 3%,97% 50%,75% 97%,25% 97%,3% 50%); border-radius:0; background:#0f766e; }
.dispatch-marker.dispatch-marker--missing { transform:rotate(45deg); border-radius:3px; background:#c026d3; }
.dispatch-marker.dispatch-marker--missing svg { transform:rotate(-45deg); }
.dispatch-marker.dispatch-marker--vehicle { border-radius:10px; background:#475569; }
.dispatch-marker.dispatch-marker--weapon { clip-path:polygon(50% 0,90% 16%,95% 70%,50% 100%,5% 70%,10% 16%); border-radius:0; background:#b91c1c; }
.dispatch-marker.dispatch-marker--fire { clip-path:polygon(50% 0,61% 22%,82% 8%,78% 34%,100% 39%,80% 55%,92% 78%,65% 73%,50% 100%,35% 73%,8% 78%,20% 55%,0 39%,22% 34%,18% 8%,39% 22%); border-radius:0; background:#ea580c; }
.dispatch-marker.dispatch-marker--wildlife { clip-path:polygon(20% 20%,35% 4%,50% 18%,65% 4%,80% 20%,92% 42%,84% 78%,65% 95%,50% 75%,35% 95%,16% 78%,8% 42%); border-radius:0; background:#166534; }
.dispatch-marker.dispatch-marker--disturbance { border-radius:14px 14px 4px 14px; background:#db2777; }
.dispatch-marker.dispatch-marker--fatality { clip-path:polygon(35% 0,65% 0,65% 35%,100% 35%,100% 65%,65% 65%,65% 100%,35% 100%,35% 65%,0 65%,0 35%,35% 35%); border-radius:0; background:#374151; }
.dispatch-marker.dispatch-marker--military { clip-path:polygon(50% 0,61% 25%,88% 12%,75% 39%,100% 50%,75% 61%,88% 88%,61% 75%,50% 100%,39% 75%,12% 88%,25% 61%,0 50%,25% 39%,12% 12%,39% 25%); border-radius:0; background:#4d7c0f; }
.response-area { stroke-dasharray:8 7; }
.dispatch-marker.dispatch-marker { display:block; width:42px!important; height:42px!important; padding:0; border:0; border-radius:0; background:transparent!important; box-shadow:none; clip-path:none!important; overflow:visible; }
.dispatch-marker .marker-art { display:block; width:42px; height:42px; object-fit:contain; }
.header-actions { display:flex; align-items:center; gap:14px; }.theme-toggle,.activity-toggle { border:1px solid rgba(255,255,255,.28); color:inherit; background:transparent; font-size:calc(12px * var(--a11y-scale,1)); font-weight:750; letter-spacing:.04em; }.theme-toggle { padding:7px 10px; border-radius:3px; }.theme-toggle:hover,.theme-toggle:focus-visible { background:rgba(255,255,255,.12); }.map-view.map-view { position:relative; display:block !important; min-height:calc(100vh - 70px); }.activity-rail.activity-rail { position:absolute; z-index:1000; inset:0 auto 0 0; width:min(360px,calc(100vw - 56px)); padding:20px 16px; box-shadow:12px 0 28px rgba(0,0,0,.22); transform:translateX(-103%); transition:transform 180ms ease; }.map-view.rail-open .activity-rail { transform:translateX(0); }.activity-toggle { position:absolute; z-index:900; top:18px; left:18px; display:flex; align-items:center; gap:7px; padding:10px 13px; color:#fff; border-color:rgba(0,0,0,.2); background:var(--ink); box-shadow:0 3px 12px rgba(0,0,0,.22); }.activity-toggle:hover,.activity-toggle:focus-visible { background:var(--blue); color:#102027; }.incident-list { gap:5px; }.incident { padding:9px 10px; }.incident h3 { margin:4px 0 2px; font-size:calc(14px * var(--a11y-scale,1)); }.incident p { font-size:calc(12px * var(--a11y-scale,1)); }.incident-top { font-size:calc(10px * var(--a11y-scale,1)); }.search { margin:16px 0 10px; }.stale-control { margin:10px 0 8px; } #map { min-height:calc(100vh - 70px); }.map-view.rail-open .activity-toggle { left:min(378px,calc(100vw - 38px)); }.map-view.rail-open .activity-toggle span { display:none; } @media (prefers-reduced-motion:reduce) { .activity-rail { transition:none; } } @media (max-width:760px) { .header-actions { margin-left:auto; gap:8px; }.theme-toggle { font-size:calc(11px * var(--a11y-scale,1)); padding:6px 8px; } #map { min-height:calc(100vh - 110px); }.activity-rail.activity-rail { min-height:calc(100vh - 110px); }.activity-toggle { top:14px; left:14px; }.map-view.rail-open .activity-toggle { left:calc(100vw - 43px); } }
* { box-sizing:border-box; } body { margin:0; color:var(--ink); background:var(--paper); font-family:Inter, ui-sans-serif, system-ui, sans-serif; } button, input { font:inherit; } button { cursor:pointer; } .topbar { height:70px; display:flex; align-items:center; justify-content:space-between; gap:24px; padding:0 24px; color:#fff; background:var(--ink); border-bottom:3px solid var(--signal); } .brand { display:flex; align-items:center; gap:11px; color:inherit; text-decoration:none; font-size:calc(12px * var(--a11y-display-scale,1)); line-height:1.08; letter-spacing:.08em; text-transform:uppercase; } .brand strong { font-size:calc(16px * var(--a11y-display-scale,1)); letter-spacing:.12em; } .beacon { width:13px; height:13px; border-radius:50%; background:var(--signal); box-shadow:0 0 0 6px rgba(210,68,46,.2); } nav { display:flex; height:100%; } .nav-button { padding:0 16px; border:0; border-bottom:3px solid transparent; color:#c4d1d5; background:transparent; font-weight:650; } .nav-button:hover,.nav-button:focus-visible,.nav-button.is-active { color:#fff; border-bottom-color:#fff; } .feed-state { color:#c4d1d5; font-size:calc(13px * var(--a11y-scale,1)); } .feed-state.live:before { content:""; display:inline-block; width:7px; height:7px; margin-right:7px; border-radius:50%; background:#6ece91; } .feed-state.warn { color:#ffd194; } .view { display:none; } .view.is-active { display:block; } .map-view { min-height:calc(100vh - 70px); display:grid !important; grid-template-columns:minmax(300px, 390px) 1fr; } .activity-rail { z-index:2; display:flex; flex-direction:column; min-height:0; padding:26px 20px; background:var(--rail); border-right:1px solid var(--line); } .eyebrow { margin:0 0 8px; color:var(--blue); font-size:calc(11px * var(--a11y-scale,1)); font-weight:800; letter-spacing:.14em; text-transform:uppercase; } h1,h2 { margin:0; font-family:Georgia, "Times New Roman", serif; font-weight:500; letter-spacing:-.03em; } h1 { font-size:calc(31px * var(--a11y-display-scale,1)); line-height:1.03; } h2 { font-size:calc(42px * var(--a11y-display-scale,1)); line-height:1.05; } .rail-heading > p:last-child,#listSummary { color:var(--muted); line-height:1.45; } .search { display:block; margin:22px 0 12px; } .search input { width:100%; padding:12px 13px; border:1px solid var(--line); border-radius:3px; outline-offset:2px; } .filters { display:flex; flex-wrap:wrap; gap:6px; } .filter { padding:6px 8px; border:1px solid var(--line); border-radius:99px; color:var(--muted); background:#fff; font-size:calc(12px * var(--a11y-scale,1)); } .filter[aria-pressed="true"] { color:var(--ink); border-color:var(--blue); background:var(--soft); } .stale-control { display:flex; gap:8px; margin:14px 0 10px; color:var(--muted); font-size:calc(12px * var(--a11y-scale,1)); } .incident-list { display:flex; flex-direction:column; gap:8px; overflow:auto; margin:0; padding:0; list-style:none; } .incident { width:100%; padding:13px; border:1px solid var(--line); border-left:3px solid var(--blue); text-align:left; background:#fff; } .incident:hover,.incident:focus-visible { border-color:var(--blue); background:var(--soft); } .incident.stale { border-left-color:#ae8a50; opacity:.75; } .incident-top { display:flex; justify-content:space-between; gap:12px; color:var(--blue); font-size:calc(11px * var(--a11y-scale,1)); font-weight:800; letter-spacing:.08em; text-transform:uppercase; } .incident h3 { margin:7px 0 4px; font-size:calc(15px * var(--a11y-scale,1)); } .incident p { margin:0; color:var(--muted); font-size:calc(13px * var(--a11y-scale,1)); } .empty-state { padding:24px 6px; color:var(--muted); line-height:1.4; } #map { min-height:calc(100vh - 70px); background:#d9e7e7; } .list-shell,.about-shell { max-width:1000px; margin:0 auto; padding:80px 32px; } .list-shell > p:not(.eyebrow),.about-shell p { max-width:670px; color:var(--muted); line-height:1.65; } .table-wrap { overflow:auto; margin-top:36px; border:1px solid var(--line); background:#fff; } table { width:100%; border-collapse:collapse; text-align:left; } th,td { padding:15px 18px; border-bottom:1px solid var(--line); font-size:calc(14px * var(--a11y-scale,1)); } th { color:var(--blue); font-size:calc(11px * var(--a11y-scale,1)); letter-spacing:.1em; text-transform:uppercase; } .source-note { padding-top:16px; color:var(--blue) !important; font-size:calc(14px * var(--a11y-scale,1)); } dialog { position:relative; max-width:450px; padding:34px; border:0; box-shadow:0 20px 80px rgba(19,33,43,.3); } dialog::backdrop { background:rgba(11,25,32,.55); } dialog h2 { font-size:calc(31px * var(--a11y-display-scale,1)); } dl { margin:25px 0; } dl div { padding:12px 0; border-top:1px solid var(--line); } dt { color:var(--blue); font-size:calc(11px * var(--a11y-scale,1)); font-weight:800; letter-spacing:.1em; text-transform:uppercase; } dd { margin:5px 0 0; } .dialog-close { position:absolute; top:11px; right:15px; border:0; color:var(--ink); background:transparent; font-size:calc(28px * var(--a11y-display-scale,1)); } .privacy-note { color:var(--muted); font-size:calc(13px * var(--a11y-scale,1)); line-height:1.45; } .sr-only { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0,0,0,0); } @media (max-width:760px) { .topbar { height:auto; min-height:68px; flex-wrap:wrap; padding:13px 16px 0; gap:10px; } nav { order:3; width:100%; height:42px; justify-content:space-between; } .nav-button { flex:1; padding:0 6px; font-size:calc(13px * var(--a11y-scale,1)); } .feed-state { font-size:calc(11px * var(--a11y-scale,1)); } .map-view { grid-template-columns:1fr; } .activity-rail { min-height:420px; border-right:0; } #map { min-height:52vh; } h2 { font-size:calc(34px * var(--a11y-display-scale,1)); } .list-shell,.about-shell { padding:50px 20px; } }

/* ---------------------------------------------------------------------------
   Map chrome, incident dialog, pan area and the accessibility rework.
   --------------------------------------------------------------------------- */

/* The Activity button drew white text on var(--ink), and --ink is a near-white ink
   colour in the dark theme, so the label disappeared into its own background. It now
   wears the same fixed dark chrome as Near me / Accessibility / Light map. */
.activity-toggle.activity-toggle { color:#fff; border:1px solid rgba(255,255,255,.24); background:rgba(10,16,19,.92); box-shadow:0 3px 12px rgba(0,0,0,.22); }
.activity-toggle.activity-toggle:hover,.activity-toggle.activity-toggle:focus-visible { color:#fff; background:rgba(34,52,61,.96); }

/* Incident details: a slightly smaller card, and the close control sits lower so it
   reads as part of the card instead of clinging to the top edge. */
dialog#incidentDialog { max-width:400px; max-height:min(86vh,760px); overflow:auto; padding:30px 28px 26px; }
dialog#incidentDialog h2 { font-size:calc(26px * var(--a11y-display-scale,1)); }
dialog#incidentDialog dl { margin:20px 0; }
dialog#incidentDialog dl div { padding:10px 0; }
#incidentDialog .dialog-close { top:18px; right:16px; display:grid; place-items:center; width:34px; height:34px; padding:0; border-radius:50%; color:var(--ink); background:var(--soft); font-size:calc(21px * var(--a11y-display-scale,1)); line-height:1; }

/* Text size scaled only the selectors that happened to use the scale variable. Anything
   with no size of its own sat at the browser default and never moved. */
html { font-size:calc(16px * var(--a11y-scale,1)); }
html[data-text-size="large"] .topbar,html[data-text-size="xlarge"] .topbar { height:auto; min-height:70px; flex-wrap:wrap; padding-top:10px; padding-bottom:10px; }

/* Higher contrast repainted only the surfaces that read their colours from the custom
   properties, which left the topbar, cards, tables, dialogs and map chrome untouched. */
html[data-contrast="true"] { --soft:#dcdcdc; }
html[data-contrast="true"] body[data-theme="dark"] { --soft:#2a2a2a; }
html[data-contrast="true"] .topbar { color:#fff; background:#000; }
html[data-contrast="true"] .nav-button,html[data-contrast="true"] .topbar .nav-button,html[data-contrast="true"] .feed-state { color:#fff; }
html[data-contrast="true"] .nav-button.is-active { border-bottom-color:#fff; }
html[data-contrast="true"] .incident,html[data-contrast="true"] .filter,html[data-contrast="true"] .search input,html[data-contrast="true"] .table-wrap,html[data-contrast="true"] dialog,html[data-contrast="true"] .leaflet-popup-content-wrapper,html[data-contrast="true"] .leaflet-popup-tip { color:var(--ink); background:var(--paper); }
html[data-contrast="true"] .incident,html[data-contrast="true"] .filter,html[data-contrast="true"] .search input,html[data-contrast="true"] .table-wrap { border:2px solid var(--line); }
html[data-contrast="true"] .incident { border-left:4px solid var(--blue); }
html[data-contrast="true"] .incident:hover,html[data-contrast="true"] .incident:focus-visible,html[data-contrast="true"] .filter[aria-pressed="true"],html[data-contrast="true"] .recent-call { color:var(--ink); background:var(--soft); }
html[data-contrast="true"] th,html[data-contrast="true"] td { border-bottom:2px solid var(--line); }
html[data-contrast="true"] .map-utilities,html[data-contrast="true"] .activity-toggle.activity-toggle { color:#fff; background:#000; border:2px solid #fff; }
html[data-contrast="true"] .map-utilities .theme-toggle { color:#fff; border-color:#fff; }
html[data-contrast="true"] .activity-toggle.activity-toggle:hover,html[data-contrast="true"] .activity-toggle.activity-toggle:focus-visible,html[data-contrast="true"] .map-utilities .theme-toggle:hover,html[data-contrast="true"] .map-utilities .theme-toggle:focus-visible { color:#000; background:#fff; }
html[data-contrast="true"] :focus-visible { outline:3px solid var(--blue); outline-offset:2px; }
/* A grey base map keeps the coloured incident markers readable. */
html[data-contrast="true"] .leaflet-tile-pane { filter:grayscale(1) contrast(1.1)!important; }
html[data-contrast="true"] body[data-theme="dark"] .leaflet-tile-pane { filter:grayscale(1) brightness(.62) contrast(1.2)!important; }

/* Reduce motion: the map jumps instead of gliding (app.js), drag inertia is off, and
   nothing eases in or out. */
html[data-reduce-motion="true"] { scroll-behavior:auto!important; }
html[data-reduce-motion="true"] .activity-rail { transition:none!important; }
html[data-reduce-motion="true"] .leaflet-fade-anim .leaflet-tile,html[data-reduce-motion="true"] .leaflet-zoom-anim .leaflet-zoom-animated { transition:none!important; }

/* Larger tap targets, on by default on touch screens. */
html[data-large-targets="true"] .theme-toggle,html[data-large-targets="true"] .activity-toggle { min-height:44px; padding:11px 14px; }
html[data-large-targets="true"] .nav-button { min-height:44px; }
html[data-large-targets="true"] .filter { min-height:38px; padding:9px 14px; }
html[data-large-targets="true"] .incident { padding:16px; }
html[data-large-targets="true"] .overlay-close,html[data-large-targets="true"] #incidentDialog .dialog-close { width:44px; height:44px; }
html[data-large-targets="true"] .a11y-text-buttons button { min-width:44px; min-height:44px; }
html[data-large-targets="true"] .popup-details { padding:11px 10px; }
html[data-large-targets="true"] .map-link { display:inline-block; min-height:38px; padding:9px 10px; }
html[data-large-targets="true"] .dispatch-marker .marker-art { width:56px; height:56px; margin:-14px 0 0 -7px; }

/* Accessibility panel: every option says what it actually does. */
.accessibility-panel { width:min(304px,calc(100% - 24px)); max-height:calc(100% - 24px); overflow:auto; gap:0; }
.calls-main { position:relative; }
.a11y-option { display:grid; gap:5px; padding:11px 0; border-top:1px solid var(--line); }
.a11y-option:first-of-type { border-top:0; padding-top:4px; }
.a11y-option > label { display:flex; gap:8px; align-items:center; font-weight:650; }
.a11y-option-head { display:flex; gap:8px; align-items:center; justify-content:space-between; font-weight:650; }
.a11y-hint { margin:0; color:var(--muted); font-size:calc(11px * var(--a11y-scale,1)); line-height:1.45; }
.a11y-badge { padding:2px 7px; border:1px solid var(--line); border-radius:99px; color:var(--muted); font-size:calc(9px * var(--a11y-scale,1)); font-weight:800; letter-spacing:.08em; text-transform:uppercase; }
.a11y-scope { margin:0 0 2px; color:var(--muted); font-size:calc(11px * var(--a11y-scale,1)); line-height:1.45; }
#accessibilityReset { margin-top:12px; }

/* The call list carries a fourth nav item now, so the row has to give a little. */
@media (max-width:760px) { .calls-page .nav-button { padding:0 4px; font-size:calc(11px * var(--a11y-scale,1)); } }

/* On a phone the utilities row and the Activity button fought over the top edge and the
   Activity label lost, which is the other half of not being able to read it. The row moves
   to the bottom-left, clear of the zoom control and the attribution. */
@media (max-width:760px) { .map-utilities { top:auto; right:auto; bottom:30px; left:14px; } }

/* ---------------------------------------------------------------------------
   Marker legibility, and the calls kept on after the source retires them.
   --------------------------------------------------------------------------- */

/* A little larger by default, and ringed so they read against the map instead of
   sinking into it. Every marker is a mid tone, so the ring flips with the theme:
   dark against the light tiles, white against the dimmed dark ones. */
.dispatch-marker.dispatch-marker { width:48px!important; height:48px!important; }
.dispatch-marker .marker-art {
  width:48px; height:48px;
  filter:drop-shadow(0 0 1.5px rgba(12,22,28,.92)) drop-shadow(0 0 1.5px rgba(12,22,28,.92)) drop-shadow(0 3px 5px rgba(0,0,0,.4));
}
body[data-theme="dark"] .dispatch-marker .marker-art {
  filter:drop-shadow(0 0 1.5px rgba(255,255,255,1)) drop-shadow(0 0 2px rgba(255,255,255,.9)) drop-shadow(0 3px 6px rgba(0,0,0,.85));
}
html[data-contrast="true"] .dispatch-marker .marker-art {
  filter:drop-shadow(0 0 2px #fff) drop-shadow(0 0 2px #fff) drop-shadow(0 0 3px #000) drop-shadow(0 2px 4px #000);
}
html[data-large-targets="true"] .dispatch-marker .marker-art { width:60px; height:60px; margin:-12px 0 0 -6px; }

/* A call the source has retired is held for 48 hours rather than dropped, and
   reads as background until you look for it. */
.dispatch-marker--retained .marker-art { opacity:.5; }
.dispatch-marker--retained:hover .marker-art,.dispatch-marker--retained:focus .marker-art { opacity:1; }
.incident.retained { opacity:.72; border-left-color:var(--muted); }
.incident.retained:hover,.incident.retained:focus-visible { opacity:1; }

/* ---------------------------------------------------------------------------
   Header that holds still, a source status dialog, and a call list with room
   to actually read.
   --------------------------------------------------------------------------- */

/* The header was a flex row with space-between, so every time the activity line
   changed width the nav shuffled sideways. Three columns with the nav in the middle
   one means the status can say whatever it likes without moving anything. */
.topbar { display:grid !important; grid-template-columns:1fr auto 1fr; align-items:center; gap:16px; }
.topbar .brand { justify-self:start; }
.topbar nav { justify-self:center; }
.topbar .feed-state { justify-self:end; text-align:right; }

/* The activity line opens the source list, so it is a button, but it should still
   read as a status. */
button.feed-state { padding:6px 9px; border:1px solid transparent; border-radius:3px; background:transparent; font:inherit; font-size:calc(13px * var(--a11y-scale,1)); font-weight:inherit; line-height:1.25; text-align:right; cursor:pointer; }
button.feed-state:hover,button.feed-state:focus-visible { border-color:rgba(255,255,255,.35); background:rgba(255,255,255,.1); }

.source-dialog-summary { margin:0 0 4px; color:var(--muted); font-size:calc(13px * var(--a11y-scale,1)); }
.source-list { display:grid; gap:0; margin:16px 0; padding:0; list-style:none; }
.source-row { display:flex; align-items:center; justify-content:space-between; gap:14px; padding:11px 0; border-top:1px solid var(--line); }
.source-row:first-child { border-top:0; }
.source-state { flex:none; padding:3px 10px; border-radius:99px; font-size:calc(11px * var(--a11y-scale,1)); font-weight:800; letter-spacing:.08em; text-transform:uppercase; }
.source-state.online { color:#0b3d22; background:#6ece91; }
.source-state.offline { color:#3d1010; background:#f0a08f; }
body[data-theme="dark"] .source-state.online { color:#04150c; background:#6ece91; }
body[data-theme="dark"] .source-state.offline { color:#250808; background:#f0644f; }
html[data-contrast="true"] .source-state.online,html[data-contrast="true"] .source-state.offline { color:#000; background:#fff; border:2px solid #000; }

/* Accessibility sits in the same corner control on both pages now, so the nav is
   only ever the pages and nothing jumps as the header fills in. */
.page-utilities { top:14px; right:14px; }

/* The call list had up to 52px of padding top and bottom, a full-size display
   heading and a hidden scrollbar, which together left room for about two rows and
   no hint that the box scrolled at all. Everything above the table stays, it is
   just tighter, and the table keeps its scrollbar. */
.calls-shell { max-width:1280px; padding:20px clamp(16px,3vw,34px) 16px; }
.calls-shell h1 { font-size:calc(25px * var(--a11y-display-scale,1)); }
.calls-shell .eyebrow { margin:0 0 4px; }
#listSummary { max-width:none; margin:6px 0 0; font-size:calc(13px * var(--a11y-scale,1)); line-height:1.4; }
.calls-shell .search { margin:12px 0 8px; }
.calls-shell .search input { padding:9px 12px; }
.calls-shell .filters { gap:5px; }
.calls-shell .table-wrap { margin-top:12px; padding-bottom:0; scrollbar-width:thin; scrollbar-color:var(--muted) transparent; }
.calls-shell .table-wrap::-webkit-scrollbar { display:block; width:11px; }
.calls-shell .table-wrap::-webkit-scrollbar-thumb { border:3px solid transparent; border-radius:99px; background:var(--muted); background-clip:content-box; }
.calls-shell th,.calls-shell td { padding:10px 14px; }
.calls-shell thead th { position:sticky; top:0; z-index:1; background:var(--rail); box-shadow:inset 0 -1px 0 var(--line); }
body[data-theme="dark"] .calls-shell thead th { background:#101a1f; }

@media (max-width:760px) {
  .topbar { grid-template-columns:1fr auto; gap:10px; }
  .topbar nav { grid-column:1 / -1; justify-self:stretch; }
  .topbar .feed-state { justify-self:end; }
  .page-utilities { top:auto; right:14px; bottom:14px; }
  .calls-shell { padding:14px 14px 10px; }
  .calls-shell th,.calls-shell td { padding:9px 10px; }
}

/* ---------------------------------------------------------------------------
   Markers that answer to the zoom, and calls that share a point.
   --------------------------------------------------------------------------- */

/* Small enough at the full service area that a cluster is still readable, back to
   full size as you close in. The origin is the bottom centre, which is the anchor
   point, so scaling never moves a marker off its location. */
.dispatch-marker > .marker-art,.dispatch-marker > .marker-stack {
  transform:scale(calc(var(--marker-scale,1) * var(--marker-target,1)));
  transform-origin:50% 100%;
}
html[data-large-targets="true"] { --marker-target:1.25; }
html[data-large-targets="true"] .dispatch-marker .marker-art { width:48px; height:48px; margin:0; }

/* A call that has ended, or has sat over eight hours with nothing said about it. */
.marker-art.is-ghost { opacity:.45; }

.marker-stack { position:relative; display:block; width:48px; height:48px; }
.marker-stack .marker-art { position:absolute; left:0; top:0; }
.marker-stack .marker-art--behind { transform:translate(-30%,-13%) scale(.78); }
.marker-count {
  position:absolute; right:-3px; bottom:2px; z-index:2;
  display:grid; place-items:center; min-width:20px; height:20px; padding:0 5px;
  border:2px solid #fff; border-radius:99px; background:#13212b; color:#fff;
  font:800 11px/1 Inter,system-ui,sans-serif;
  box-shadow:0 1px 3px rgba(0,0,0,.5);
}
body[data-theme="dark"] .marker-count { border-color:#e6edef; background:#0a1013; }

/* The popup for a shared point lists every call on it, most recent first. */
.incident-popup--stack { gap:5px; max-width:240px; }
.popup-stack { display:grid; gap:2px; max-height:220px; overflow:auto; margin:4px 0 0; padding:0; list-style:none; }
.popup-stack-row { display:flex; gap:8px; align-items:center; padding:6px 5px; border-top:1px solid var(--line); cursor:pointer; }
.popup-stack-row:first-child { border-top:0; }
.popup-stack-row:hover,.popup-stack-row:focus-visible { background:var(--soft); }
.popup-stack-row.ghost { opacity:.55; }
.popup-stack-row.ghost:hover { opacity:1; }
.popup-stack-icon { flex:none; width:26px; height:26px; object-fit:contain; }
.popup-stack-row span { display:grid; gap:1px; min-width:0; }
.popup-stack-row strong { font-size:calc(11px * var(--a11y-scale,1)); line-height:1.25; }
.popup-stack-row small { color:var(--muted); font-size:calc(10px * var(--a11y-scale,1)); }
html[data-large-targets="true"] .popup-stack-row { padding:10px 6px; }

/* Closed calls are retained either way. This only decides whether the map draws them,
   because 48 hours of history turns the default view into mostly history. */
.closed-toggle { display:flex; gap:8px; align-items:flex-start; margin:0 0 10px; color:var(--muted); font-size:calc(12px * var(--a11y-scale,1)); line-height:1.35; cursor:pointer; }
.closed-toggle input { margin-top:2px; flex:none; }
html[data-large-targets="true"] .closed-toggle { padding:6px 0; }
