/* Light palette on :root; the dark one replaces only these tokens, either from
   the OS setting or from the header toggle (data-theme on <html>). The toggle
   wins in both directions: an explicit "light" beats a dark OS. */
:root {
  --ink: #1f2933;
  --ink-body: #333d47;
  --ink-soft: #52606d;
  --ink-faint: #9aa5b1;
  --rule: #e4e7eb;
  --rule-soft: #f0f2f4;
  --bg: #ffffff;
  --bg-soft: #f5f7fa;
  --bg-hover: #eef2f6;
  --field-border: #ccc;
  --link: #37628f;
  --warn: #c0392b;
  --caution: #b9770e;
  --good: #1e8449;
  --error-ink: #b34040;
  --error-bg: #fdf2f2;
  --focus: #2f6feb;
  --header-bg: #1f2933;
  --swatch-ring: transparent;
  --header-h: 48px;
  --panel-shadow: 0 2px 8px rgba(0, 0, 0, .15);
  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #e4e7eb;
    --ink-body: #cfd6dd;
    --ink-soft: #aab4be;
    --ink-faint: #7b8794;
    --rule: #323c47;
    --rule-soft: #28313b;
    --bg: #1a2028;
    --bg-soft: #222a33;
    --bg-hover: #2a343f;
    --field-border: #46525e;
    --link: #8ab8e6;
    --warn: #f07465;
    --caution: #e5a443;
    --good: #5cc98a;
    --error-ink: #f4a6a0;
    --error-bg: #3a2326;
    --focus: #6ea8ff;
    --header-bg: #11161c;
    --swatch-ring: rgba(255, 255, 255, .35);
    --panel-shadow: 0 2px 10px rgba(0, 0, 0, .5);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --ink: #e4e7eb;
  --ink-body: #cfd6dd;
  --ink-soft: #aab4be;
  --ink-faint: #7b8794;
  --rule: #323c47;
  --rule-soft: #28313b;
  --bg: #1a2028;
  --bg-soft: #222a33;
  --bg-hover: #2a343f;
  --field-border: #46525e;
  --link: #8ab8e6;
  --warn: #f07465;
  --caution: #e5a443;
  --good: #5cc98a;
  --error-ink: #f4a6a0;
  --error-bg: #3a2326;
  --focus: #6ea8ff;
  --header-bg: #11161c;
  --swatch-ring: rgba(255, 255, 255, .35);
  --panel-shadow: 0 2px 10px rgba(0, 0, 0, .5);
  color-scheme: dark;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* A single visible focus indicator for everything interactive. :focus-visible
   rather than :focus, so it appears for keyboard use without ringing every
   mouse click. The browser default is suppressed by the reset above on some
   controls, which left keyboard users with nothing at all. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
/* Inset, so the ring isn't clipped by the scrolling list that contains it.
   :has(:focus-visible) rather than :focus-within, which would also fire on a
   mouse click. */
.nearby-item:focus-visible,
.layer-group label:has(input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

html, body {
  height: 100%;
  font-family: var(--font);
  color: var(--ink);
  background: var(--bg);
}

body {
  display: flex;
  flex-direction: column;
}

/* --- Site header --- */

.site-header {
  flex: 0 0 auto;
  height: var(--header-h);
  background: var(--header-bg);
  color: #f0f4f8;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 16px;
  z-index: 10;
}
.site-header .brand {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
}
.site-header .tagline {
  font-size: 12px;
  color: #9aa5b1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.site-header nav {
  margin-left: auto;
  display: flex;
  gap: 4px;
}
.site-header nav a {
  font-size: 13px;
  color: #cbd2d9;
  text-decoration: none;
  padding: 6px 10px;
  border-radius: 5px;
  white-space: nowrap;
}
.site-header nav a:hover { background: rgba(255, 255, 255, .1); color: #fff; }
.site-header nav a[aria-current="page"] { background: rgba(255, 255, 255, .16); color: #fff; }

/* Same icon in both states: a half-filled circle, the usual light/dark mark. */
#theme-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: 4px;
  border: none;
  border-radius: 5px;
  background: none;
  color: #cbd2d9;
  cursor: pointer;
}
#theme-toggle:hover { background: rgba(255, 255, 255, .1); color: #fff; }
#theme-toggle svg { width: 16px; height: 16px; }

/* For a heading that search engines and screen readers need but sighted
   visitors would only see duplicated by the map page itself. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- Map page --- */

#map-wrap {
  flex: 1 1 auto;
  position: relative;
  min-height: 0;
}
#map { position: absolute; inset: 0; }
.noscript {
  position: absolute;
  inset: 40% 16px auto;
  z-index: 3;
  max-width: 28rem;
  margin: 0 auto;
  padding: 12px 16px;
  border-radius: 8px;
  background: var(--bg);
  box-shadow: var(--panel-shadow);
  font-size: 14px;
  line-height: 1.5;
}
.noscript a { color: var(--link); }

#controls {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 1;
  background: var(--bg);
  border-radius: 8px;
  padding: 12px 16px;
  box-shadow: var(--panel-shadow);
  font-size: 13px;
  max-height: calc(100% - 24px);
  width: 260px;
  display: flex;
  flex-direction: column;
}
/* Scrolls on its own so the collapse button stays pinned to the corner. */
#controls-body { overflow-y: auto; min-height: 0; }

#collapse-controls {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--rule);
  border-radius: 5px;
  background: var(--bg);
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
#collapse-controls:hover { background: var(--bg-soft); color: var(--ink); }
#collapse-controls::before { content: '\00AB'; }  /* « */

/* Collapsed: shrink to just the button, tucked against the left margin. */
#controls.collapsed {
  width: auto;
  padding: 0;
  border-radius: 6px;
}
#controls.collapsed #controls-body { display: none; }
#controls.collapsed #collapse-controls {
  position: static;
  width: 30px;
  height: 30px;
  border: none;
  font-size: 14px;
}
#controls.collapsed #collapse-controls::before { content: '\00BB'; }  /* » */

