/* Discovery v3 -- the redesigned discovery screen.
 *
 * Lifted from design/discovery-search.html, which was reviewed screen by
 * screen, so the tokens and components here are the ones that were signed off
 * rather than a retyped approximation.
 *
 * Deliberately NOT a fourth entry in the mm_theme cookie: v3 has its own shell
 * (places/v3/base.html) and does not load magazine/otter/pebble at all, so it
 * cannot regress the pages that share those.
 *
 * Changes from the design file, all noted inline below:
 *   - .map is a live Leaflet container, not a background image
 *   - card/pin classes align with what the Django templates emit
 */


/* ---------------------------------------------------------------- tokens */
:root {
  /* surfaces */
  --surface: #faf8ff;
  --surface-container-lowest: #ffffff;
  --surface-container-low: #f2f3ff;
  --surface-container: #ecedf9;
  --surface-variant: #e1e2ee;

  /* content */
  --on-surface: #191b24;
  --on-surface-variant: #424655;
  --outline: #727787;
  --outline-variant: #c2c6d8;

  /* brand */
  --primary: #0057cd;
  --primary-container: #0d6efd;
  --on-primary: #ffffff;
  --on-primary-container: #ffffff;

  /* accents */
  --action-orange: #ff7a59;
  --soft-teal: #2ec4b6;
  --sun-yellow: #ffbf00;
  --deep-onyx: #212529;
  --cloud-white: #f8f9fa;

  /* type */
  --font-display: "Plus Jakarta Sans", system-ui, -apple-system, sans-serif;
  --font-body: "Plus Jakarta Sans", system-ui, -apple-system, sans-serif;
  --font-label: "Quicksand", system-ui, -apple-system, sans-serif;

  /* shape + rhythm (8px base) */
  --radius-sm: 0.25rem;
  --radius: 0.5rem;
  --radius-md: 0.75rem;
  --radius-lg: 1rem;
  --radius-full: 9999px;
  --gutter: 24px;
  --margin-desktop: 40px;
  --margin-mobile: 16px;
  --container-max: 1200px;
  /* Gap above the first card in the list, and above a card revealed by
     tapping a map pin. ONE value: .rail__scroll pads by it, and
     discovery-v3.js reads it back with getComputedStyle so the resting
     position and the reveal position cannot drift apart. Without the padding
     the first card sat flush against the scroller's top edge and overflow
     clipped its border -- it looked cropped before anything had scrolled. */
  --card-top-gap: 12px;

  /* the blue-tinted ambient shadows the design system calls for */
  --shadow-sm: 0 1px 2px rgba(13, 110, 253, 0.06), 0 1px 3px rgba(13, 110, 253, 0.05);
  --shadow-md: 0 4px 12px rgba(13, 110, 253, 0.10), 0 2px 4px rgba(13, 110, 253, 0.06);
  --shadow-rail: 4px 0 24px rgba(13, 110, 253, 0.05);
}

*, *::before, *::after { box-sizing: border-box; }

/* Desktop lets the page grow so the footer can live below the fold; the
   mobile block re-pins this to the viewport for the app shell. */
html, body { min-height: 100%; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  color: var(--on-surface);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
}


.material-symbols-outlined {
  font-family: "Material Symbols Outlined";
  font-weight: normal;
  font-style: normal;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  font-variation-settings: "FILL" 0, "wght" 400, "GRAD" 0, "opsz" 24;
}
.material-symbols-outlined.filled { font-variation-settings: "FILL" 1; }

/* ------------------------------------------------------------------- nav */
.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(250, 248, 255, 0.8);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(194, 198, 216, 0.3);
  box-shadow: var(--shadow-sm);
  flex: none;
}
.topbar__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 16px var(--margin-desktop);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.topbar__left { display: flex; align-items: center; gap: 32px; min-width: 0; flex: 0 1 auto; }

.brand { display: inline-flex; align-items: center; gap: 8px; flex: none; }
.brand img { height: 32px; width: auto; object-fit: contain; display: block; }

.mainnav { display: flex; align-items: center; gap: 24px; min-width: 0; }
.mainnav a {
  font-family: var(--font-body);
  color: var(--on-surface-variant);
  text-decoration: none;
  padding-bottom: 4px;
  border-bottom: 2px solid transparent;
  transition: color .3s, border-color .3s;
  white-space: nowrap;
}
.mainnav a:hover { color: var(--primary); }
.mainnav a[aria-current="page"] {
  color: var(--primary);
  font-weight: 700;
  border-bottom-color: var(--primary);
}

.topbar__right { display: flex; align-items: center; gap: 16px; flex: 0 1 auto; min-width: 0; }
.topbar__account { display: none; }

/* location picker — a value + chevron, so it reads as "change this", not
   "type a query here". Shrinks before the nav does. */
.locpicker { position: relative; flex: 0 1 auto; min-width: 0; }
.locpicker__trigger {
  display: flex; align-items: center; gap: 8px;
  max-width: 260px;
  padding: 8px 12px 8px 14px;
  border-radius: var(--radius-full);
  border: 1px solid var(--outline-variant);
  background: var(--surface-container);
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--on-surface);
  cursor: pointer;
  transition: background .2s, border-color .2s;
}
.locpicker__trigger:hover { background: var(--surface-variant); }
.locpicker__trigger[aria-expanded="true"] {
  background: var(--surface);
  border-color: var(--primary);
}
.locpicker__pin { color: var(--primary); font-size: 20px; flex: none; }
.locpicker__value {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 600;
}
.locpicker__caret { color: var(--outline); font-size: 20px; flex: none; }

