/* The map drawer and the map (WP A4). Loaded only on `/`, after site.css, whose tokens it uses.

   Copied from the approved prototype (design/high-fidelity/ACG_HIGH_FIDELITY.html, "Map drawer
   (phone) / map pane (desktop)", "markers", "price pills", "map controls", "recovery strip",
   "floating selected card"; ACG_VISUAL_SYSTEM.md §9-§11, §15), token for token. What differs,
   and why:
   * the page is the scroll container, so the drawer is fixed to the viewport and its heights
     use viewport units where the prototype's device frame used container units (plan §8.2 #4);
   * a marker button is the full 44 x 44 px target and draws its 16 px dot with ::before (the
     prototype drew the dot on the button and widened the hit area with ::before), so the
     button itself measures 44 px (plan §4.3, CR #5). Dot, ring, slash and selected state keep
     the prototype's values;
   * the chosen starting point (D12) was not in the design; its look is the Founder's choice of
     28 Sep 2026: a map pin in the marker ink, whose shape tells it apart from every shop.
   Drawer heights (visual system §15): results-focused 44 px + clamp(96, 22.5 % - 78, 140) px +
   safe area; balanced half; map-focused everything below the pinned search. */

.ic {
  width: 20px;
  height: 20px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ic--16 {
  width: 16px;
  height: 16px;
}

/* ---- the pinned search (F.7) ---- */

.search-page--map {
  padding-top: var(--s3);
}

.search-page--map .search-head {
  position: sticky;
  top: 0;
  z-index: 11;
  margin: 0 calc(-1 * var(--gutter-r)) 0 calc(-1 * var(--gutter-l));
  padding: var(--s3) var(--gutter-r) 0 var(--gutter-l);
  background: var(--c-canvas);
  border-bottom: 1px solid var(--c-divider);
}

/* While the search panel is open, on phones the drawer steps aside (UX §8); Cancel brings it
   back where it was. Hidden, not removed: the map keeps its size, so nothing is redrawn. On wide
   screens the map is its own pane and stays. */
@media (width < 1024px) {
  .is-searching .drawer {
    visibility: hidden;
  }

  /* Visual system §11: on phones the brand mark is the first thing in the search row, not a
     bar of its own above the field. The bar's 56 px (and, at 200% zoom, three lines of
     wordmark) are what the results need; the mark keeps its 44 px target and its link home.
     While the field is in use the row gives the mark's place to Cancel (§11, "Focused state
     replaces the brand mark and locate with a text Cancel button"). */
  .has-map .site-header {
    display: none;
  }

  .brand-row {
    display: grid;
    place-items: center;
    flex: none;
    width: var(--hit);
    height: var(--hit);
    /* The mark (32 px) lines up with the page's gutter; its target reaches 6 px past it. */
    margin-left: calc((32px - var(--hit)) / 2);
    border-radius: var(--r-md);
    color: var(--c-brand);
  }

  .is-searching .brand-row {
    display: none;
  }
}

/* The mark in the search row exists only for the phone layout; the wide layout has its own bar. */
@media (width >= 1024px) {
  .brand-row {
    display: none;
  }
}

/* The last card and the footer can always be scrolled clear of the drawer, whichever position it
   is in (drawer.js writes `--drawer-room`; the lowest position's room is the fallback). */
.has-drawer .has-map {
  padding-bottom: var(--drawer-room, var(--drawer-rf));
}

/* A focused item is scrolled clear of what covers the page (WCAG 2.4.11): the pinned search at
   the top, on phones the drawer at the bottom. drawer.js measures both (`--head-stuck`,
   `--drawer-h`). */
html.has-drawer {
  scroll-padding-top: calc(var(--head-stuck, 0px) + var(--s4));
}

@media (width < 1024px) {
  html.has-drawer {
    scroll-padding-bottom: calc(var(--drawer-h, 0px) + var(--s4));
  }
}

/* ---- the drawer ---- */

:root {
  /* The strip of map the results-focused drawer shows below its handle never gets less than this
     (JS reads it too, to size a drag). On a short screen, a landscape phone or a page at 200%
     zoom, it gives most of that height back to the results. */
  --drawer-rf-min: 96px;
  --drawer-rf: calc(44px + clamp(var(--drawer-rf-min), calc(22.5vh - 78px), 140px) + env(safe-area-inset-bottom));
  --drawer-rf: calc(44px + clamp(var(--drawer-rf-min), calc(22.5dvh - 78px), 140px) + env(safe-area-inset-bottom));
  --drawer-bal: 50vh;
  --drawer-bal: 50dvh;
  --drawer-mf: calc(100vh - var(--head-bottom, 160px));
  --drawer-mf: calc(100dvh - var(--head-bottom, 160px));
}

@media (height < 520px) {
  :root {
    --drawer-rf-min: 40px;
  }
}

.drawer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 12;
  height: var(--drawer-now, var(--drawer-rf));
  display: flex;
  flex-direction: column;
  background: var(--c-drawer);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: var(--e-drawer);
  overflow: hidden;
  /* It does not animate its height: drawer.js slides it with a transform (the map would resize
     on every frame). At rest this is the visible drawer. */
}