/* Leave room for the collapse button so it never sits over the Go button. */
#search-form { display: flex; margin-bottom: 10px; padding-right: 30px; }
#search-input {
  flex: 1;
  min-width: 0;
  padding: 7px 10px;
  border: 1px solid var(--field-border);
  border-radius: 5px 0 0 5px;
  background: var(--bg);
  color: var(--ink);
  font-size: 13px;
  outline: none;
}
#search-input:focus { border-color: var(--ink-faint); }
#search-btn {
  padding: 7px 12px;
  border: 1px solid var(--field-border);
  border-left: none;
  border-radius: 0 5px 5px 0;
  background: var(--bg-soft);
  color: var(--ink);
  font-size: 13px;
  cursor: pointer;
}
#search-btn:hover { background: var(--bg-hover); }

#locate-btn {
  width: 100%;
  padding: 6px 10px;
  margin-bottom: 8px;
  border: 1px solid var(--rule);
  border-radius: 5px;
  background: var(--bg);
  color: var(--link);
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
}
#locate-btn:hover:not(:disabled) { background: var(--bg-soft); }
#locate-btn:disabled { color: var(--ink-faint); cursor: default; }

#search-result {
  font-size: 12px;
  color: var(--ink-body);
  margin-bottom: 8px;
  display: none;
}
#search-result .matched-addr { font-weight: 600; margin-bottom: 4px; }
/* Was a span; now a real button, so the chrome needs stripping back. */
#clear-search {
  border: none;
  background: none;
  padding: 0;
  color: var(--link);
  cursor: pointer;
  font-size: 11px;
  font-family: inherit;
}
#clear-search:hover { text-decoration: underline; }

#radius-row {
  display: none;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 12px;
}
#radius-row label { color: var(--ink-soft); white-space: nowrap; }
#radius-select {
  padding: 3px 6px;
  border: 1px solid var(--field-border);
  border-radius: 4px;
  background: var(--bg);
  color: var(--ink);
  font-size: 12px;
}

#search-error {
  display: none;
  font-size: 12px;
  color: var(--error-ink);
  background: var(--error-bg);
  border-radius: 4px;
  padding: 8px 10px;
  margin-bottom: 8px;
  line-height: 1.4;
}
#search-error .hint { color: var(--ink-soft); font-size: 11px; margin-top: 4px; }