.locpicker__menu {
  position: absolute; top: calc(100% + 8px); left: 0;
  min-width: 280px;
  background: var(--surface);
  border: 1px solid rgba(194, 198, 216, 0.5);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 8px;
  z-index: 60;
}
.locpicker__menu[hidden] { display: none; }
.locpicker__current {
  width: 100%; display: flex; align-items: center; gap: 12px;
  padding: 12px; background: none; border: 0; cursor: pointer;
  text-align: left; border-radius: var(--radius);
  transition: background .2s;
}
.locpicker__current:hover { background: var(--surface-variant); }
.locpicker__current-icon {
  width: 32px; height: 32px; flex: none;
  border-radius: var(--radius-full);
  background: rgba(13, 110, 253, 0.12);
  color: var(--primary);
  display: flex; align-items: center; justify-content: center;
}
.locpicker__current-icon .material-symbols-outlined { font-size: 18px; }
.locpicker__current-title {
  display: block; font-family: var(--font-label);
  font-size: 14px; line-height: 20px; font-weight: 700; color: var(--on-surface);
}
.locpicker__current-sub { display: block; font-size: 12px; color: var(--on-surface-variant); }
.locpicker__label {
  margin: 8px 0 4px; padding: 0 12px;
  font-family: var(--font-label);
  font-size: 12px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--outline);
}
/* These rows are <a> now (real links, so they work without JS). Without the
   resets they inherit the browser's link styling -- blue and underlined --
   which is why the popular areas looked like a list of hyperlinks rather than
   menu rows. */
.locpicker__opt {
  width: 100%; text-align: left;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  border: 0; background: none; cursor: pointer;
  border-radius: var(--radius);
  font-family: var(--font-body); font-size: 15px;
  font-weight: 500;
  color: var(--on-surface);
  text-decoration: none;
  box-sizing: border-box;
  transition: background .2s, color .2s;
}
.locpicker__opt:visited { color: var(--on-surface); }
.locpicker__opt:hover { background: var(--surface-variant); color: var(--primary); }
.locpicker__opt .material-symbols-outlined {
  font-size: 20px; color: var(--outline-variant); flex: none;
  transition: color .2s;
}
.locpicker__opt:hover .material-symbols-outlined { color: var(--primary); }

/* text search over locations, inside the picker */
.locpicker__search {
  position: relative;
  margin-bottom: 4px;
}
.locpicker__search .material-symbols-outlined {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--outline); font-size: 20px; pointer-events: none;
}
.locpicker__search input {
  width: 100%;
  padding: 10px 12px 10px 40px;
  border: 2px solid var(--outline-variant);
  border-radius: var(--radius);
  background: var(--surface-container-lowest);
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--on-surface);
  outline: none;
  transition: border-color .2s;
}
.locpicker__search input::placeholder { color: var(--outline); }
.locpicker__search input:focus { border-color: var(--primary); }

.locpicker__empty {
  margin: 0; padding: 16px 12px;
  font-size: 14px; color: var(--on-surface-variant);
}
.locpicker__empty[hidden] { display: none; }

/* buttons — 500ms hover transition, "squishy" active state */
.btn {
  font-family: var(--font-label);
  font-size: 14px; line-height: 20px; font-weight: 700;
  border-radius: var(--radius-full);
  cursor: pointer;
  white-space: nowrap;
  /* Most .btn are <a>, which the browser underlines by default -- visible on
     "Konto" and "Tickets buchen" in the topbar. Set here rather than on each
     variant so a new one cannot reintroduce it; .btn--ondark already carried
     its own copy for the same reason. */
  text-decoration: none;
  transform: scale(.95);
  transition: background .5s, color .5s, box-shadow .5s, border-color .5s, transform .15s;
}
.btn:active { transform: scale(.90); }
.btn--ghost {
  padding: 8px 16px;
  background: transparent;
  color: var(--on-surface);
  border: 1px solid var(--outline-variant);
}
.btn--ghost:hover { background: var(--surface-variant); }
/* Action Orange is reserved for ticketing — the one CTA exception */
.btn--ticket {
  padding: 8px 20px;
  background: var(--action-orange);
  color: var(--cloud-white);
  border: 0;
  box-shadow: var(--shadow-sm);
}
.btn--ticket:hover { box-shadow: var(--shadow-md); }

/* ------------------------------------------------------------------ shell */
/* flex:none + an explicit height, not flex:1 -- as a flex child, flex:1 sets
   flex-basis:0 and the shell then grows to its content (1622px) instead of
   the viewport. */
.shell {
  flex: none;
  display: flex;
  position: relative;
  overflow: hidden;
  min-height: 0;
  height: calc(100vh - var(--topbar-h, 69px));
  height: calc(100dvh - var(--topbar-h, 69px));
}

/* The topbar is sticky, so the shell must subtract its real height. */
.topbar { --topbar-h: 69px; }

/* Leaflet owns this box. Position/size only -- the tiles come from the
   library, not from a background image as in the design file. */
.map {
  position: absolute; inset: 0;
  background-color: var(--surface-container-low);
}
/* Keep the whole map below the rail/tab bar by stacking the CONTAINER, not
   its panes. Leaflet gives each pane its own z-index (tiles 200, markers 600,
   popups 700); flattening them all to one value renders markers underneath
   the tiles, which looks like "the pins never loaded". */
.map { z-index: 0; }
.map .leaflet-container { font-family: var(--font-body); }
/* {# DATA #} real Leaflet map mounts here — see places/static/css/vendor/leaflet.css */

.pin { position: absolute; transform: translate(-50%, -50%); cursor: pointer; }
.pin__dot {
  width: 40px; height: 40px;
  border-radius: var(--radius-full);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-md);
  transition: transform .3s;
}
.pin:hover .pin__dot { transform: scale(1.1); }
.pin--outdoor .pin__dot {
  background: var(--surface);
  border: 2px solid var(--action-orange);
  color: var(--action-orange);
}
.pin--indoor .pin__dot {
  background: var(--primary);
  border: 2px solid var(--surface);
  color: var(--on-primary);
}
.pin__label {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  margin-top: 4px; padding: 4px 8px;
  background: var(--surface);
  border-radius: var(--radius-sm);
  font-size: 12px; font-weight: 700; white-space: nowrap;
  box-shadow: var(--shadow-sm);
  opacity: 0; transition: opacity .3s;
}
.pin:hover .pin__label { opacity: 1; }