.drawer[data-snap="rf"] {
  --drawer-now: var(--drawer-rf);
}

.drawer[data-snap="bal"] {
  --drawer-now: var(--drawer-bal);
}

.drawer[data-snap="mf"] {
  --drawer-now: var(--drawer-mf);
  border-radius: 0;
}

.drawer__handle {
  position: relative;
  flex: none;
  height: 44px;
  width: 100%;
  border: 0;
  padding: 12px 0 0;
  background: var(--c-drawer);
  color: var(--c-text);
  cursor: grab;
  touch-action: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  font: var(--w-medium) var(--fs-row)/1 var(--font);
  border-bottom: 1px solid var(--c-divider);
}

.drawer__handle::before {
  content: "";
  position: absolute;
  top: 6px;
  left: 50%;
  width: 36px;
  height: 4px;
  margin-left: -18px;
  border-radius: 2px;
  background: var(--c-border-control);
}

.drawer__handle .ic {
  width: 16px;
  height: 16px;
  stroke-width: 2;
}

.drawer__handle b {
  font-weight: var(--w-strong);
  font-variant-numeric: tabular-nums;
}

.drawer__handle:active {
  cursor: grabbing;
}

/* The drawer clips its children and the map paints over the handle's lower edge, so a ring drawn
   outside the handle is never seen: it is drawn inside (WCAG 2.4.7). */
.drawer__handle {
  border-radius: inherit;
}

.drawer__handle:focus-visible {
  outline-offset: -4px;
  box-shadow: inset 0 0 0 2px var(--c-focus-gap);
}

.drawer__handle--off {
  cursor: default;
  color: var(--c-text-secondary);
}

.drawer__handle--off::before,
.drawer__handle--off .ic {
  display: none;
}

/* Reads the bottom safe area for the drag arithmetic (CSS knows it; script cannot ask). */
.drawer__probe {
  position: absolute;
  width: 0;
  height: env(safe-area-inset-bottom);
  visibility: hidden;
  pointer-events: none;
}

/* While the map is unavailable, a card's Map button would lead nowhere. */
.map-unavailable .mapbtn {
  display: none;
}

/* ---- the map ---- */

.map {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background: var(--c-map-land);
}

.map__gl {
  position: absolute;
  inset: 0;
}

/* MapLibre makes the canvas a tab stop and pans it with the arrow keys, so it shows when it has
   the focus (WCAG 2.4.7). The ring is drawn inside the map: `.map` clips whatever is outside, and
   the global ring's gap is a box-shadow a canvas paints under its own pixels, so the gap is the
   pseudo-element below. A click does not draw it (:focus-visible). */
.map__gl canvas {
  outline: none;
}

.map__gl canvas:focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: -4px;
  box-shadow: none;
}

.map__gl:has(canvas:focus-visible)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 6;
  box-shadow: inset 0 0 0 2px var(--c-focus-gap); /* the 2 px the ring (offset -4 px) leaves free */
  pointer-events: none;
}

.map__gl .maplibregl-ctrl-bottom-left,
.map__gl .maplibregl-ctrl-bottom-right,
.map__gl .maplibregl-ctrl-top-left,
.map__gl .maplibregl-ctrl-top-right {
  display: none !important;
}