.divider { border: none; border-top: 1px solid var(--rule); margin: 8px 0; }

#layer-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}
#layer-header { font-size: 11px; color: var(--ink-faint); }
#toggle-all {
  border: none;
  background: none;
  padding: 0;
  font-size: 11px;
  font-family: inherit;
  color: var(--link);
  cursor: pointer;
}
#toggle-all:hover { text-decoration: underline; }

.layer-group { margin-bottom: 2px; }
.layer-group label {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 0;
  cursor: pointer;
  user-select: none;
}
.layer-group input[type="checkbox"] { accent-color: var(--ink-soft); }
.layer-group.sub { padding-left: 18px; font-size: 12px; }
.layer-group.sub .swatch { width: 8px; height: 8px; }
/* The ring keeps near-black categories (greenhouse gas) visible on the dark panel. */
.swatch { display: inline-block; width: 10px; height: 10px; border-radius: 50%; box-shadow: 0 0 0 1px var(--swatch-ring); }
.count {
  color: var(--ink-faint);
  font-size: 11px;
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

#status {
  position: absolute;
  bottom: 12px;
  left: 12px;
  z-index: 1;
  background: var(--bg);
  border-radius: 6px;
  padding: 6px 12px;
  box-shadow: var(--panel-shadow);
  font-size: 12px;
  color: var(--ink-soft);
}

.search-pin {
  width: 16px;
  height: 16px;
  background: #111;
  border: 3px solid #fff;
  border-radius: 50%;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .3);
}

/* --- Nearby results panel --- */

#nearby-panel {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
  background: var(--bg);
  border-radius: 8px;
  box-shadow: var(--panel-shadow);
  width: 290px;
  max-height: calc(100% - 24px);
  display: none;
  flex-direction: column;
  overflow: hidden;
}
#nearby-head {
  padding: 10px 14px;
  border-bottom: 1px solid var(--rule);
  font-size: 12px;
  font-weight: 700;
  flex: 0 0 auto;
}
#nearby-head .sub {
  font-weight: 400;
  color: var(--ink-faint);
  font-size: 11px;
  margin-top: 2px;
}
#nearby-summary {
  flex: 0 0 auto;
  padding: 10px 14px 11px;
  border-bottom: 1px solid var(--rule);
  background: var(--bg-soft);
}
#nearby-summary:empty { display: none; }
.sum-row {
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.5;
  display: flex;
  gap: 5px;
  align-items: baseline;
}
.sum-row b {
  font-weight: 700;
  font-size: 13px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* Severity shows in the number, so the eye lands on it before the words. */
.sum-row.bad b  { color: var(--warn); }
.sum-row.warn b { color: var(--caution); }
.sum-row.ok     { color: var(--good); }

/* min-height:0 lets this shrink below content size so it scrolls instead of
   overflowing the panel's max-height */
#nearby-list { overflow-y: auto; min-height: 0; }

/* A button styled as a list row: full width, left aligned, no native chrome. */
.nearby-item {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  width: 100%;
  padding: 8px 14px;
  border: none;
  border-bottom: 1px solid var(--rule-soft);
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.nearby-item:hover { background: var(--bg-hover); }
.nearby-item:last-child { border-bottom: none; }
.nearby-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-top: 4px;
  flex: 0 0 auto;
}
.nearby-body { flex: 1; min-width: 0; }
/* Spans rather than divs, since a button may only hold phrasing content. */
.nearby-name, .nearby-meta, .nearby-flag { display: block; }
.nearby-name {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--ink);
}
.nearby-meta {
  color: var(--ink-soft);
  font-size: 11px;
  margin-top: 1px;
  font-variant-numeric: tabular-nums;
}
.nearby-flag {
  color: var(--warn);
  font-size: 11px;
  font-weight: 500;
  margin-top: 2px;
}
.nearby-note {
  padding: 10px 14px;
  font-size: 11px;
  color: var(--ink-faint);
  text-align: center;
}

/* --- Popups --- */