/* --- Map pins ------------------------------------------------------------
   The .pin-bubble / .map-pin rules and the --category-* colours live in the
   theme stylesheets, which v3 deliberately does not load. Without these the
   markers render at zero size: present in the DOM, invisible on screen.
   Colours are mapped onto the v3 palette rather than copied from pebble. */

:root {
  --category-play:     #ffbf00;  /* sun-yellow  */
  --category-eat:      #ff7a59;  /* action-orange */
  --category-urgent:   #2ec4b6;  /* soft-teal */
  --category-learn:    #0057cd;  /* primary */
  --category-explore:  #2e9e5b;
  --category-shopping: #8b6bb1;
  --category-default:  #424655;  /* on-surface-variant */
}

.map-pin { background: none; border: 0; }

.pin-bubble {
  position: relative;
  width: 36px;
  height: 36px;
  background: var(--pin-color, var(--primary));
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid #fff;
  color: #fff;
  box-shadow: 0 4px 12px rgba(25, 27, 36, 0.18);
  transition: transform .2s;
}

.pin-bubble i { font-size: 16px; line-height: 1; }

.map-pin.selected { z-index: 30 !important; }

.map-pin.selected .pin-bubble {
  width: 44px;
  height: 44px;
  border-width: 3px;
  box-shadow: 0 6px 20px rgba(25, 27, 36, 0.3);
}

/* Bookable venue: same Action Orange as the card badge and the Book button,
   so the map carries the signal the rest of the page does. */
.pin-ticket {
  position: absolute;
  top: -2px; right: -2px;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--action-orange);
  border: 2px solid #fff;
  box-sizing: border-box;
}

/* Selected card, when its pin is clicked. */
.card.is-active {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* ------------------------------------------------------------------- rail */
.rail {
  position: relative;
  z-index: 10;
  width: 480px;
  flex: none;
  height: 100%;
  background: rgba(250, 248, 255, 0.95);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-right: 1px solid rgba(194, 198, 216, 0.3);
  box-shadow: var(--shadow-rail);
  display: flex;
  flex-direction: column;
}
.rail__head { flex: none; padding: 24px 24px 0; }
.rail__handle { display: none; }
.rail__scroll {
  flex: 1; overflow-y: auto;
  padding: var(--card-top-gap) 24px 24px;
}
.rail__scroll::-webkit-scrollbar { width: 6px; }
.rail__scroll::-webkit-scrollbar-track { background: transparent; }
.rail__scroll::-webkit-scrollbar-thumb {
  background-color: rgba(194, 198, 216, 0.5);
  border-radius: 10px;
}

.rail h1 {
  font-family: var(--font-display);
  font-size: 24px; line-height: 32px; font-weight: 600;
  margin: 0 0 8px;
  color: var(--on-surface);
}
.rail__lede { margin: 0 0 24px; color: var(--on-surface-variant); }

/* filter chips — pill "bubbles" of information */
/* Desktop wraps: there is no swipe here, and a hidden scrollbar made the
   later filters unreachable. The rail is tall, so rows are cheaper than
   concealed options. Mobile switches back to a swipeable single row. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-bottom: 16px;
  margin-bottom: 8px;
}
.chip {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  padding: 6px 16px;
  border-radius: var(--radius-full);
  font-family: var(--font-label);
  font-size: 14px; line-height: 20px; font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  background: var(--surface);
  color: var(--on-surface);
  border: 1px solid var(--outline-variant);
  transition: background .3s, color .3s, border-color .3s;
}
.chip:hover { background: var(--surface-variant); }
.chip[aria-current="page"] {
  background: var(--primary-container);
  color: var(--on-primary-container);
  border-color: transparent;
  box-shadow: var(--shadow-sm);
}
/* 18px, not the 24px default: the chip is a 32px pill, and the icon has to
   sit on the label's cap height rather than tower over it. */
.chip__icon {
  margin-right: 6px;
  font-size: 18px;
  font-variation-settings: "FILL" 0, "wght" 500, "GRAD" 0, "opsz" 20;
}
.chip[aria-current="page"] .chip__icon { font-variation-settings: "FILL" 1, "wght" 500, "GRAD" 0, "opsz" 20; }
/* the revenue filter reads as an offer, not just another mood */
.chip--book {
  border-color: rgba(255, 122, 89, 0.5);
  color: #b8391c;
  background: rgba(255, 122, 89, 0.10);
  font-weight: 700;
}
.chip--book:hover { background: rgba(255, 122, 89, 0.18); }
.chip--book[aria-current="page"] {
  background: var(--action-orange);
  color: var(--cloud-white);
  border-color: transparent;
}


/* --- Refine row (distance + duration) ------------------------------------
   One ~40px row rather than eight more chips, which on the 480px rail would
   be two extra rows above the results. Same construction as the footer
   language switcher: our own pill with an invisible <select> over it, because
   a styled <select> is not portable across browsers. */
.refine {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 16px;
}

.refine__control {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px 6px 12px;
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius-full);
  background: var(--surface-container-lowest);
  transition: background .2s, border-color .2s;
}

.refine__control:hover { background: var(--surface-variant); }
.refine__control:focus-within { border-color: var(--primary); }

.refine__icon,
.refine__caret { color: var(--outline); font-size: 18px; flex: none; }

.refine__value {
  font-family: var(--font-label);
  font-size: 13px;
  font-weight: 700;
  line-height: 18px;
  color: var(--on-surface);
  white-space: nowrap;
}

/* Invisible but focusable: opacity, not display/visibility, so it keeps
   keyboard access and stays in the accessibility tree. */