/* A marker is a 0 x 0 wrapper handed to MapLibre, holding the 44 px button centred on the point
   (MAP §4). The wrapper carries the stacking order, since MapLibre moves it with a transform. */
.mkw {
  width: 0;
  height: 0;
}

.mkw.is-hover {
  z-index: 5;
}

.mkw.is-selected {
  z-index: 6;
}

.mk,
.cl {
  position: absolute;
  width: var(--hit);
  height: var(--hit);
  margin: -22px 0 0 -22px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  z-index: 2;
}

.mk::before {
  content: "";
  position: absolute;
  left: 14px;
  top: 14px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--c-marker-stroke);
  background: var(--c-marker-fill);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
  transition: transform var(--m-quick) var(--ease-out);
}

.mk--closed::before,
.mk--temp::before {
  background: var(--c-marker-hollow);
  border: 3px solid var(--c-marker-fill);
  box-shadow:
    0 0 0 1.5px var(--c-marker-stroke),
    0 1px 2px rgba(0, 0, 0, 0.3);
}

.mk--temp::after {
  content: "";
  position: absolute;
  left: 13px;
  top: 20.5px;
  width: 16px;
  height: 3px;
  background: var(--c-marker-fill);
  transform: rotate(-45deg);
  border-radius: 1px;
  box-shadow: 0 0 0 1px var(--c-marker-stroke);
}

.mk--unknown::before {
  background: var(--c-marker-unknown);
}

.mk.is-hover::before,
.mk:hover::before {
  box-shadow:
    0 0 0 3px var(--c-marker-stroke),
    0 0 0 5px var(--c-selected);
}

.mk.is-selected::before {
  left: 9px;
  top: 9px;
  width: 26px;
  height: 26px;
  background: var(--c-marker-selected);
  border: 3px solid var(--c-marker-stroke);
  box-shadow:
    0 0 0 6px color-mix(in srgb, var(--c-marker-selected) 24%, transparent),
    0 2px 6px rgba(0, 0, 0, 0.35);
}

.mk.is-selected.mk--closed::before,
.mk.is-selected.mk--temp::before {
  background: var(--c-marker-hollow);
  border-color: var(--c-marker-selected);
}

.mk__label {
  position: absolute;
  left: 44px;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  padding: 5px 8px;
  border-radius: var(--r-sm);
  background: var(--c-marker-label-bg);
  color: var(--c-marker-label-text);
  font: var(--w-strong) var(--fs-meta)/1 var(--font);
  font-stretch: var(--place-width);
  box-shadow: var(--e1);
  pointer-events: none;
}

/* Price pills (product intent): a label with a tail pointing at the shop. The pill is part of
   its marker's button, so one focus stop covers the shop and its price (plan §4.3). */
.pp {
  position: absolute;
  left: 22px;
  top: 22px;
  transform: translate(-50%, calc(-100% - 6px));
  height: 26px;
  /* As wide as its own text, whatever the engine's shrink-to-fit makes of a box inside a 44 px
     button: a price is never cut ("€20 per joi..."), and a long one is shortened in the data's
     words (the first clause: "€79.20·16 joints"), not clipped. */
  width: max-content;
  max-width: none;
  padding: 0 8px;
  border-radius: var(--r-sm);
  border: 1px solid var(--c-pill-border);
  background: var(--c-pill-bg);
  color: var(--c-pill-text);
  font: var(--w-strong) var(--fs-meta)/24px var(--font);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  box-shadow: var(--e1);
  z-index: 3;
}

.pp::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -5px;
  width: 8px;
  height: 8px;
  margin-left: -4px;
  background: inherit;
  border: inherit;
  border-width: 0 1px 1px 0;
  transform: rotate(45deg);
  border-radius: 0 0 2px 0;
}

.mk--closed .pp,
.mk--temp .pp {
  border-style: dashed;
  color: var(--c-pill-muted);
}

.mk.is-hover .pp,
.mk:hover .pp {
  box-shadow:
    0 0 0 2px var(--c-selected),
    var(--e1);
}

.mk.is-selected .pp {
  background: var(--c-pill-selected-bg);
  color: var(--c-pill-selected-text);
  border-color: var(--c-pill-selected-bg);
  border-style: solid;
  height: 30px;
  line-height: 28px;
  padding: 0 10px;
  font-size: var(--fs-row);
  z-index: 7;
  box-shadow: var(--e2);
}