.maplibregl-popup-content {
  font-family: var(--font);
  font-size: 13px;
  padding: 12px 16px;
  max-width: 300px;
  background: var(--bg);
  color: var(--ink);
}
.popup-name { font-weight: 700; font-size: 14px; margin-bottom: 4px; }
.popup-address { color: var(--ink-soft); margin-bottom: 6px; }
.popup-dist { color: var(--ink-faint); font-size: 12px; margin-bottom: 6px; }
.popup-layers { margin-bottom: 6px; }
.popup-layers span {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 11px;
  font-weight: 600;
  color: #fff;
  margin-right: 3px;
  margin-bottom: 2px;
}
.popup-osm { font-size: 11px; color: var(--ink-soft); margin-bottom: 6px; line-height: 1.5; }
.popup-osm a { color: var(--link); }
.popup-compliance { font-size: 11px; margin-bottom: 6px; line-height: 1.5; }
/* Kept faint and tight against the compliance block above, so it reads as a
   footnote on that status rather than as another fact about the facility. */
.popup-compliance:has(+ .popup-asof) { margin-bottom: 2px; }
.popup-asof {
  font-size: 10px;
  color: var(--ink-faint);
  margin-bottom: 6px;
}
.popup-loading { color: var(--ink-faint); font-size: 12px; padding: 2px 0; }
.popup-source { font-size: 11px; color: var(--ink-faint); }
.popup-source a { color: var(--link); }

/* MapLibre's own chrome is styled for a white map. Its tip is a CSS border
   triangle, so the color goes on whichever side faces the content. */
.maplibregl-popup-anchor-top .maplibregl-popup-tip,
.maplibregl-popup-anchor-top-left .maplibregl-popup-tip,
.maplibregl-popup-anchor-top-right .maplibregl-popup-tip { border-bottom-color: var(--bg); }
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip,
.maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip,
.maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip { border-top-color: var(--bg); }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--bg); }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--bg); }
.maplibregl-popup-close-button { color: var(--ink-soft); }

.maplibregl-ctrl-group { background: var(--bg); }
.maplibregl-ctrl-group button + button { border-top-color: var(--rule); }
.maplibregl-ctrl-group button:not(:disabled):hover { background-color: var(--bg-hover); }
.maplibregl-ctrl.maplibregl-ctrl-attrib,
.maplibregl-ctrl-attrib.maplibregl-compact { background: var(--bg); color: var(--ink-soft); }
.maplibregl-ctrl-attrib a { color: var(--ink-soft); }
/* The zoom, compass and attribution icons are dark SVGs baked into MapLibre's
   stylesheet, so they can only be inverted, not recolored. */
:root[data-theme="dark"] .maplibregl-ctrl-icon,
:root[data-theme="dark"] .maplibregl-ctrl-attrib-button { filter: invert(1); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .maplibregl-ctrl-icon,
  :root:not([data-theme="light"]) .maplibregl-ctrl-attrib-button { filter: invert(1); }
}

/* --- Content pages (about, data) --- */

.page {
  flex: 1 1 auto;
  overflow-y: auto;
}
.page-inner {
  max-width: 44rem;
  margin: 0 auto;
  padding: 36px 20px 56px;
}
.page h1 {
  font-size: 26px;
  letter-spacing: -0.02em;
  margin-bottom: 6px;
}
.page .lede {
  font-size: 15px;
  color: var(--ink-soft);
  line-height: 1.6;
  margin-bottom: 28px;
}
.page h2 {
  font-size: 16px;
  margin: 32px 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--rule);
}
.page h3 { font-size: 14px; margin: 20px 0 6px; }
.page p, .page li {
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-body);
}
.page p { margin-bottom: 12px; }
.page ul, .page ol { margin: 0 0 12px 20px; }
.page li { margin-bottom: 5px; }
.page a { color: var(--link); }
.page code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  background: var(--bg-soft);
  padding: 1px 5px;
  border-radius: 3px;
}
.page strong { font-weight: 650; }

.callout {
  background: var(--bg-soft);
  border-left: 3px solid var(--ink-faint);
  border-radius: 0 4px 4px 0;
  padding: 12px 16px;
  margin: 0 0 16px;
}
.callout p:last-child { margin-bottom: 0; }