.refine__select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  border: 0;
  margin: 0;
  padding: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

.refine__select option { color: var(--on-surface); background: var(--surface); }

.refine__go {
  padding: 6px 14px;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--primary);
  color: #fff;
  font-family: var(--font-label);
  font-weight: 700;
  cursor: pointer;
}

/* ------------------------------------------------------------------ cards */
.cards { display: grid; grid-template-columns: 1fr; gap: 16px; }

.card {
  position: relative;
  background: var(--surface-container-lowest);
  border: 1px solid rgba(194, 198, 216, 0.3);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .3s, transform .3s;
}
/* hover lifts 4px and spreads the shadow — the tactile feedback loop.
   Guarded by (hover: hover): on iOS an element carrying a :hover rule
   consumes the first tap to show that state, so a card needed tapping twice
   to open. Desktop keeps the effect; touch goes straight through. */
@media (hover: hover) {
  .card:hover { box-shadow: var(--shadow-md); transform: translateY(-4px); }
}
/* bookable venues get the orange edge, tying them to the ticketing CTA */
.card--partner { border-color: rgba(255, 122, 89, 0.45); }

.card__media { position: relative; height: 128px; background: var(--surface-container); }
.card--partner .card__media { height: 160px; }
.card__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* gradient scrim for text legibility over photography */
.card__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(33, 37, 41, 0.6), transparent);
}

/* ---------------------------------------------------- iconized card ---
   A place with no photo. Instead of a 128px placeholder that is identical for
   every place in its category, the card goes horizontal: a small category tile
   beside the text. Saves ~96px of height each, which on mobile is the
   difference between seeing two cards and seeing four.

   The colours are the pin colours (--category-*), so a place looks the same in
   the list as on the map. The slug -> colour mapping is duplicated from
   CATEGORY_COLOR_VARS in map-pins.js; places/test_category_colours.py asserts
   the two stay in step, because a silent divergence here is exactly the kind
   of thing nobody notices. */
.card--icon { display: flex; align-items: stretch; gap: 0; }

.card--icon .card__icon {
  flex: none;
  width: 84px;
  display: grid;
  place-items: center;
  /* colour-mix so one variable drives both the tint and the glyph, and the
     tile stays legible on the card surface rather than shouting like a pin. */
  background: color-mix(in srgb, var(--card-cat, var(--category-default)) 12%, transparent);
  color: var(--card-cat, var(--category-default));
}
.card--icon .card__icon i { font-size: 30px; line-height: 1; }
.card--icon .card__body {
  flex: 1;
  min-width: 0;
  padding: 12px 14px;
  /* Centre the text against the icon tile. Without this the title sits at the
     top of a short card and the tile beside it looks unbalanced -- the photo
     layout has enough height that top-alignment reads fine, this one does
     not. */
  display: flex;
  flex-direction: column;
  justify-content: center;
}
/* No photo means no scrim, and the title sits on the surface, not on an image. */
.card--icon .card__media, .card--icon .card__media::after { display: none; }
/* Keep the save control clear of the icon tile. */
.card--icon .card__save { top: 8px; right: 8px; }
/* A bookable place without a photo is still bookable, so the badge stays --
   but it MUST remain absolutely positioned. The badge is a direct child of
   .card, and .card--icon is display:flex, so position:static turns it into a
   flex item wedged between the icon tile and the body.
   Icon-only here: "Tickets" does not fit over an 84px tile, and the Book
   button below already carries the word. font-size:0 collapses the text node
   while the glyph keeps its own size; the label still reaches screen readers. */
.card--icon .card__badge {
  top: 8px; left: 8px;
  padding: 4px;
  gap: 0;
  font-size: 0;
}
.card--icon .card__badge .material-symbols-outlined { font-size: 16px; }

/* Category colours, mirroring map-pins.js CATEGORY_COLOR_VARS. */
.card--icon[data-category="indoor_playground"],
.card--icon[data-category="playground"],
.card--icon[data-category="farm"]            { --card-cat: var(--category-play); }
.card--icon[data-category="cafe"],
.card--icon[data-category="restaurant"],
.card--icon[data-category="bakery"],
.card--icon[data-category="ice_cream"]       { --card-cat: var(--category-eat); }
.card--icon[data-category="toilets"]         { --card-cat: var(--category-urgent); }
.card--icon[data-category="museum"],
.card--icon[data-category="zoo"],
.card--icon[data-category="library"],
.card--icon[data-category="science_center"],
.card--icon[data-category="aquarium"],
.card--icon[data-category="historic_site"]   { --card-cat: var(--category-learn); }
.card--icon[data-category="park"],
.card--icon[data-category="hiking"],
.card--icon[data-category="landmark"],
.card--icon[data-category="theme_park"],
.card--icon[data-category="water_park"]      { --card-cat: var(--category-explore); }
.card--icon[data-category="shopping"]        { --card-cat: var(--category-shopping); }

.card__badge {
  position: absolute; top: 12px; left: 12px; z-index: 2;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  background: var(--action-orange);
  color: var(--cloud-white);
  font-size: 12px; font-weight: 700;
  box-shadow: var(--shadow-sm);
}
.card__badge .material-symbols-outlined { font-size: 14px; }

/* Save works without an account (local first, synced on sign-in), so it is a
   plain toggle with no auth gate in front of it. */