.pp__n {
  font-stretch: var(--place-width);
  font-weight: var(--w-medium);
}

/* Collision (plan §4.5): the lower-priority pill yields; its shop keeps its dot and its name. */
.pp.is-collided {
  visibility: hidden;
}

.cl {
  z-index: 1;
  display: grid;
  place-items: center;
  color: var(--c-cluster-text);
  font: var(--w-strong) var(--fs-meta)/1 var(--font);
  font-variant-numeric: tabular-nums;
}

.cl::before {
  content: "";
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  background: var(--c-cluster-bg);
  border: 1.5px solid var(--c-cluster-border);
  box-shadow: var(--e1);
}

.cl__n {
  position: relative;
}

/* Desktop hover: the shop's name over its marker; nothing scrolls (UX §7). */
.tip {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, calc(-100% - 16px));
  padding: 5px 8px;
  border-radius: var(--r-sm);
  background: var(--c-text);
  color: var(--c-canvas);
  font: var(--w-strong) var(--fs-meta)/1 var(--font);
  font-stretch: var(--place-width);
  white-space: nowrap;
  z-index: 9;
  pointer-events: none;
  box-shadow: var(--e1);
}

/* The chosen starting point (D12): a map pin in marker ink with its tip on the point. */
.startpin {
  width: var(--hit);
  height: var(--hit);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  cursor: grab;
  touch-action: none;
}

.startpin svg {
  width: 34px;
  height: 32px;
  overflow: visible;
  filter: var(--pin-shadow);
}

.startpin path {
  fill: var(--c-marker-fill);
  stroke: var(--c-marker-stroke);
  stroke-width: 1.4;
}

.startpin circle {
  fill: var(--c-marker-stroke);
}

.map.is-placing .maplibregl-canvas {
  cursor: crosshair;
}

.map.is-placing .mkw,
.map.is-placing .startpin {
  pointer-events: none;
}

/* ---- map controls ---- */

.map-ctls {
  position: absolute;
  top: var(--s6);
  right: max(var(--s6), env(safe-area-inset-right));
  display: flex;
  gap: var(--s4);
  z-index: 8;
}

.map.has-strip .map-ctls {
  top: calc(var(--strip-h, 64px) + var(--s6) * 2);
}

.map-ctl {
  width: var(--hit);
  height: var(--hit);
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: var(--r-md);
  background: var(--c-surface-raised);
  border: 1px solid var(--c-border);
  color: var(--c-text);
  box-shadow: var(--e1);
  cursor: pointer;
  transition:
    background-color var(--m-press) linear,
    transform var(--m-press) linear;
}

.map-ctl:hover {
  background: var(--c-sunken);
}

.map-ctl:active,
.map-ctl[aria-pressed="true"] {
  background: var(--c-brand-tint);
}

.map-ctl:active {
  transform: scale(0.96);
}

.drawer[data-snap="mf"] .ctl-expand {
  display: none;
}

.map-recentre {
  position: absolute;
  right: var(--s6);
  bottom: calc(var(--s6) + env(safe-area-inset-bottom));
  z-index: 8;
  height: 40px;
  padding: 0 var(--s6);
  gap: var(--s3);
  display: inline-flex;
  align-items: center;
  border-radius: var(--r-md);
  background: var(--c-surface-raised);
  border: 1px solid var(--c-border);
  color: var(--c-text);
  box-shadow: var(--e1);
  font: var(--w-medium) var(--fs-row)/1 var(--font);
  cursor: pointer;
}

.map-recentre::after {
  content: "";
  position: absolute;
  inset: -2px;
}

.drawer[data-snap="rf"] .map-recentre {
  display: none;
}

