/* Page fonts, self-hosted (SIL Open Font License; Latin subset). Public Sans is one variable file covering weights 400-800. */
@font-face { font-family: "Public Sans"; font-style: normal; font-weight: 400 800; font-display: swap; src: url(../fonts/ui/PublicSans-latin-var.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(../fonts/ui/IBMPlexMono-400-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(../fonts/ui/IBMPlexMono-500-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 600; font-display: swap; src: url(../fonts/ui/IBMPlexMono-600-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

/* Layout: full-screen map with a fixed tool cluster (upper right on computers,
   lower left on touchscreens), and the selected-ZIP panel on the right (a bottom
   sheet on phones).
   Look: a surveyor's paper map marked up with a yellow highlighter. */
:root {
  --paper: #f2f4f1;
  --panel: #fbfcfa;
  --ink: #1b2420;
  --muted: #5a6560;
  --rule: #d5dcd7;
  --grip: #cfd6d1; --grip-hover: #c1c9c4;   /* the drag-handle cell on floating boxes */
  --accent: #1d6b58;          /* interactive controls */
  --accent-ink: #ffffff;
  --hl: #f4b400;              /* highlighter: selected ZIPs */
  --hl-strong: #9a6c00;
  --hl-soft: #fff1c2;
  --remove: #c23b26;
  --remove-soft: #fbe3de;
  --map-water: #c5d5dc;
  --map-land: #e8ede5;
  --map-land-other: #d9ded6;
  /* Map label colors are picked to tell apart at a glance: counties violet (lines and names),
     cities blue, ZIPs neutral grey (lines and numbers). Avoid yellow, red, teal and light blue,
     which mean selected, remove, controls and water. */
  --map-zip-line: #989da1;
  --map-county: #6b3fb0;
  --map-hover: #8fb7a9;
  --map-label: #5d6266;
  --map-city: #1c5bb0;
  --map-capital: #0f3f85;     /* state capitals: a deeper city blue, in bold */
  --map-halo: #f4f6f2;
  --map-point: #5d6b64;
  --map-road: #ffffff;        /* street map: light streets with a grey outline */
  --map-road-casing: #c4ccc6;
  --map-highway: #fbfbf8;
  --map-highway-casing: #929d97;
  --map-road-label: #59645e;
  --shape-on: #33403a;       /* the chosen shape (Circle or Lasso) */
  --shape-on-ink: #ffffff;
  --shadow: 0 1px 2px rgba(22, 32, 28, .12), 0 6px 18px rgba(22, 32, 28, .12);
  --font-ui: "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --radius: 10px;
  --panel-w: 360px;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #121816; --panel: #171e1b; --ink: #e5ebe7; --muted: #9aa69f; --rule: #2a3430; --grip: #34403a; --grip-hover: #3f4c46;
    --accent: #5ec3a5; --accent-ink: #0e1714; --hl: #f6bd1f; --hl-strong: #ffd666; --hl-soft: #3a3213;
    --remove: #f07058; --remove-soft: #3d1f1a;
    --map-water: #0d1518; --map-land: #1d2521; --map-land-other: #161c19; --map-zip-line: #5b6064;
    --map-county: #c4a3f5; --map-hover: #3f6b5d; --map-label: #abafb3; --map-city: #8db8ff;
    --map-capital: #b9d3ff;
    --map-halo: #141a17; --map-point: #9aa69f; --shape-on: #5b6d64; --shape-on-ink: #ffffff;
    --map-road: #36423c; --map-road-casing: #1d2521; --map-highway: #56645d; --map-highway-casing: #141a17; --map-road-label: #a3afa8;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 22px rgba(0, 0, 0, .35);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --paper: #121816; --panel: #171e1b; --ink: #e5ebe7; --muted: #9aa69f; --rule: #2a3430; --grip: #34403a; --grip-hover: #3f4c46;
  --accent: #5ec3a5; --accent-ink: #0e1714; --hl: #f6bd1f; --hl-strong: #ffd666; --hl-soft: #3a3213;
  --remove: #f07058; --remove-soft: #3d1f1a;
  --map-water: #0d1518; --map-land: #1d2521; --map-land-other: #161c19; --map-zip-line: #5b6064;
  --map-county: #c4a3f5; --map-hover: #3f6b5d; --map-label: #abafb3; --map-city: #8db8ff;
  --map-capital: #b9d3ff;
  --map-halo: #141a17; --map-point: #9aa69f; --shape-on: #5b6d64; --shape-on-ink: #ffffff;
  --map-road: #36423c; --map-road-casing: #1d2521; --map-highway: #56645d; --map-highway-casing: #141a17; --map-road-label: #a3afa8;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 22px rgba(0, 0, 0, .35);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body { margin: 0; background: var(--paper); color: var(--ink); font: 14px/1.45 var(--font-ui); overflow-x: hidden; }   /* the app fills the first screen; the About text scrolls in below it */
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
[hidden] { display: none !important; }

.app {
  height: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--panel-w);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "top top" "stage panel";
}

/* ---------- top bar ---------- */
.topbar {
  grid-area: top; display: flex; align-items: center; gap: 16px;
  padding-block: 10px; padding-left: max(16px, env(safe-area-inset-left, 0px)); padding-right: max(16px, env(safe-area-inset-right, 0px));
  padding-top: max(10px, env(safe-area-inset-top, 0px));
  background: var(--panel); border-bottom: 1px solid var(--rule); position: relative; z-index: 10;
}
.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand-mark { width: 30px; height: 30px; flex: none; }
/* Logo: a magnifier over "ZIP". The letters stay dark on the yellow lens in both themes. */
.brand-mark .lens { fill: var(--hl); stroke: var(--ink); stroke-width: 2; }
.brand-mark .handle { stroke: var(--ink); stroke-width: 4.5; stroke-linecap: round; }
.brand-mark .zip { fill: #1b2420; font: 800 9px Arial, Helvetica, sans-serif; }
/* An <h1> that reads as one sentence ("ZipZoomer U.S. ZIP code map: ..."), drawn as the two-line brand. */
.brand-text { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; margin: 0; font-size: inherit; font-weight: inherit; }
/* Shortens with "…" rather than pushing "Help" off a phone screen (larger text sizes). */
.brand-name { font-weight: 800; letter-spacing: -.01em; font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The tagline is long: it shortens with "…" when the search box needs the room (full text on hover). */
.brand-sub { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search { position: relative; flex: 1; max-width: 460px; margin-left: auto; }
.search input {
  width: 100%; height: 38px; padding: 0 12px; border-radius: 8px; border: 1px solid var(--rule);
  background: var(--paper); font-family: var(--font-ui);
}
.search input::placeholder { color: var(--muted); }
.results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; margin: 0; padding: 4px; list-style: none;
  background: var(--panel); border: 1px solid var(--rule); border-radius: var(--radius); box-shadow: var(--shadow);
  max-height: min(60vh, 420px); overflow-y: auto; z-index: 20;
}
.results li { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 6px; cursor: pointer; }
.results li[aria-selected="true"], .results li:hover { background: var(--paper); }
.results .r-main { flex: 1; min-width: 0; }
.results .r-title { font-weight: 600; }
.results .r-zip { font-family: var(--font-mono); font-weight: 600; }
.results .r-sub { color: var(--muted); font-size: 12px; }
.results .r-act { display: flex; gap: 6px; flex: none; }
.results .r-empty { color: var(--muted); cursor: default; }
.chip-btn {
  border: 1px solid var(--rule); background: var(--panel); border-radius: 999px; padding: 2px 10px; font-size: 12px; font-weight: 600;
}
.chip-btn.add { border-color: var(--hl-strong); }
.chip-btn.rem { color: var(--remove); }
.ghost-btn { border: 1px solid var(--rule); background: transparent; border-radius: 8px; height: 38px; padding: 0 12px; font-weight: 600; white-space: nowrap; }
.list-btn { display: none; }   /* phones only (see the phone block) */
.list-btn b { font-family: var(--font-mono); background: var(--hl-soft); padding: 0 4px; border-radius: 3px; }
.list-btn[aria-expanded="true"] { background: var(--shape-on); border-color: var(--shape-on); color: var(--shape-on-ink); }
.list-btn[aria-expanded="true"] b { background: transparent; }

/* ---------- map stage ---------- */
.stage { grid-area: stage; position: relative; min-width: 0; min-height: 0; }
.map { position: absolute; inset: 0; background: var(--map-water); }
.map .maplibregl-canvas-container, .map canvas { touch-action: none; }
/* Hand cursor normally. While selecting: a crosshair with a + (add) or − (remove) badge. */
.map.selecting[data-act="add"] .maplibregl-canvas-container,
.map.selecting[data-act="add"] .maplibregl-canvas-container.maplibregl-interactive,
.map.selecting[data-act="add"] .maplibregl-canvas-container.maplibregl-interactive:active,
.map.selecting[data-act="add"] .maplibregl-canvas-container.maplibregl-interactive.maplibregl-track-pointer { cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M11 1v20M1 11h20' stroke='white' stroke-width='3.5'/%3E%3Cpath d='M11 1v20M1 11h20' stroke='%231b2420' stroke-width='1.5'/%3E%3Ccircle cx='24' cy='24' r='7' fill='%23f4b400' stroke='%231b2420' stroke-width='1.5'/%3E%3Cpath d='M20.5 24h7M24 20.5v7' stroke='%231b2420' stroke-width='2.2'/%3E%3C/svg%3E") 11 11, crosshair; }
.map.selecting[data-act="remove"] .maplibregl-canvas-container,
.map.selecting[data-act="remove"] .maplibregl-canvas-container.maplibregl-interactive,
.map.selecting[data-act="remove"] .maplibregl-canvas-container.maplibregl-interactive:active,
.map.selecting[data-act="remove"] .maplibregl-canvas-container.maplibregl-interactive.maplibregl-track-pointer { cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M11 1v20M1 11h20' stroke='white' stroke-width='3.5'/%3E%3Cpath d='M11 1v20M1 11h20' stroke='%231b2420' stroke-width='1.5'/%3E%3Ccircle cx='24' cy='24' r='7' fill='%23c23b26' stroke='%231b2420' stroke-width='1.5'/%3E%3Cpath d='M20.5 24h7' stroke='white' stroke-width='2.2'/%3E%3C/svg%3E") 11 11, crosshair; }
.loading {
  position: absolute; inset: 0; display: grid; place-items: center; color: var(--muted); font-weight: 600;
  background: var(--map-water); z-index: 3;
}
.maplibregl-ctrl-attrib { font-size: 11px; }
.maplibregl-ctrl-group { background: var(--panel) !important; box-shadow: var(--shadow) !important; }
.maplibregl-ctrl-group button + button { border-top-color: var(--rule) !important; }
:root[data-theme="dark"] .maplibregl-ctrl-icon { filter: invert(1); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .maplibregl-ctrl-icon { filter: invert(1); } }

/* ---------- tool cluster: zoom buttons + selection toolbar ----------
   Computers: the map's upper-right corner, toolbar to the left of the zoom
   buttons. Touchscreens: the lower-left corner, zoom buttons on the left (see
   the touchscreen block at the end). */
.tools {
  position: absolute; z-index: 4;
  top: 10px; right: max(10px, env(safe-area-inset-right, 0px));
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
.tool-row { display: flex; flex-direction: row-reverse; align-items: stretch; gap: 8px; }
/* MapLibre's zoom buttons, stretched to the toolbar's height. */
.zoom-slot { display: flex; }
.zoom-slot .maplibregl-ctrl-group { display: flex; flex-direction: column; border: 1px solid var(--rule); border-radius: 14px; overflow: hidden; }
.zoom-slot .maplibregl-ctrl-group button { flex: 1; width: 40px; height: auto; touch-action: manipulation; }
.maplibregl-ctrl-bottom-right { bottom: var(--sheet-offset, 0px); }
.seg {
  margin: 0; padding: 4px; border: 1px solid var(--rule); border-radius: var(--radius); background: var(--panel);
  display: flex; gap: 2px; min-width: 0;
}
.seg label {
  position: relative; display: flex; align-items: center; gap: 7px; padding: 7px 11px 7px 9px; border-radius: 7px;
  font-weight: 600; cursor: pointer; white-space: nowrap;
}
.seg input { position: absolute; opacity: 0; pointer-events: none; }
.seg-dot { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--muted); flex: none; display: grid; place-items: center; }
.seg-dot::after { content: ""; width: 6px; height: 6px; border-radius: 50%; background: transparent; }
.seg input:checked + .seg-dot { border-color: var(--accent); }
.seg input:checked + .seg-dot::after { background: var(--accent); }
.seg label:has(input:checked) { background: var(--paper); box-shadow: inset 0 0 0 1px var(--rule); }
.seg input:focus-visible + .seg-dot { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- selection toolbar: shape switch + Add / Remove buttons ---------- */
.toolbar {
  display: grid; grid-template-columns: auto auto auto; align-items: stretch; gap: 6px; padding: 6px;
  background: var(--panel); border: 1px solid var(--rule); border-radius: 14px; box-shadow: var(--shadow);
}
.shapes { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.shape {
  position: relative; flex: 1; display: flex; align-items: center; gap: 7px; padding: 0 12px 0 9px; min-height: 40px;
  border-radius: 9px; font-weight: 600; cursor: pointer; color: var(--muted); border: 1px solid transparent;
}
.shape input { position: absolute; opacity: 0; pointer-events: none; }
.shape svg { width: 20px; height: 20px; flex: none; }
.shape svg * { fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.shape svg .dot { fill: currentColor; stroke: none; }
.shape:hover { color: var(--ink); }
.shape:has(input:checked) { color: var(--shape-on-ink); background: var(--shape-on); border-color: var(--shape-on); }
.shape:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Edge rule (Touching / Center in / Fully in): a full-width row under the shape and Add / Remove. */
.edges {
  grid-column: 1 / -1; margin: 0; padding: 6px 0 0; border: 0; border-top: 1px solid var(--rule);
  display: flex; gap: 3px; min-width: 0;
}
.edge {
  position: relative; flex: 1; display: flex; align-items: center; justify-content: center; gap: 4px;
  min-height: 30px; padding: 0 5px; border-radius: 8px; border: 1px solid transparent;
  font-weight: 600; font-size: 12px; white-space: nowrap; cursor: pointer; color: var(--muted);
}
.edge input { position: absolute; opacity: 0; pointer-events: none; }
.edge svg { width: 18px; height: 18px; flex: none; }
.edge svg * { fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linejoin: round; }
.edge svg .ring { stroke-dasharray: 2.4 1.8; }
.edge svg .dot { fill: currentColor; stroke: none; }
.edge:hover { color: var(--ink); }
.edge:has(input:checked) { color: var(--shape-on-ink); background: var(--shape-on); border-color: var(--shape-on); }
.edge:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 1px; }

.act {
  position: relative; width: 92px; flex: none; border-radius: 11px; border: 1.5px solid var(--rule);
  background: var(--panel); color: var(--ink);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 8px 6px;
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
  transition: background-color .1s, border-color .1s, color .1s;
}
.act:hover { border-color: var(--muted); }
.act-sign { font: 600 24px/1 var(--font-mono); }
.act-label { font-weight: 800; font-size: 14px; line-height: 1.2; }
/* Room for two lines, so the button doesn't change size when its text does. */
.act-hint {
  font: 600 11px/1.2 var(--font-ui); letter-spacing: .01em; color: var(--muted);
  white-space: pre-line; text-align: center; min-height: 2.4em; display: grid; place-items: center;
}
.act[data-action="add"] .act-sign { color: var(--hl-strong); }
.act[data-action="remove"] .act-sign { color: var(--remove); }
.act.on[data-action="add"] { background: var(--hl); border-color: var(--hl-strong); }
.act.on[data-action="remove"] { background: var(--remove); border-color: var(--remove); }
.act.on[data-action="add"], .act.on[data-action="add"] .act-sign, .act.on[data-action="add"] .act-hint { color: #1b2420; }
.act.on[data-action="remove"], .act.on[data-action="remove"] .act-sign, .act.on[data-action="remove"] .act-hint { color: #ffffff; }
.act .lock { position: absolute; top: 6px; right: 6px; width: 14px; height: 14px; display: none; }
.act .lock * { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.act .lock rect { fill: currentColor; }
.act.locked .lock { display: block; }

/* ---------- undo / redo: the map's upper-left corner ---------- */
/* Solid arrows when there is something to undo or redo, grey when not. */
.history {
  position: absolute; z-index: 4; top: 10px; left: max(10px, env(safe-area-inset-left, 0px));
  display: flex; background: var(--panel); border: 1px solid var(--rule); border-radius: 12px;
  box-shadow: var(--shadow); overflow: hidden;
}
.history button {
  width: 42px; height: 40px; display: grid; place-items: center; padding: 0; border: 0;
  background: none; color: var(--ink); touch-action: manipulation;
}
.history button + button { border-left: 1px solid var(--rule); }
.history button:not(:disabled):hover { background: var(--paper); }
.history button:disabled { color: var(--muted); opacity: .4; cursor: default; }
.history svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- zoom panel (zoomdebug.js; press D): below undo / redo ---------- */
.zoomdbg {
  position: absolute; z-index: 5; top: 60px; left: max(10px, env(safe-area-inset-left, 0px));
  width: 310px; max-width: calc(100% - 20px); max-height: calc(100% - 140px); display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--rule); border-radius: 10px; box-shadow: var(--shadow);
  font-size: 12px; line-height: 1.3;
}
.zd-head { display: flex; align-items: center; gap: 8px; padding: 7px 8px 6px 10px; border-bottom: 1px solid var(--rule); }
.zd-zoom { flex: 1; font-weight: 600; white-space: nowrap; }
.zd-zoom b { font: 600 18px/1 var(--font-mono); font-variant-numeric: tabular-nums; margin-left: 4px; }
.zd-copy { border: 1px solid var(--rule); background: var(--paper); border-radius: 7px; padding: 4px 8px; white-space: nowrap; font-weight: 600; font-size: 12px; }
.zd-close { border: 0; background: none; font-size: 18px; line-height: 1; padding: 2px 6px; color: var(--muted); }
.zd-jumps { display: flex; flex-wrap: wrap; gap: 3px; padding: 6px 8px; border-bottom: 1px solid var(--rule); }
.zd-jumps button {
  min-width: 28px; height: 26px; padding: 0 4px; border: 1px solid var(--rule); border-radius: 6px;
  background: var(--paper); font: 500 12px/1 var(--font-mono); touch-action: manipulation;
}
.zd-jumps button:hover, .zd-copy:hover { border-color: var(--accent); }
.zd-copy[aria-expanded="true"] { background: var(--shape-on); color: var(--shape-on-ink); border-color: var(--shape-on); }
.zd-layers { list-style: none; margin: 0; padding: 4px 0; overflow-y: auto; min-height: 0; }
.zd-layers li { display: grid; grid-template-columns: 10px 1fr auto auto; align-items: center; gap: 6px; padding: 2px 10px; }
.zd-layers li.off { color: var(--muted); opacity: .55; }
.zd-layers li.lbl .zd-id { font-weight: 600; }
.zd-dot { width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid var(--muted); }
.zd-layers li.on .zd-dot { background: var(--accent); border-color: var(--accent); }
.zd-id, .zd-n, .zd-range { font-family: var(--font-mono); font-size: 11.5px; }
.zd-n { color: var(--hl-strong); }
.zd-range { color: var(--muted); }
.zd-foot { padding: 5px 10px 7px; border-top: 1px solid var(--rule); color: var(--muted); font-size: 11px; }
@media (hover: none) and (pointer: coarse) { .zd-foot { display: none; } }   /* no D key on touchscreens */

.coach {
  display: flex; align-items: center; gap: 10px; max-width: 330px;
  background: var(--ink); color: var(--paper); border-radius: 10px; padding: 8px 8px 8px 12px; box-shadow: var(--shadow);
  font-size: 13px; line-height: 1.35;
}
.coach button { flex: none; border: 0; border-radius: 7px; background: var(--hl); color: #1b2420; font-weight: 700; padding: 5px 10px; }

.readout {
  position: absolute; z-index: 6; pointer-events: none; transform: translate(14px, -50%);
  background: var(--ink); color: var(--paper); border-radius: 8px; padding: 5px 9px; font: 600 12.5px/1.3 var(--font-mono);
  white-space: nowrap; box-shadow: var(--shadow); font-variant-numeric: tabular-nums;
}
.readout .rm { color: var(--remove-soft); }
.tip {
  position: absolute; z-index: 6; pointer-events: none; transform: translate(14px, 14px);
  background: var(--panel); border: 1px solid var(--rule); border-radius: 8px; padding: 6px 9px; box-shadow: var(--shadow);
  font-size: 12.5px; white-space: nowrap;
}
.tip b { font-family: var(--font-mono); }
.tip .t-sub { color: var(--muted); }
.tip .t-sel { color: var(--hl-strong); font-weight: 700; }
/* Bottom center on computers (the tools are in the top corner); near the top on touchscreens. */
.toast {
  position: absolute; z-index: 7; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--sheet-offset, 0px) + var(--attrib-h, 34px) + 12px);
  display: flex; align-items: center; gap: 12px; background: var(--ink); color: var(--paper);
  border-radius: 999px; padding: 7px 8px 7px 16px; box-shadow: var(--shadow); font-weight: 600; max-width: calc(100% - 32px);
}
/* Shown while the map is zoomed out too far for ZIP outlines (usdata.js LOAD_ZOOM).
   Bottom center on computers, like the toast; near the top on touchscreens. */
.zoom-hint {
  position: absolute; z-index: 5; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--sheet-offset, 0px) + var(--attrib-h, 34px) + 12px);
  background: var(--panel); color: var(--muted); border: 1px solid var(--rule); border-radius: 999px;
  padding: 6px 14px; box-shadow: var(--shadow); font-size: 13px; font-weight: 600;
  max-width: calc(100% - 32px); text-align: center; pointer-events: none;
}
/* Radius around a ZIP (the drop-down's Radius button). Computers: directly under
   the map toolbar (its height is measured in app.js). Touchscreens: near the top,
   below undo / redo, since the toolbar sits at the bottom there. */
.radius-card {
  position: absolute; z-index: 6;
  top: calc(10px + var(--tools-h, 150px) + 8px); right: max(10px, env(safe-area-inset-right, 0px));
  width: max-content; max-width: calc(100% - 24px);
  background: var(--panel); border: 1px solid var(--rule); border-radius: 12px; box-shadow: var(--shadow);
  padding: 9px 10px 8px; display: flex; flex-direction: column; gap: 7px;
}
.rc-head { display: flex; align-items: center; gap: 7px; font-weight: 700; }
.rc-head svg { width: 18px; height: 18px; flex: none; }
.rc-head svg * { fill: none; stroke: currentColor; stroke-width: 1.9; }
.rc-head svg .dot { fill: currentColor; stroke: none; }
.rc-head b { font-family: var(--font-mono); }
.rc-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
#rcDist {
  width: 4.2em; height: 34px; padding: 0 8px; border: 1px solid var(--rule); border-radius: 8px;
  background: var(--paper); font: 600 15px var(--font-mono); text-align: right; font-variant-numeric: tabular-nums;
}
#rcDist::placeholder { color: var(--muted); }
.rc-units { margin: 0; padding: 2px; border: 1px solid var(--rule); border-radius: 8px; display: flex; gap: 2px; }
.rc-units label { position: relative; cursor: pointer; }
.rc-units input { position: absolute; opacity: 0; pointer-events: none; }
.rc-units span { display: grid; place-items: center; height: 28px; padding: 0 9px; border-radius: 6px; font-weight: 600; color: var(--muted); }
.rc-units label:has(input:checked) span { background: var(--shape-on); color: var(--shape-on-ink); }
.rc-units label:has(input:focus-visible) span { outline: 2px solid var(--accent); outline-offset: 1px; }
.rc-add, .rc-rem, .rc-cancel { height: 34px; border-radius: 8px; padding: 0 12px; font-weight: 700; white-space: nowrap; }
.rc-add { border: 1.5px solid var(--hl-strong); background: var(--hl); color: #1b2420; }
.rc-add:disabled { background: var(--panel); border-color: var(--rule); color: var(--muted); cursor: default; }
.rc-rem { border: 1.5px solid var(--remove); background: var(--panel); color: var(--remove); }
.rc-cancel { border: 1px solid var(--rule); background: var(--panel); color: var(--ink); }
.rc-sub { color: var(--muted); font-size: 12px; }
.toast span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.toast button { border: 0; background: var(--hl); color: #1b2420; border-radius: 999px; padding: 4px 12px; font-weight: 700; flex: none; }

/* ---------- panel ---------- */
.panel { grid-area: panel; background: var(--panel); border-left: 1px solid var(--rule); min-height: 0; display: flex; flex-direction: column; z-index: 5; }
.sheet-handle { display: none; }
.panel-body {
  overflow-y: auto; min-height: 0; flex: 1; display: flex; flex-direction: column; gap: 18px;
  padding-block: 18px 22px; padding-left: 18px; padding-right: max(18px, env(safe-area-inset-right, 0px));
  padding-bottom: max(22px, env(safe-area-inset-bottom, 0px));
}
.tally { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "num text"; column-gap: 14px; align-items: center; }
.tally-num {
  grid-area: num; font: 700 52px/1 var(--font-mono); letter-spacing: -.03em; font-variant-numeric: tabular-nums;
  background: linear-gradient(transparent 58%, var(--hl-soft) 58%, var(--hl-soft) 92%, transparent 92%); padding: 0 4px;
}
.tally-text { grid-area: text; min-width: 0; }
.tally-label { font-weight: 700; font-size: 15px; }
.tally-sub, .tally-pop { color: var(--muted); font-size: 12.5px; }
.tally-pop { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.icon-btn { border: 1px solid var(--rule); background: var(--panel); border-radius: 8px; padding: 5px 12px; font-weight: 600; font-size: 13px; }
.icon-btn:disabled { opacity: .45; cursor: default; }

.sec-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.sec-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); }
.export-sec, .types-sec { display: flex; flex-direction: column; gap: 10px; border-top: 1px solid var(--rule); padding-top: 16px; }
.type-n { color: var(--muted); font-size: 12px; }
.types-note { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.45; }
.inline-select { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.inline-select select { border: 1px solid var(--rule); background: var(--panel); border-radius: 6px; padding: 2px 4px; font-size: 12px; color: var(--ink); }
#zipList {
  width: 100%; min-height: 150px; height: 26vh; resize: vertical; border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper); padding: 10px 12px; font: 500 13px/1.6 var(--font-mono); font-variant-numeric: tabular-nums;
}
.issues { margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: var(--remove-soft); font-size: 12.5px; }
.issues b { font-family: var(--font-mono); }
.issues button { margin-left: 6px; border: 0; background: none; text-decoration: underline; padding: 0; font-weight: 600; color: var(--remove); }
.row-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin-top: 10px; }
.text-btn { border: 0; background: none; padding: 2px 0; font-weight: 600; color: var(--accent); text-decoration: underline; text-underline-offset: 3px; font-size: 13px; cursor: pointer; }
.file-btn input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.file-btn:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.check { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.check input { width: 16px; height: 16px; accent-color: var(--accent); margin: 0; }
.seg-wide { box-shadow: none; }
.seg-wide label { flex: 1; justify-content: center; }
.export-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.primary-btn, .secondary-btn { height: 42px; border-radius: 9px; font-weight: 700; }
.primary-btn { border: 0; background: var(--accent); color: var(--accent-ink); }
.secondary-btn { border: 1px solid var(--accent); background: transparent; color: var(--accent); }
.export-more { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.about { margin-top: auto; border-top: 1px solid var(--rule); padding-top: 14px; color: var(--muted); font-size: 12px; }
.about p { margin: 0 0 6px; max-width: 60ch; }
.about-small { font-size: 11px; }
.about a { color: var(--accent); font-weight: 600; }

/* ---------- help ---------- */
.help { position: fixed; inset: 0; z-index: 30; background: rgba(10, 16, 14, .45); display: grid; place-items: center; padding: 16px; }
.help-card { background: var(--panel); border-radius: 14px; box-shadow: var(--shadow); max-width: 760px; width: 100%; max-height: 90%; overflow-y: auto; padding: 20px 22px; }
.help-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.help-head h2 { margin: 0; font-size: 19px; text-wrap: balance; }
.help-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.help h3 { font-size: 12px; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin: 16px 0 6px; }
.help ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; }
.help-foot { color: var(--muted); font-size: 13px; margin: 16px 0 0; }

/* ---------- phones and narrow tablets ---------- */
@media (max-width: 760px) {
  .app { grid-template-columns: minmax(0, 1fr); grid-template-areas: "top" "stage"; }
  .topbar { flex-wrap: wrap; gap: 8px 10px; padding-block: 8px; padding-top: max(8px, env(safe-area-inset-top, 0px)); }
  /* Hidden from sight on phones but still read by screen readers and search engines (it is part of the H1). */
  .brand-sub { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .search { order: 3; flex-basis: 100%; max-width: none; }
  .ghost-btn { height: 32px; }
  .list-btn { display: block; margin-left: auto; }
  .list-btn + .ghost-btn { padding: 0 10px; }
  .brand { flex: 1 1 0; }   /* the site name shortens with "…" so the buttons stay on its line */
  .panel {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 8; border-left: 0; border-top: 1px solid var(--rule);
    border-radius: 16px 16px 0 0; box-shadow: 0 -6px 24px rgba(0, 0, 0, .16); max-height: 72%;
  }
  .sheet-handle {
    display: grid; grid-template-columns: 1fr auto; grid-template-areas: "grip grip" "sum tog"; align-items: center; gap: 4px 10px;
    width: 100%; border: 0; background: transparent; padding-block: 6px 10px;
    padding-left: max(16px, env(safe-area-inset-left, 0px)); padding-right: max(16px, env(safe-area-inset-right, 0px));
    padding-bottom: max(10px, env(safe-area-inset-bottom, 0px)); text-align: left;
  }
  .panel.open .sheet-handle { padding-bottom: 10px; }
  .sheet-grip { grid-area: grip; justify-self: center; width: 40px; height: 4px; border-radius: 2px; background: var(--rule); }
  .sheet-summary { grid-area: sum; font-size: 15px; }
  .sheet-summary b { font-family: var(--font-mono); background: var(--hl-soft); padding: 0 4px; border-radius: 3px; }
  .sheet-toggle { grid-area: tog; color: var(--accent); font-weight: 700; }
  .panel .panel-body { display: none; }
  /* Extra room at the end so the export buttons can scroll up past iOS Safari's floating bar. */
  .panel.open .panel-body { display: flex; padding-top: 4px; padding-bottom: calc(max(22px, env(safe-area-inset-bottom, 0px)) + 80px); }
  .stage { --sheet-offset: 64px; }
  .seg label { padding: 6px 9px 6px 7px; font-size: 13px; }
  .shape { min-height: 38px; padding: 0 10px 0 8px; }
  .coach { max-width: calc(100vw - 28px); }
  .help-cols { grid-template-columns: 1fr; gap: 0; }
  #zipList { height: 22vh; }
}

/* ---------- touchscreens: tools in the lower left, zoom buttons first ----------
   Very narrow computer windows use this too, since the tools would cover the
   undo / redo buttons in the top row. */
@media (hover: none) and (pointer: coarse), (max-width: 480px) {
  .tools {
    top: auto; right: auto; align-items: flex-start;
    /* Sits above the map credits line (its height is measured in app.js, since
       the credits grow when the "i" button opens them). */
    left: max(14px, env(safe-area-inset-left, 0px));
    bottom: calc(var(--sheet-offset, 0px) + var(--attrib-h, 34px) + 6px);
  }
  .tool-row { flex-direction: row; gap: 6px; }
  .coach { order: -1; }                 /* above the tools */
  .zoom-hint { top: 66px; bottom: auto; }   /* below the undo / redo buttons */
  .zoom-slot .maplibregl-ctrl-group button { width: 40px; }
  .toast { top: 66px; bottom: auto; }   /* below the undo / redo buttons */
  /* Full width between 12px margins, so it wraps instead of running off the screen. */
  .radius-card { top: 66px; left: max(12px, env(safe-area-inset-left, 0px)); right: max(12px, env(safe-area-inset-right, 0px)); width: auto; max-width: none; }
  .history { left: max(14px, env(safe-area-inset-left, 0px)); }
  .history button { width: 46px; height: 44px; }
  /* Wide enough for "hold to activate." on one line. */
  .act { width: 93px; padding-inline: 4px; }
  .act-hint { font-size: 10.5px; }
  .shape { gap: 6px; padding: 0 8px 0 7px; }
  .edge { min-height: 34px; }
}
/* iPhones zoom the whole page in when a text box under 16px is tapped, and stay zoomed. */
@media (hover: none) and (pointer: coarse) {
  .search input, #rcDist, #zipList, .inline-select select { font-size: 16px; }
}

/* ---------- movable, collapsible boxes (float.js) ----------
   Each floating box has a grip cell on its left, set off by a thin divider line (the cue that
   it's a handle): tap or click to collapse the box to a labelled pill, drag to move it. */
.grip, .history > .grip { display: none; }   /* .history > .grip outranks ".history button" */
.floating .grip {
  display: flex; align-items: center; justify-content: center; gap: 6px; flex: none; align-self: stretch;
  min-width: 34px; min-height: 26px; width: auto; height: auto; padding: 0 9px; border: 0; background: var(--grip);
  color: var(--muted); font-weight: 700; font-size: 13px; white-space: nowrap; cursor: grab;
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
.floating .grip:hover { color: var(--ink); background: var(--grip-hover); }
/* Clip the grey grip cell to each box's rounded corners. */
.tools.floating .toolbar, .radius-card.floating { overflow: hidden; }
.floating .grip svg { width: 16px; height: 16px; flex: none; fill: currentColor; stroke: none; }
.grip-label:empty { display: none; }
.floating.dragging { opacity: .85; }
.floating.dragging .grip { color: var(--ink); cursor: grabbing; }
.floating.collapsed .grip {
  /* Folded pill: only the dotted cell (34px, like an open grip) is grey, then the divider line;
     the label keeps the box's own color. */
  --cell: var(--grip);
  min-height: 38px; padding: 0 12px 0 9px; gap: 18px; color: var(--ink); border: 0 !important;
  background: linear-gradient(to right, var(--cell) 0 34px, var(--rule) 34px 35px, var(--panel) 35px);
}
.floating.collapsed .grip:hover { --cell: var(--grip-hover); }
/* Undo / redo: the grip is the first cell; the existing "button + button" line divides it from undo. */
.history.floating.collapsed > :not(.grip) { display: none !important; }
/* Tools: the grip is a column at the left of the toolbar, full height, moving the whole cluster. */
.tools.floating .toolbar { grid-template-columns: auto auto auto auto; }
.tools.floating .toolbar > .grip { grid-row: 1 / span 2; margin: -6px 0 -6px -6px; border-right: 1px solid var(--rule); }
.tools.floating .edges { grid-column: 2 / -1; }
.tools.moved { align-items: flex-start; }   /* a moved cluster stays where its grip was dropped */
.tools.floating.collapsed .zoom-slot, .tools.floating.collapsed .coach,
.tools.floating.collapsed .toolbar > :not(.grip) { display: none !important; }
.tools.floating.collapsed .toolbar { grid-template-columns: auto; padding: 0; }
.tools.floating.collapsed .toolbar > .grip { margin: 0; grid-row: auto; }
/* Radius card: the grip is a column at the left of the card, full height. */
.radius-card.floating { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 10px; padding-left: 0; }
.radius-card.floating > :not(.grip) { grid-column: 2; }
.radius-card.floating > .grip { grid-row: 1 / span 3; margin: -9px 0 -8px; border-right: 1px solid var(--rule); }
.radius-card.floating.collapsed { display: flex; padding: 0; right: auto; width: max-content; }
.radius-card.floating.collapsed > :not(.grip) { display: none !important; }
.radius-card.floating.collapsed > .grip { margin: 0; }
@media (hover: none) and (pointer: coarse) {
  .floating .grip { cursor: auto; }
  .floating.collapsed .grip { min-height: 44px; padding-right: 14px; }   /* finger-sized pill */
}
/* Small phones (360 wide): tighten a little more so everything fits in one row. */
@media (max-width: 370px) {
  .toolbar { gap: 4px; padding: 5px; }
  .act { width: 87px; }
  .act-hint { font-size: 10px; letter-spacing: 0; }
  .edge { font-size: 11.5px; gap: 3px; padding: 0 3px; }
  .zoom-slot .maplibregl-ctrl-group button { width: 36px; }
}
@media (prefers-reduced-motion: reduce) { .act { transition: none; } }

/* ---------- About section: plain page text below the app ----------
   The app fills the first screen (the .app box is as tall as the window); this section follows it as an
   ordinary scrolling section. Same type and color tokens as the privacy page. It sits above the phone
   bottom sheet (z-index 8, fixed to the screen), so the sheet slides away as the page scrolls down to it. */
.about-page {
  position: relative; z-index: 9; background: var(--paper); border-top: 1px solid var(--rule);
  padding: 40px max(16px, env(safe-area-inset-right, 0px)) 72px max(16px, env(safe-area-inset-left, 0px));
  font-size: 16px; line-height: 1.6;
}
.about-wrap { max-width: 720px; margin: 0 auto; }
.about-page h2 { font-size: 21px; line-height: 1.25; margin: 40px 0 10px; text-wrap: balance; }
.about-page .about-back + h2 { margin-top: 18px; }
.about-page p, .about-page li { margin: 0 0 10px; }
.about-page ul, .about-page ol { margin: 0 0 12px; padding-left: 22px; }
.about-page li { margin-bottom: 8px; }
.about-page a { color: var(--accent); font-weight: 600; text-underline-offset: 3px; }
.about-back { margin: 0 0 6px; font-size: 14px; }
.about-tagline { color: var(--muted); font-size: 17px; font-weight: 600; line-height: 1.4; margin: 0 0 14px; }
.about-updated { margin-top: 40px; padding-top: 14px; border-top: 1px solid var(--rule); color: var(--muted); font-size: 14px; }
/* Questions: each one opens in place; the answer text is in the page either way. */
.faq details { border: 1px solid var(--rule); border-radius: var(--radius); background: var(--panel); margin-bottom: 8px; }
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; padding: 10px 14px;
  font-weight: 700; cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; flex: none; font: 600 20px/1 var(--font-mono); color: var(--muted); }
.faq details[open] > summary::after { content: "\2212"; }
.faq details > p { margin: 0; padding: 0 14px 14px; }
@media (max-width: 760px) {
  .about-page { padding-top: 28px; padding-bottom: calc(max(24px, env(safe-area-inset-bottom, 0px)) + 80px); }
  .about-page h2 { font-size: 20px; margin-top: 32px; }
}

/* The page scrolls now (the About section is below the app). Its own scroll bar is hidden, so computers that always
   show scroll bars don't lose 15px of map width. Scrolling still works with the wheel over the top bar, the keyboard
   (Space, Page Down, End) and the About links. */
html { scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }
/* Scrolling to the end of a box that has its own scroll bar must not carry on and move the whole page. */
.panel-body, .results, .help, .help-card, .zd-layers { overscroll-behavior: contain; }
.help { overflow: auto; }   /* makes the dark backdrop a scroll box too, so the page behind the Help box stays put */
.help-foot a { color: var(--accent); font-weight: 600; }