.card__save {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  border: 0;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.92);
  color: var(--on-surface-variant);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: color .3s, transform .15s, background .3s;
}
.card__save:hover { background: #fff; color: var(--action-orange); }
.card__save:active { transform: scale(.9); }
.card__save[aria-pressed="true"] { color: var(--action-orange); }
.card__save[aria-pressed="true"] .material-symbols-outlined {
  font-variation-settings: "FILL" 1;
}
.card__save .material-symbols-outlined { font-size: 20px; }

/* ticketing block — the only Action Orange inside a card */
.card__book {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(194, 198, 216, 0.4);
}
.card__price {
  font-family: var(--font-label);
  font-size: 13px;
  color: var(--on-surface-variant);
}
.card__price strong { color: var(--on-surface); font-size: 15px; }
/* sits above the card's stretched link so it is separately clickable */
.card__bookcta {
  position: relative; z-index: 2;
  text-decoration: none;
  display: inline-block;
}

.card__body { padding: 16px; }
.card__title {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--on-surface);
  margin: 0;
  font-size: 18px; line-height: 26px;
}
.card--partner .card__title { font-size: 20px; line-height: 28px; }
.card__desc {
  font-family: var(--font-label);
  font-size: 14px; line-height: 20px;
  color: var(--on-surface-variant);
  margin: 4px 0 12px;
}
.card__meta {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 12px;
}
.card__tags { display: flex; gap: 8px; flex-wrap: wrap; }
.tag {
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  background: var(--surface-variant);
  color: var(--on-surface-variant);
  font-size: 12px; font-weight: 700;
}
.card__distance { color: var(--primary); font-weight: 700; white-space: nowrap; }
/* whole card is clickable without nesting interactive elements */
.card__link::after { content: ""; position: absolute; inset: 0; }
.card__link { position: static; color: inherit; text-decoration: none; }

/* ----------------------------------------------------------------- footer */
.sitefooter {
  flex: none;
  background: var(--deep-onyx);
  border-top: 1px solid rgba(114, 119, 135, 0.2);
  font-family: var(--font-label);
  font-size: 14px; line-height: 20px;
}
/* venue acquisition band, sitting on top of the footer proper */
.venuecta { border-bottom: 1px solid rgba(114, 119, 135, 0.25); }
.venuecta__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 32px var(--margin-desktop);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--gutter);
  flex-wrap: wrap;
}
.venuecta h2 {
  font-family: var(--font-display);
  font-size: 22px; line-height: 30px; font-weight: 600;
  color: var(--cloud-white);
  margin: 0;
}
.venuecta p { color: var(--outline-variant); margin: 4px 0 0; }
.btn--ondark {
  padding: 10px 24px;
  background: var(--cloud-white);
  color: var(--deep-onyx);
  border: 0;
  text-decoration: none;
  display: inline-block;
  flex: none;
}
.btn--ondark:hover { box-shadow: var(--shadow-md); }

.sitefooter__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 48px var(--margin-desktop);
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: var(--gutter);
}
.sitefooter__brandcol { display: flex; flex-direction: column; align-items: flex-start; }
.sitefooter__brand { display: inline-block; margin-bottom: 16px; }
.sitefooter__brand img { height: 32px; width: auto; display: block; }
.sitefooter p { color: var(--outline-variant); margin: 0; }
.sitefooter__col { display: flex; flex-direction: column; gap: 12px; }
.sitefooter__col h3 {
  font-family: var(--font-label);
  font-size: 12px; line-height: 16px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--cloud-white);
  margin: 0 0 4px;
}
.sitefooter__col a {
  color: var(--outline-variant);
  text-decoration: none;
  opacity: .8;
  transition: color .3s, opacity .3s;
}
.sitefooter__col a:hover { color: var(--cloud-white); opacity: 1; text-decoration: underline; }
.sitefooter__lang {
  margin-top: 16px;
  color: var(--outline-variant);
  text-decoration: none;
  opacity: .8;
}
.sitefooter__lang:hover { color: var(--cloud-white); opacity: 1; }

/* four columns need more room than three did */
@media (max-width: 1100px) {
  .sitefooter__inner { grid-template-columns: 1fr 1fr 1fr; }
  .sitefooter__brandcol { grid-column: 1 / -1; }
}

/* legal links inside the mobile sheet; hidden while the footer is visible */
.sheet-legal { display: none; }

/* ---------------------------------------------------------------- tabbar */
.tabbar { display: none; }

/* ------------------------------------------------- mobile search trigger */
.mapsearch { display: none; }

/* =========================================================== geo dialog */
.scrim {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(33, 37, 41, 0.4);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: fade .2s ease;
}
.scrim[hidden] { display: none; }
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }

.geodialog {
  position: fixed; inset: 0; z-index: 100;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 96px var(--margin-desktop) var(--margin-desktop);
  pointer-events: none;      /* only the panel is interactive */
}
.geodialog[hidden] { display: none; }

.geodialog__panel {
  pointer-events: auto;
  width: 100%;
  max-width: 512px;
  background: var(--surface);
  border: 1px solid rgba(194, 198, 216, 0.3);
  border-radius: var(--radius-lg);
  box-shadow: 0 12px 40px rgba(25, 27, 36, 0.18), 0 4px 12px rgba(13, 110, 253, 0.08);
  overflow: hidden;
  animation: dialog-in .25s cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes dialog-in {
  from { opacity: 0; transform: translateY(-8px) scale(.98); }
  to   { opacity: 1; transform: none; }
}

.geodialog__handle { display: none; }

.geodialog__body { display: flex; gap: 16px; padding: 24px 24px 0; }
.geodialog__icon {
  flex: none;
  width: 48px; height: 48px;
  border-radius: var(--radius-full);
  background: rgba(13, 110, 253, 0.10);
  color: var(--primary);
  display: flex; align-items: center; justify-content: center;
}
.geodialog__icon .material-symbols-outlined { font-size: 28px; }
.geodialog h2 {
  font-family: var(--font-display);
  font-size: 24px; line-height: 32px; font-weight: 600;
  margin: 0; color: var(--on-surface);
}
.geodialog p { margin: 4px 0 0; color: var(--on-surface-variant); }

.geodialog__actions {
  display: flex; justify-content: flex-end; gap: 12px;
  padding: 24px;
}
.btn--quiet {
  padding: 8px 16px;
  background: transparent;
  border: 0;
  color: var(--on-surface-variant);
}
.btn--quiet:hover { background: var(--surface-variant); }
.btn--primary {
  padding: 8px 24px;
  background: var(--primary);
  color: var(--on-primary);
  border: 0;
  box-shadow: var(--shadow-sm);
}
.btn--primary:hover { box-shadow: var(--shadow-md); }

/* ====================================================== location search */
.locsearch { display: none; }


/* --- Language switcher (footer) ----------------------------------------- */
/* Mirrors .locpicker__trigger from the header, in a dark-footer palette.
   The pill below is our markup; the <select> is invisible on top of it, so no
   browser ever paints the closed control and it cannot drift from the design
   the way a styled <select> does. */
.langswitch { margin-top: 20px; }

.langswitch__control {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px 9px 14px;
  border: 1px solid rgba(194, 198, 216, 0.3);
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.04);
  transition: background .3s, border-color .3s;
}