/* ODbL: the attribution is on every map, at every drawer position. */
.map-attrib {
  position: absolute;
  left: max(var(--s4), env(safe-area-inset-left));
  /* Its words can run on, but never under a notch at the right. */
  max-width: calc(100% - max(var(--s4), env(safe-area-inset-left)) - env(safe-area-inset-right));
  bottom: calc(var(--s2) + env(safe-area-inset-bottom));
  z-index: 7;
  margin: 0;
  padding: 1px 4px;
  border-radius: var(--r-xs);
  background: color-mix(in srgb, var(--c-map-land) 88%, transparent);
  /* 12 px, the smallest text of the site (`--fs-small`). It was the 10 px `--fs-attr`, meant for
     a photo credit; the map's line is read against moving tiles, and the licence asks only that
     the credit be legible and shown (OSMF attribution guidelines set no size). */
  font: var(--w-regular) var(--fs-small)/1.25 var(--font);
  color: var(--c-map-label);
}

.map-attrib a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 1px;
}

/* A floating card would cover it: the attribution moves above the card, and so does Re-centre,
   which a Map button's jump to the shop brings up under the card (6 Oct 2026). */
.map.has-float .map-attrib {
  bottom: calc(var(--float-h, 150px) + var(--s6) + var(--s2) + env(safe-area-inset-bottom));
}

.map.has-float .map-recentre {
  bottom: calc(var(--float-h, 150px) + var(--s6) + var(--s2) + env(safe-area-inset-bottom));
}

/* ---- the strip under the handle ----
   Placing the starting point (D12) uses the recovery strip in its column form (visual system
   §11, "Notices and recovery"). */

.mstrip {
  position: absolute;
  top: var(--s6);
  left: max(var(--s6), env(safe-area-inset-left));
  right: max(var(--s6), env(safe-area-inset-right));
  z-index: 9;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s5);
  padding: var(--s4) var(--s4) var(--s4) var(--s6);
  min-height: 52px;
  background: var(--c-surface-raised);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  box-shadow: var(--e2);
  font: var(--w-regular) var(--fs-row)/1.35 var(--font);
  overflow: hidden;
}

.mstrip b {
  font-weight: var(--w-strong);
}

.mstrip--col {
  flex-direction: column;
  align-items: stretch;
  padding: var(--s5) var(--s6) var(--s6);
}

.mstrip p {
  margin: 0;
}

.mstrip__acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  margin-top: var(--s4);
}

/* D20: why "Near me" sent the visitor here, above the picker's own line. */
.start-strip__reason {
  margin-bottom: var(--s3);
  font-weight: var(--w-strong);
}

.start-strip__places {
  display: flex;
  align-items: center;
  gap: var(--s4);
  margin-top: var(--s5);
}

.start-strip__label {
  flex: none;
  color: var(--c-text-secondary);
}

.start-strip__select {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0 var(--s4);
  border: 1px solid var(--c-border-control);
  border-radius: var(--r-md);
  background: var(--c-surface);
  color: var(--c-text);
  font: var(--w-medium) var(--fs-body)/1 var(--font);
}

/* Buttons inside the map: the prototype's small secondary button (36 px, 44 px hit). */
.map .btn {
  position: relative;
  min-height: 0;
  height: 36px;
  padding: 0 var(--s6);
  gap: var(--s3);
  border: 1px solid var(--c-border-control);
  background: var(--c-surface);
  color: var(--c-text);
  font: var(--w-strong) var(--fs-row)/1 var(--font);
  white-space: nowrap;
  transition:
    background-color var(--m-press) linear,
    transform var(--m-press) linear;
}

.map .btn::after {
  content: "";
  position: absolute;
  inset: -4px;
}

.map .btn:hover {
  background: var(--c-sunken);
}

.map .btn:active {
  background: var(--c-brand-tint);
  transform: scale(0.98);
}

.map .btn--primary {
  background: var(--c-brand);
  border-color: var(--c-brand);
  color: var(--c-on-brand);
}

.map .btn--primary:hover {
  background: var(--c-brand-hover);
}

.map .btn--primary:active {
  background: var(--c-brand-pressed);
}

/* ---- the map could not be drawn ----
   It yields its space to one quiet line and a retry, no error colour: the list is the product
   and the map a convenience (MAP §7). */

.map-off {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s5);
  padding: 0 var(--s7) env(safe-area-inset-bottom);
  background: var(--c-sunken);
  font: var(--w-regular) var(--fs-row)/1.35 var(--font);
  color: var(--c-text-secondary);
}

.map-off p {
  margin: 0;
}

