#mapPane { position: absolute; inset: 0; overflow: hidden; background: var(--map-land); touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none; outline-offset: -3px; }
#mapPane.is-drag { cursor: grabbing; }
#mapPane canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
#pinLayer { position: absolute; inset: 0; pointer-events: none; }
/* At full-map zoom a vertical swipe scrolls the page. Zoomed in, one finger pans the map. */
#mapPane.is-zoomed { touch-action: none; }

/* dots are the exact data position */
.dot { position: absolute; left: 0; top: 0; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%; background: var(--ink); border: 2px solid var(--bg); box-shadow: 0 0 0 1px rgba(0,0,0,.25); pointer-events: none; will-change: transform; }
.dot.is-muted { background: var(--dot-mute); }
.dot.is-sel { width: 13px; height: 13px; margin: -6.5px 0 0 -6.5px; }
.dot.no-dot { display: none; }

/* pills speak the price-pill language */
.pin { position: absolute; left: 0; top: 0; width: 0; height: 0; padding: 0; margin: 0; pointer-events: auto; will-change: transform; transform-origin: center; }
.pill { position: absolute; left: 0; top: 0; display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; transform: translate(-50%, -50%); background: var(--card); color: var(--ink); border-radius: 999px; box-shadow: var(--pill-shadow); font-size: 13px; font-weight: 700; line-height: 1; white-space: nowrap; transition: transform .16s cubic-bezier(.2,.9,.3,1.3), background .12s, color .12s, opacity .22s; }
.pill .pn { font-weight: 600; color: inherit; }
.pill .ps { font-weight: 600; } .pill .ps i { font-style: normal; font-size: .92em; }
.pin.is-hover .pill, .pin:hover .pill { transform: translate(-50%, -50%) scale(1.05); z-index: 3; }
.pin:focus-visible { outline: none; } .pin:focus-visible .pill { outline: 2px solid var(--ink); outline-offset: 2px; }
.pin.is-hover, .pin:hover, .pin.is-sel { z-index: 5; }
.pin.is-sel .pill { background: var(--ink); color: var(--on-ink); box-shadow: 0 2px 10px rgba(0,0,0,.32); }
.pin.is-sel .belo-i path { fill: var(--ink); }
.pin.is-muted:not(.is-sel) .pill { background: var(--card-quiet); color: var(--mute); box-shadow: 0 1px 3px rgba(0,0,0,.14); height: 24px; font-size: 11.5px; padding: 0 8px; font-weight: 600; }
.pin.no-pill .pill { display: none; }
/* A dot-only pin keeps an invisible target on its dot, so it still opens on a tap. */
.pin.dot-only:not(.is-sel) .pill { width: 30px; height: 30px; padding: 0; opacity: 0; overflow: hidden; box-shadow: none; }
@media (hover: hover) { .pin.dot-only:not(.is-sel):hover .pill { width: auto; height: 28px; padding: 0 10px; opacity: 1; overflow: visible; box-shadow: var(--pill-shadow); } }


/* floating controls */
.mctl { position: absolute; z-index: 8; right: 14px; top: 14px; background: var(--card); border-radius: var(--r); box-shadow: var(--shadow2); display: flex; flex-direction: column; overflow: hidden; }
.mctl button { width: 40px; height: 40px; display: grid; place-items: center; font-size: 20px; font-weight: 500; }
.mctl button + button { border-top: 1px solid var(--line2); }
.mctl button:hover { background: var(--bg2); }
#zoomReset { display: none; }
#mapPane.is-zoomed #zoomReset { display: grid; }
/* The phone's bigger-map button sits with the zoom controls. */
#mapGrow { display: none; }
#mapGrow[aria-pressed="true"] { background: var(--ink); color: var(--on-ink); }


/* The axis words are a compass painted on the map once the streets run straight. */
.axisword { position: absolute; z-index: 6; font-size: 12.5px; font-weight: 800; color: var(--ink); background: var(--map-chip); padding: 4px 11px; border-radius: 999px; pointer-events: none; opacity: 0; transition: opacity .35s; white-space: nowrap; box-shadow: 0 1px 3px rgba(0,0,0,.12); }
html.map-straight .axisword.on { opacity: 1; }
.aw-n { top: 14px; left: 50%; transform: translateX(-50%); }
.aw-w { left: 66px; top: 14px; }