table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-bottom: 16px;
}
table.data th, table.data td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
}
table.data th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--ink-soft);
  border-bottom: 2px solid var(--rule);
  white-space: nowrap;
}
table.data td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.table-scroll { overflow-x: auto; }

.page-inner p.contact {
  font-size: 15px;
  font-weight: 600;
  margin-top: -4px;
}

/* --- Footer --- */

.site-footer {
  flex: 0 0 auto;
  border-top: 1px solid var(--rule);
  background: var(--bg-soft);
  padding: 20px;
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.6;
}
.site-footer .footer-inner {
  max-width: 44rem;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  justify-content: space-between;
}
.site-footer a { color: var(--link); }
.site-footer .attribution { max-width: 30rem; }

/* The map page can't carry the full footer — every pixel here is taken from the
   map itself — so it gets a single slim strip instead. */
.map-disclaimer {
  flex: 0 0 auto;
  border-top: 1px solid var(--rule);
  background: var(--bg-soft);
  padding: 6px 14px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--ink-soft);
  text-align: center;
}
.map-disclaimer a { color: var(--link); white-space: nowrap; }

/* --- Phone layout --- */

/* At desktop widths the results panel is a column pinned right, so it needs no
   grab bar. */
#nearby-collapse { display: none; }

@media (max-width: 640px) {
  /* The two panels were 260px pinned left and 290px pinned right — 574px of
     furniture on a ~390px screen, so opening the filters put them on top of
     each other. The results become a bottom sheet instead: full width, owning
     the lower half, while the filters keep the upper left. */
  #nearby-panel {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: auto;
    max-height: 45%;
    border-radius: 12px 12px 0 0;
  }

  /* Collapsed hides the list but keeps the header and the summary, because the
     summary is where the counts are: collapsed is then still informative
     rather than a stub, and the map gets most of the screen back without
     clearing the search and losing the results. */
  #nearby-panel.sheet-collapsed { max-height: none; }
  #nearby-panel.sheet-collapsed #nearby-list { display: none; }

  /* The grab bar is small, so the header is a tap target too (wired up in
     panels.js) — that is most of the sheet's width. */
  #nearby-head { cursor: pointer; }

  #nearby-collapse {
    display: block;
    flex: 0 0 auto;
    width: 100%;
    padding: 9px 0 5px;
    border: none;
    background: none;
    cursor: pointer;
  }
  /* Drawn as a pseudo-element: a button may only contain phrasing content, so
     the bar cannot be a child div. */
  #nearby-collapse::before {
    content: '';
    display: block;
    width: 36px;
    height: 4px;
    margin: 0 auto;
    border-radius: 2px;
    background: var(--ink-faint);
  }

  /* Hold an expanded filter list to the top so it cannot reach into the sheet
     or the status line below it, and keep it above both in the stack — while
     you are working the filters, that is what you want to see. The vertical
     budget is 44% filters + ~5% status + 45% sheet, which leaves a margin
     rather than meeting exactly. */
  #controls {
    max-height: 44%;
    z-index: 2;
  }

  /* The status line stays bottom-left and is lifted clear of the sheet instead.
     Moving it to the top right put it opposite the filter panel at the same
     top offset, and on a ~390px screen an expanded panel (12-272px) and a
     status line like "16,140 facilities in view" (about 201-381px) overlap by
     70px. Bottom-left collides with nothing: the filters are top-left and
     MapLibre's controls are bottom-right.

     Offsets mirror the ones used for the map controls below. */
  #status { max-width: calc(100% - 24px); }
  #map-wrap.sheet-open #status { bottom: calc(45% + 12px); }
  #map-wrap.sheet-open:has(#nearby-panel.sheet-collapsed) #status { bottom: 162px; }

  /* Keep MapLibre's zoom buttons and the basemap credit clear of the sheet:
     attribution that is covered is attribution that isn't given. The collapsed
     offset is an approximation of grab bar + header + summary — erring high,
     since a little extra gap looks fine and a short one hides the credit. */
  #map-wrap.sheet-open .maplibregl-ctrl-bottom-right { bottom: 45%; }
  #map-wrap.sheet-open:has(#nearby-panel.sheet-collapsed)
    .maplibregl-ctrl-bottom-right { bottom: 150px; }
}