.map-off a {
  position: relative;
  color: var(--c-brand-text);
}

.map-off a::after {
  content: "";
  position: absolute;
  inset: -14px -8px;
}

.map-off b {
  display: block;
  color: var(--c-text);
  font-weight: var(--w-strong);
}

.map-off--gl {
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--s3);
}

/* ---- cards and the map ---- */

/* The Map button is shown by script, after the page has painted (the list comes first, the map
   later): until then its row keeps the button's height, so no card jumps when it appears
   (layout shift). Without script it is never shown and takes no room. */
@media (scripting: enabled) {
  .card__r3:has(> .mapbtn[hidden]) {
    min-height: 28px;
  }
}

/* The card's Map affordance (visual system §11, row 3). */
.mapbtn {
  position: relative;
  z-index: 4;
  flex: none;
  height: 28px;
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  margin-left: auto;
  padding: 0 var(--s5) 0 var(--s4);
  border-radius: var(--r-md);
  border: 1px solid var(--c-border-strong);
  background: var(--c-card);
  color: var(--c-text);
  font: var(--w-medium) var(--fs-count)/1 var(--font);
  cursor: pointer;
  transition:
    background-color var(--m-press) linear,
    transform var(--m-press) linear;
}

.mapbtn::after {
  content: "";
  position: absolute;
  inset: -8px -6px;
}

.mapbtn .ic {
  width: 16px;
  height: 16px;
}

.mapbtn:hover {
  background: var(--c-sunken);
}

.mapbtn:active {
  background: var(--c-brand-tint);
  transform: scale(0.96);
}

/* Directions on the card of a selected shop: the Map button's own look, as a link. */
.mapbtn--dir {
  text-decoration: none;
}

.mapbtn--dir:hover {
  color: var(--c-text);
}

/* A shop selected on the map that is not on this page: its card, pinned above the list. */
.pinned {
  margin: var(--s4) 0 var(--s5);
  border-radius: 14px;
  box-shadow: 0 0 0 2px var(--c-selected);
  background: var(--c-selected-bg);
  overflow: hidden;
}

.pinned__tag {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s4);
  padding: 0 0 0 var(--s6);
  min-height: 40px;
  font: var(--w-medium) var(--fs-count)/1.3 var(--font);
  color: var(--c-brand-text);
}

.pinned__close {
  width: var(--hit);
  height: var(--hit);
  flex: none;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-text);
  cursor: pointer;
}

/* `.pinned` clips its children (the rounded corners), so the ring is drawn inside the button. */
.pinned__close:focus-visible {
  outline-offset: -4px;
  box-shadow: inset 0 0 0 2px var(--c-focus-gap);
}

.pinned .card {
  margin: 0;
  border-radius: 0;
  border-width: 1px 0 0;
}

/* The selected shop while the map shows (visual system §11; D26, the Founder, 7 Oct 2026: balanced
   too, not only map-focused): the list's own card floats over the map, under a bar with the
   previous and the next shop, where the shop stands in the result, and the close. The bar is the
   pinned card's tag row (`selected-bg`, brand ring), so the two read as one selected thing. */
.float {
  position: absolute;
  left: max(var(--s6), env(safe-area-inset-left));
  right: max(var(--s6), env(safe-area-inset-right));
  bottom: calc(var(--s6) + env(safe-area-inset-bottom));
  z-index: 10;
  /* A sideways swipe steps, a vertical drag is the drawer's (discovery.js): the browser takes
     neither for a scroll of the page behind. */
  touch-action: none;
}

.drawer[data-snap="rf"] .float {
  display: none;
}

.float__in {
  border-radius: 14px;
  box-shadow:
    0 0 0 2px var(--c-selected),
    var(--e2);
  background: var(--c-selected-bg);
  overflow: hidden;
}

.float.is-swiping .float__in {
  cursor: grabbing;
}

.float__bar {
  display: flex;
  align-items: center;
  min-height: var(--hit);
  color: var(--c-brand-text);
}

.float__step,
.float__close {
  width: var(--hit);
  height: var(--hit);
  flex: none;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-text);
  cursor: pointer;
  transition: background-color var(--m-press) linear;
}