@media (max-width: 979px) {
  .mctl { right: 8px; top: auto; bottom: 24px; display: grid; grid-template-columns: 40px; }
  .mctl button + button { border-top: 0; }
  #mapGrow { display: grid; }
  #zoomIn, #zoomOut { display: none; }
  #mapPane.is-zoomed #zoomIn, #mapPane.is-zoomed #zoomOut, .map-big #zoomIn, .map-big #zoomOut { display: grid; }
  #mapPane.is-zoomed .mctl, .map-big .mctl { grid-template-columns: repeat(4, 40px); }
  .pill { height: 26px; font-size: 12px; padding: 0 9px; gap: 4px; }
  /* Every pill is at least a 40 px target. */
  .pill::after { content: ''; position: absolute; inset: -7px -2px; }
  .pin.dot-only:not(.is-sel) .pill { width: 40px; height: 40px; }
  .pin.is-sel .pill { height: 30px; font-size: 12.5px; padding: 0 11px; gap: 6px; }
  .aw-n { top: 80px; left: 8px; transform: none; } .aw-w { left: auto; right: 8px; top: 80px; }
  .axisword { font-size: 11px; padding: 3px 8px; }
  /* A short pane gets small axis words. */
  #mapPane.is-short .aw-n, #mapPane.is-short .aw-w { top: 78px; font-size: 10.5px; padding: 2px 7px; }
  /* A very short, crowded pane shows dots only. */
  #mapPane.is-quiet .pin:not(.is-sel):not(.is-hi) .pill { width: 40px; height: 40px; padding: 0; opacity: 0; overflow: hidden; box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) { .axisword { transition: none; } }

/* A listed pin shows its name, rating and price together. */
.pill .pnum { display: inline-flex; align-items: center; gap: 6px; }
@media (max-width: 979px) {
  .pill:has(.pn + .pnum) { flex-direction: column; align-items: flex-start; gap: 0; height: auto; padding: 3px 8px 4px; line-height: 1.18; border-radius: 10px; font-size: 10.5px; }
  .pill:has(.pn + .pnum) .pn { font-weight: 600; }
  .pill .pnum { gap: 5px; }
  /* A muted pill holds both of its rows, and a dot-only pin keeps its invisible target. */
  .pin.is-muted:not(.is-sel):not(.dot-only) .pill { height: auto; padding: 3px 8px; font-size: 10.5px; }
}
@media (max-width: 979px) { #mapPane.is-zoomed .mctl, .map-big .mctl { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 40px; } }

/* Dots take clicks too, with a target larger than the mark. Pills stay on top. */
.dot { pointer-events: auto; cursor: pointer; z-index: 1; }
.dot::after { content: ''; position: absolute; inset: -9px; border-radius: 50%; }
.pin { z-index: 2; }
@media (max-width: 979px) { .dot::after { inset: -13px; } }
.pill .ps { font-weight: 700; } .pill .ps i { font-style: normal; font-size: 1.08em; }
/* Max is blocked, so its pin is hatched like a blocked date. */
.pin.is-hatched .pill { background: repeating-linear-gradient(135deg, var(--hatch-a) 0 5px, var(--hatch-b) 5px 10px); color: var(--hatch-ink); }
.dot.is-hatched { background: var(--bg); box-shadow: 0 0 0 1.5px var(--ink); }

/* The walk. A listing waits under the others, walks as a small dark chip you can follow, and opens at its measured place. */
.pin.is-waiting { z-index: 0; }
.pin.is-waiting:not(.is-sel) .pill { color: var(--mute); box-shadow: 0 1px 3px rgba(0,0,0,.14); }
.pin .pill { transition: color .3s ease; }
.pin.is-walking { z-index: 4; }
.pin.is-walking .pill { height: 22px; padding: 0 8px; font-size: 11px; background: var(--ink); color: var(--on-ink); box-shadow: 0 2px 8px rgba(0,0,0,.3); }
.pin.just-landed { z-index: 4; }
.pin.just-landed .pill { animation: landpill .9s cubic-bezier(.2,.8,.3,1) both; }
.pin.just-landed .pnum { position: relative; }
.pin.just-landed .pnum > .ps, .pin.just-landed .pnum > .belo { animation: landnums .36s .1s cubic-bezier(.2,.8,.3,1) both; }
.pin.just-landed .belo-i path { animation: landbelo .9s ease both; }
.pill .was { position: absolute; left: 0; top: 50%; font-weight: 700; white-space: nowrap; transform: translateY(-50%); animation: landwas .3s ease both; }
.pill .was i { font-style: normal; font-size: 1.08em; }
.dot.just-landed { animation: landdot .8s ease-out both; }
@keyframes landpill { 0% { transform: translate(-50%, -50%) scale(1.18); background: var(--ink); color: var(--on-ink); box-shadow: 0 6px 22px rgba(0,0,0,.34); } 38% { transform: translate(-50%, -50%) scale(1); background: var(--ink); color: var(--on-ink); box-shadow: 0 4px 14px rgba(0,0,0,.3); } 100% { transform: translate(-50%, -50%) scale(1); background: var(--card); color: var(--ink); } }
@keyframes landnums { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
@keyframes landwas { from { opacity: 1; transform: translateY(-50%); } to { opacity: 0; transform: translateY(-130%); } }
@keyframes landbelo { 0%, 38% { fill: var(--ink); } 100% { fill: var(--on-ink); } }
@keyframes landdot { 0% { box-shadow: 0 0 0 0 rgba(var(--ink-rgb),.5); } 100% { box-shadow: 0 0 0 20px rgba(var(--ink-rgb),0); } }
@media (prefers-reduced-motion: reduce) { .pin.just-landed .pill, .pin.just-landed .pnum > *, .pin.just-landed .belo-i path, .dot.just-landed { animation: none; } }

.axisword { display: inline-flex; align-items: center; gap: 5px; }
.axisword .aw-g { font-style: normal; font-size: .9em; }
.axisword .belo-i { flex: none; }