.langswitch__control:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(194, 198, 216, 0.55);
}

/* :focus-within, not :focus -- focus lands on the invisible select, but the
   ring belongs on the pill the user can see. */
.langswitch__control:focus-within {
  border-color: var(--cloud-white);
  background: rgba(255, 255, 255, 0.10);
}

.langswitch__icon,
.langswitch__caret {
  color: var(--outline-variant);
  font-size: 20px;
  flex: none;
  transition: color .3s;
}

.langswitch__value {
  font-family: var(--font-label);
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  color: var(--cloud-white);
  white-space: nowrap;
}

.langswitch__control:hover .langswitch__icon,
.langswitch__control:focus-within .langswitch__icon { color: var(--cloud-white); }

/* Invisible, but covering the whole pill so a click anywhere opens it.
   opacity:0 rather than visibility/display: those would make it
   unfocusable and remove it from the accessibility tree. */
.langswitch__select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  border: 0;
  margin: 0;
  padding: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

/* The dropdown LIST is still painted by the OS from the option's own colours,
   not the select's -- without this it is unreadable on some platforms. */
.langswitch__select option {
  color: var(--on-surface);
  background: var(--surface);
  font-weight: 500;
}

.langswitch__go {
  margin-left: 8px;
  padding: 9px 16px;
  border-radius: var(--radius-full);
  border: 0;
  background: var(--cloud-white);
  color: var(--deep-onyx);
  font-family: var(--font-label);
  font-weight: 700;
  cursor: pointer;
}

/* Visually hidden but available to screen readers. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------ responsive */
/* Tablet: rail narrows and the topbar tightens before anything collapses. */
@media (max-width: 1200px) {
  .rail { width: 400px; }
  .topbar__inner { padding-left: 24px; padding-right: 24px; gap: 12px; }
  .topbar__left { gap: 20px; }
  .mainnav { gap: 16px; }
  .topbar__right { gap: 12px; }
  .locpicker__trigger { max-width: 190px; }
}

/* Below this the nav and the search genuinely cannot coexist. Search wins —
   this is a discovery page — and the nav links stay reachable in the footer. */
@media (max-width: 1000px) {
  .mainnav { display: none; }
  .locpicker__trigger { max-width: 240px; }
}

/* ===========================================================================
   Mobile: app shell, not a scrolled page.

   The map owns the viewport and the rail becomes a bottom sheet over it,
   following the sheet convention already used in places/ (24px top radius,
   translateY + cubic-bezier(.2,.8,.2,1), 40x4 grab handle). Three snap points
   driven by the --sheet-y custom property so the drag gesture can write an
   arbitrary value between them.
   =========================================================================== */