.float__step:hover,
.float__close:hover {
  background: color-mix(in srgb, var(--c-selected) 12%, transparent);
}

.float__step:active,
.float__close:active {
  background: color-mix(in srgb, var(--c-selected) 20%, transparent);
}

/* At either end the button stays where it is, so focus is never dropped, and says so. */
.float__step[aria-disabled="true"] {
  color: var(--c-text-secondary);
  opacity: 0.4;
  cursor: default;
}

.float__step[aria-disabled="true"]:hover,
.float__step[aria-disabled="true"]:active {
  background: transparent;
}

/* `.float__in` clips its children (the rounded corners), so the ring is drawn inside the button. */
.float__step:focus-visible,
.float__close:focus-visible {
  outline-offset: -4px;
  box-shadow: inset 0 0 0 2px var(--c-focus-gap);
}

.float__pos {
  margin: 0;
  min-width: 0;
  display: flex;
  gap: var(--s3);
  font: var(--w-medium) var(--fs-count)/1.3 var(--font);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The card shows the name on a phone; the bar names the shop only where it stands alone. */
.float__name {
  display: none;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: var(--w-strong);
  color: var(--c-text);
}

.float__close {
  margin-left: auto;
}

.float .card {
  margin: 0;
  border-radius: 0;
  border-width: 1px 0 0;
}

.float .card__media {
  height: 78px;
}

.float .card--nophoto .card__media {
  height: 60px;
}

.float .card__scrim {
  height: 70px;
}

/* In balanced the map is half the screen: the band gives way so that the map above the card is
   still a map (D26). The rows are the list card's own, laid out by its own rules. */
.drawer[data-snap="bal"] .float .card__media {
  height: 56px;
}

.drawer[data-snap="bal"] .float .card__scrim {
  height: 56px;
}

.float .card__r3 {
  margin-top: var(--s4);
  flex-wrap: wrap;
}

.float__acts {
  display: flex;
  align-items: center;
  gap: var(--s4);
  margin-left: auto;
}

/* "View shop" is the card's one named way to the shop's page, above the card's own link. */
.map .float__view {
  position: relative;
  z-index: 4;
  height: var(--hit);
}

.float .mapbtn--dir {
  height: var(--hit);
  margin-left: 0;
}

/* ---- desktop (visual system §11): the results panel beside a full-height map ---- */

@media (width >= 1024px) {
  .has-map {
    --panel-w: 460px;
  }

  .has-map .site-header {
    position: sticky;
    top: 0;
    z-index: 14;
  }

  .has-map .brand {
    max-width: none;
    margin: 0;
  }

  .has-map .search-page,
  .has-map .site-footer {
    max-width: none;
    width: var(--panel-w);
    margin-left: 0;
    margin-right: 0;
  }

  .search-page--map .search-head {
    top: var(--site-header-h);
  }

  .has-drawer .has-map {
    padding-bottom: 0;
  }

  .has-map .drawer {
    top: var(--site-header-h);
    left: var(--panel-w);
    height: auto;
    border-radius: 0;
    border-left: 1px solid var(--c-border);
    box-shadow: none;
  }

  .has-map .drawer__handle,
  .has-map .ctl-expand,
  .has-map .float .card {
    display: none;
  }

  /* Wide screens: the selected card is the list's, beside the map, so the bar stands alone at
     the bottom of the map with the shop's name (D26). */
  .has-map .drawer[data-snap] .float {
    display: block;
  }

  .has-map .float {
    left: 0;
    right: 0;
    width: max-content;
    max-width: calc(100% - 2 * var(--s7));
    margin: 0 auto;
    bottom: var(--s7);
  }

  .has-map .float__name {
    display: block;
  }

  .has-map .float__pos {
    padding: 0 var(--s3);
  }

  .has-map .float__n::before {
    content: "· ";
  }

  .has-map .map-ctls {
    flex-direction: column;
    top: var(--s7);
    right: max(var(--s7), env(safe-area-inset-right));
  }

  .has-map .drawer[data-snap] .map-recentre {
    display: inline-flex;
  }

  .has-map .drawer[data-snap] .map-recentre[hidden] {
    display: none !important;
  }
}

@media (width >= 1440px) {
  .has-map {
    --panel-w: 520px;
  }
}