@media (max-width: 900px) {
  html, body { height: 100%; }
  body {
    overflow: hidden;   /* mobile stays a fixed app shell */
    /* fall back for browsers without dvh, then prefer it: avoids the sheet
       being clipped by mobile Safari's collapsing toolbar */
    height: 100vh;
    height: 100dvh;
  }

  /* compact app-style top bar floating over the map */
  .topbar {
    background: rgba(250, 248, 255, 0.92);
    /* Collapsible: discovery-v3.js adds body.sheet-open once the sheet is
       opened past ~30%, giving these ~52px back to the list. max-height
       rather than transform, because the space has to be reclaimed by the
       layout, not merely vacated -- .shell is flex:1 and grows into it. */
    max-height: 80px;
    overflow: hidden;
    transition: max-height .25s ease;
  }
  body.sheet-open .topbar { max-height: 0; }
  .topbar__inner { padding: 6px var(--margin-mobile); }
  /* the tab bar's Book tab is the persistent ticketing CTA here, so the
     topbar one would just be a second copy of it */
  .mainnav, .locpicker, .btn--ghost, .topbar .btn--ticket { display: none; }
  .brand img { height: 26px; }
  .topbar__account {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; margin-right: -8px;
    border-radius: var(--radius-full);
    color: var(--on-surface-variant);
    text-decoration: none;
    transition: background .3s, color .3s;
  }
  .topbar__account:hover { background: var(--surface-container); color: var(--primary); }

  /* Mobile: back to a fixed shell, footer hidden, sheet over the map. */
  .shell { position: relative; overflow: hidden; height: auto; flex: 1; }

  /* map fills everything behind the sheet */
  .map { position: absolute; inset: 0; }

  /* ---- the sheet ---- */
  .rail {
    /* % of shell height hidden at rest. Lowered from 54: the header chrome
       (handle + title + chips + refine) left under ~100px of cards, which
       is less than one card and made the list awkward to scroll. */
    --sheet-peek: 46;
    --sheet-y: var(--sheet-peek);
    position: absolute;
    left: 0; right: 0; bottom: 0;
    top: 0;
    width: 100%;
    height: auto;
    z-index: 40;
    background: var(--surface-container-lowest);
    border-right: 0;
    border-radius: 24px 24px 0 0;
    /* stronger than the card shadow: this floats above the map */
    box-shadow: 0 -4px 24px rgba(13, 110, 253, 0.12), 0 -1px 4px rgba(25, 27, 36, 0.06);
    transform: translateY(calc(var(--sheet-y) * 1%));
    transition: transform .3s cubic-bezier(0.2, 0.8, 0.2, 1);
    overscroll-behavior: contain;
  }
  /* while dragging, follow the finger with no easing */
  .rail.is-dragging { transition: none; }
  .rail.is-expanded { --sheet-y: 2; }
  .rail.is-collapsed { --sheet-y: 78; }
  /* Collapsed shows only the handle and the title. Hiding the chips rather
     than tuning the snap % keeps the cut clean whatever the translated
     strings wrap to. */
  .rail.is-collapsed .chips,
  .rail.is-collapsed .rail__scroll { display: none; }

  /* single swipeable row on touch, where the gesture is natural and the
     vertical space is scarce */
  .chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
  }
  .chips::-webkit-scrollbar { display: none; }
  .chip { white-space: nowrap; flex: none; }

  .rail__head { padding: 0 var(--margin-mobile) 0; }

  /* Grab handle. The bar stays 40x4 (matching places/ collection_add_sheet),
     but the HIT AREA is 44px tall -- the minimum comfortable touch target.
     At the old 10px/14px padding it was ~28px, which is why the sheet was
     hard to grab. */
  .rail__handle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 44px;
    padding: 0;
    background: none;
    border: 0;
    cursor: grab;
    touch-action: none;          /* we handle the drag ourselves */
  }
  .rail__handle:active { cursor: grabbing; }
  .rail__handle span {
    display: block;
    width: 40px; height: 4px;
    margin: 0 auto;
    border-radius: 2px;
    background: var(--outline-variant);
  }

  .rail h1 {
    font-size: 20px; line-height: 26px;
    margin-bottom: 12px;
    /* Doubles as a drag surface (see discovery-v3.js). touch-action:none is
       required or the browser scrolls instead of giving us pointermove. Safe
       here because an h1 has nothing to tap; it is NOT set on .rail__head,
       which would kill the chips' horizontal swipe. */
    touch-action: none;
    cursor: grab;
    user-select: none;
  }
  /* Hidden on mobile: the h1 already says what this list is, and at peek this
     line cost ~38px of the ~100px left for cards. */
  .rail__lede { display: none; }

  /* Once the visitor has actually used the sheet, the title has done its job
     and becomes 38px of wasted height. Set by discovery-v3.js on first drag or
     scroll, remembered for the session. */
  .rail--compact .rail__head h1 { display: none; }
  /* The h1 doubles as a drag surface, so removing it would drop the grab area
     back to 44px. Give the handle the height instead -- same target, no title. */
  .rail--compact .rail__handle { min-height: 56px; }

  .rail__scroll {
    /* The sheet is a FULL-height element pushed down by translateY, so the
       bottom var(--sheet-y)% of it sits below the shell's clip. .rail__scroll
       is flex:1 against that full height, which left its last stretch of
       content permanently below the fold AND unscrollable -- the container
       itself was not overflowing.
       --sheet-hidden is that offset in px, written by discovery-v3.js
       (setState + drag). Padding it back makes the last card reachable, and
       makes the container overflow again so the scroll-to-expand handler
       still fires. */
    padding: var(--card-top-gap) var(--margin-mobile)
             calc(24px + var(--sheet-hidden, 0px));
    /* -webkit-overflow-scrolling: touch removed. Momentum scrolling has been
       the default since iOS 13, and the property creates its own stacking
       context -- a documented cause of absolutely positioned children inside
       the scroller (here: .card__link::after, the stretched tap target)
       becoming untappable on device while working in desktop emulation. */
    overscroll-behavior: contain;
  }
  /* room for the tab bar plus the home indicator */
  .rail__scroll::after {
    content: "";
    display: block;
    height: calc(72px + env(safe-area-inset-bottom));
  }

  /* legal links replace the footer down here */
  .sitefooter { display: none; }
  .sheet-legal {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 16px;
    margin-top: 24px;
    padding-top: 16px;
    border-top: 1px solid rgba(194, 198, 216, 0.4);
  }
  .sheet-legal a {
    font-family: var(--font-label);
    font-size: 13px;
    color: var(--on-surface-variant);
    text-decoration: none;
  }
  .sheet-legal a:hover { text-decoration: underline; }

  /* ---- bottom tab bar ---- */
  .tabbar {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 60;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    background: rgba(255, 255, 255, 0.94);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-top: 1px solid rgba(194, 198, 216, 0.4);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .tabbar__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 8px 4px 10px;
    text-decoration: none;
    color: var(--on-surface-variant);
    font-family: var(--font-label);
    font-size: 11px;
    font-weight: 700;
    transition: color .3s;
  }
  .tabbar__item .material-symbols-outlined { font-size: 24px; }
  .tabbar__item[aria-current="page"] { color: var(--primary); }
  /* Book stays orange even when inactive — it is the revenue surface */
  .tabbar__item--accent { color: var(--action-orange); }
  .tabbar__item--accent[aria-current="page"] { color: var(--action-orange); }

  /* ---- floating search + locate over the map ---- */
  .mapsearch {
    position: absolute;
    top: 12px; left: var(--margin-mobile); right: var(--margin-mobile);
    z-index: 30;
    display: flex;
    gap: 8px;
  }
  .mapsearch__field {
    height: 48px;
    background: var(--surface-container-lowest);
    border: 1px solid rgba(194, 198, 216, 0.3);
    border-radius: var(--radius-full);
    box-shadow: 0 2px 8px rgba(13, 110, 253, 0.10);
    cursor: pointer;
    transition: transform .15s;
  }
  .mapsearch__field:active { transform: scale(.95); }
  .mapsearch__field {
    flex: 1;
    min-width: 0;
    display: flex; align-items: center; gap: 12px;
    padding: 0 16px;
    font-family: var(--font-body);
    font-size: 16px;
    color: var(--on-surface-variant);
    text-align: left;
  }
  .mapsearch__field .material-symbols-outlined { color: var(--primary); flex: none; }
  .mapsearch__label {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-weight: 600; color: var(--on-surface);
  }
  .mapsearch__caret { color: var(--outline) !important; }

  /* ---- permission ask becomes a bottom sheet ---- */
  .geodialog {
    align-items: flex-end;
    padding: 0;
  }
  .geodialog__panel {
    max-width: none;
    border: 0;
    border-radius: 24px 24px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
    animation: sheet-in .3s cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  @keyframes sheet-in {
    from { transform: translateY(100%); }
    to   { transform: none; }
  }
  .geodialog__handle {
    display: block;
    width: 100%;
    padding: 10px 0 4px;
    background: none; border: 0;
  }
  .geodialog__handle span {
    display: block;
    width: 40px; height: 4px; margin: 0 auto;
    border-radius: 2px;
    background: var(--outline-variant);
  }
  .geodialog__body { padding: 16px var(--margin-mobile) 0; }
  .geodialog h2 { font-size: 20px; line-height: 28px; }
  .geodialog__actions {
    padding: 24px var(--margin-mobile) 32px;
  }
  /* full-width stacked buttons read better under the thumb */
  .geodialog__actions .btn { flex: 1; transform: none; padding: 12px 16px; }
  .geodialog__actions .btn:active { transform: scale(.97); }

  /* ---- full-screen location search ---- */
  .locsearch {
    position: fixed; inset: 0; z-index: 110;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    transform: translateY(100%);
    transition: transform .3s cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  .locsearch[hidden] { display: none; }
  .locsearch.is-open { transform: none; }

  .locsearch__head {
    flex: none;
    padding: env(safe-area-inset-top) var(--margin-mobile) 16px;
    border-bottom: 1px solid rgba(194, 198, 216, 0.2);
  }
  .locsearch__bar {
    display: flex; align-items: center; justify-content: space-between;
    padding-top: 8px; margin-bottom: 16px;
  }
  .locsearch__back {
    width: 40px; height: 40px; margin-left: -8px;
    display: flex; align-items: center; justify-content: center;
    border: 0; background: none; cursor: pointer;
    border-radius: var(--radius-full);
    color: var(--on-surface-variant);
  }
  .locsearch__back:hover { background: var(--surface-container); }
  .locsearch__title {
    font-family: var(--font-display);
    font-size: 18px; font-weight: 600; color: var(--on-surface);
  }
  .locsearch__spacer { width: 40px; }

  .locsearch__input { position: relative; }
  .locsearch__input .material-symbols-outlined {
    position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
    color: var(--outline); pointer-events: none;
  }
  .locsearch__input input {
    width: 100%;
    padding: 12px 16px 12px 48px;
    background: var(--surface-container-lowest);
    border: 2px solid var(--outline-variant);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: 16px;             /* 16px min, or iOS zooms on focus */
    color: var(--on-surface);
    outline: none;
    box-shadow: var(--shadow-sm);
    transition: border-color .2s;
  }
  .locsearch__input input:focus { border-color: var(--primary); }

  .locsearch__body {
    flex: 1;
    overflow-y: auto;
    padding: 16px var(--margin-mobile) calc(24px + env(safe-area-inset-bottom));
    background: var(--surface-bright, var(--surface));
  }

  .locsearch__current {
    width: 100%;
    display: flex; align-items: center; gap: 16px;
    padding: 16px;
    margin-bottom: 24px;
    background: rgba(13, 110, 253, 0.08);
    border: 0;
    border-radius: var(--radius-md);
    cursor: pointer;
    text-align: left;
    transition: background .2s, transform .15s;
  }
  .locsearch__current:hover { background: rgba(13, 110, 253, 0.16); }
  .locsearch__current:active { transform: scale(.98); }
  .locsearch__current-icon {
    flex: none;
    width: 40px; height: 40px;
    border-radius: var(--radius-full);
    background: var(--primary);
    color: var(--on-primary);
    display: flex; align-items: center; justify-content: center;
    box-shadow: var(--shadow-sm);
  }
  .locsearch__current-title {
    display: block;
    font-family: var(--font-label);
    font-size: 16px; font-weight: 700; color: var(--primary);
  }
  .locsearch__current-sub {
    display: block; font-size: 13px; color: rgba(0, 87, 205, 0.8);
  }

  .locsearch__label {
    font-family: var(--font-label);
    font-size: 12px; line-height: 16px; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase;
    color: var(--outline);
    margin: 24px 0 12px; padding: 0 8px;
  }
  .locsearch__label:first-of-type { margin-top: 0; }

  .locsearch__list { list-style: none; margin: 0; padding: 0; }
  .locsearch__list a,
  .locsearch__list button {
    width: 100%;
    display: flex; align-items: center; gap: 16px;
    padding: 12px;
    border: 0; background: none; cursor: pointer;
    border-radius: var(--radius);
    font-family: var(--font-body);
    font-size: 16px;
    color: var(--on-surface);
    text-align: left;
    transition: background .2s, color .2s;
  }
  .locsearch__list a,
  .locsearch__list a:visited { text-decoration: none; color: var(--on-surface); }
  .locsearch__list a:hover,
  .locsearch__list button:hover { background: var(--surface-container); color: var(--primary); }
  .locsearch__list .material-symbols-outlined { color: var(--outline-variant); flex: none; }
  .locsearch__list--places button:hover { color: var(--on-surface); }
  .locsearch__list--places button:hover .material-symbols-outlined { color: var(--action-orange); }
}

/* Users who prefer reduced motion get the snap without the slide. */
@media (prefers-reduced-motion: reduce) {
  .rail, .card, .btn, .chip { transition: none; }
}
