/* ==========================================================================
   BTS BLVD — interactive map
   Palette leans on "borahae" purple with the Korean-flag red/blue accents
   used in the reference poster.
   ========================================================================== */

:root {
  --purple:       #7B2CFF;
  --purple-deep:  #3D0F86;
  --purple-soft:  #F2EBFF;
  --pink:         #FF3D77;
  --red:          #E3122F;
  --blue:         #1E4FD8;
  --gold:         #FFB300;
  --gold-deep:    #E08600;

  --ink:          #1B1030;
  --ink-soft:     #5B4E77;
  --line:         #E7DFF6;
  --paper:        #FFFFFF;
  --paper-2:      #FBF8FF;

  --panel-w:      380px;
  --radius:       14px;

  /* Spare scroll length kept under the map page purely so an in-app browser
     sees a page that can scroll and isn't parked at the very top. See the
     `.page-map` block below. */
  --runway:       64px;
  --shadow-sm:    0 1px 2px rgba(27,16,48,.08), 0 2px 8px rgba(27,16,48,.06);
  --shadow-md:    0 6px 24px rgba(27,16,48,.14);
  --shadow-lg:    0 18px 50px rgba(27,16,48,.22);

  --font: 'Outfit', system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  font-family: var(--font);
  color: var(--ink);
  background: var(--paper-2);
  -webkit-font-smoothing: antialiased;
  /* No pull-to-refresh, no overscroll glow, and nothing handed up to a host
     webview — safe on the partner page too, which still scrolls normally. */
  overscroll-behavior: none;
}

/* In-app browsers (Threads, Instagram, Facebook) put the page inside a sheet
   that drags away to dismiss, and both platforms decide whether a drag belongs
   to that sheet by asking the webview whether its content can scroll: iOS looks
   at the scroll view, Android calls `canScrollVertically`. Pinning the page
   down (`position: fixed` on html/body) answers "no, nothing to scroll" — so
   every map pan was handed straight to the host's dismiss gesture and the whole
   browser moved instead of the map.

   So the app is pinned, not the document: `.app` is fixed to the viewport, and
   the document keeps a short empty runway (`--runway`) below it that app.js
   parks in the middle of. The webview now answers "yes, and it isn't at the
   top", keeps the gesture, and nothing moves on screen because the only thing
   in flow is blank space behind a fixed layer.
   Scoped to the map page; partner.html must keep scrolling normally. */
html.page-map > body { overflow-x: hidden; }
/* Touch devices only — a mouse pointer would just get a pointless scrollbar. */
@media (pointer: coarse) {
  html.page-map > body { min-height: calc(100% + var(--runway)); }
}
html.page-map .app {
  position: fixed;
  top: 0; left: 0;
  width: 100%;
}

a { color: var(--purple); }

/* ── Layout ────────────────────────────────────────────────────────────── */

/* Height, most-wanted last. `100vh` on Android/iOS measures the *largest*
   viewport (browser bar retracted), so the bottom of the app hides behind the
   URL bar; `100dvh` fixes that but is missing on older phone browsers (LG G7
   era), where the whole declaration is dropped and the grid collapses to
   content height. `--app-h` is the belt-and-braces layer: app.js writes the
   real `innerHeight` into it and adds `.has-vh`, so a browser that understands
   neither still gets an exact fit. */
.app {
  display: grid;
  grid-template-columns: var(--panel-w) 1fr;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}
body.has-vh .app { height: var(--app-h); }

.mapwrap { position: relative; }
#map { position: absolute; inset: 0; background: #E8E3F5; }

/* Leaflet already claims the gesture on the map itself; these are the bits of
   chrome sitting *over* it, where a stray drag would otherwise reach the page. */
.mapwrap, .legend, .onboardTip, .pinNudge, .fab, .brand, .controls, .detailModal__backdrop {
  touch-action: none;
}
/* …but anything that legitimately scrolls keeps its own gesture, and keeps it
   to itself. */
.listwrap, .detailModal__box, .leaflet-popup-content {
  touch-action: pan-y;
  overscroll-behavior: contain;
}

/* ── Sidebar ───────────────────────────────────────────────────────────── */

.panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--paper);
  border-right: 1px solid var(--line);
  box-shadow: 6px 0 28px rgba(27,16,48,.07);
  /* above Leaflet's control pane (1000) so the attribution can't bleed
     through the list sheet on phones */
  z-index: 1100;
}

/* Everything below the header. On desktop it just fills the sidebar; on
   phones it becomes the sheet that slides up over the map. */
.sheet {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--paper);
}

.brand {
  padding: 22px 22px 18px;
  background:
    radial-gradient(120% 120% at 0% 0%, #9B4DFF 0%, var(--purple) 42%, var(--purple-deep) 100%);
  color: #fff;
  position: relative;
  overflow: hidden;
}
/* soft light streak, echoes the poster's sticker feel */
.brand::after {
  content: "";
  position: absolute; inset: -40% -20% auto auto;
  width: 260px; height: 260px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.22), transparent 65%);
  pointer-events: none;
}

.brand__mark {
  margin: 0;
  display: flex; align-items: baseline; gap: 8px;
  font-weight: 900; letter-spacing: -.02em; line-height: .92;
}
.brand__mark--sub {
  margin-top: 4px;
}
.brand__bts {
  font-size: 46px;
  color: #fff;
  text-shadow: 3px 3px 0 var(--red), 6px 6px 0 rgba(0,0,0,.18);
}
.brand__blvd {
  font-family: 'Unbounded', var(--font);
  font-size: 38px;
  font-weight: 800;
  letter-spacing: 0;
  color: #fff;
}
.brand__tagline {
  margin: 10px 0 0;
  font-size: 18px; font-weight: 700; line-height: 1.3;
  color: #fff;
}
.brand__dates {
  margin: 12px 0 0;
  display: inline-block;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(255,255,255,.16);
  border: 1px solid rgba(255,255,255,.35);
  font-size: 11.5px; font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase;
}

/* ── Controls ──────────────────────────────────────────────────────────── */

.controls {
  padding: 14px 18px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}

.search { position: relative; }
.search svg {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 17px; height: 17px;
  fill: none; stroke: var(--ink-soft); stroke-width: 2; stroke-linecap: round;
  pointer-events: none;
}
.search input {
  width: 100%;
  padding: 10px 12px 10px 36px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: var(--paper-2);
  font: inherit; font-size: 14px;
  color: var(--ink);
}
.search input:focus {
  outline: none;
  border-color: var(--purple);
  box-shadow: 0 0 0 3px rgba(123,44,255,.15);
  background: #fff;
}

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.chip {
  border: 1.5px solid var(--line);
  background: var(--paper-2);
  color: var(--ink-soft);
  border-radius: 999px;
  padding: 5px 11px;
  font: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer;
  transition: all .14s ease;
  white-space: nowrap;
}
.chip:hover { border-color: #C9B6F5; color: var(--ink); }
.chip[aria-pressed="true"] {
  background: var(--purple);
  border-color: var(--purple);
  color: #fff;
  box-shadow: 0 2px 8px rgba(123,44,255,.32);
}

.toggle {
  display: flex; align-items: center; gap: 9px;
  margin-top: 12px;
  cursor: pointer;
  user-select: none;
}
.toggle input { position: absolute; opacity: 0; pointer-events: none; }
.toggle__box {
  width: 34px; height: 20px; border-radius: 999px;
  background: #DED4F0; position: relative; flex: none;
  transition: background .16s ease;
}
.toggle__box::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px; border-radius: 50%;
  background: #fff; box-shadow: var(--shadow-sm);
  transition: transform .16s ease;
}
.toggle input:checked + .toggle__box { background: var(--gold); }
.toggle input:checked + .toggle__box::after { transform: translateX(14px); }
.toggle input:focus-visible + .toggle__box { box-shadow: 0 0 0 3px rgba(123,44,255,.3); }
.toggle__label { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.toggle__label .star {
  display: inline-block;
  color: var(--gold-deep);
  animation: star-pop 1.1s ease-in-out infinite;
}

@keyframes star-pop {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.45); }
}

@media (prefers-reduced-motion: reduce) {
  .toggle__label .star { animation: none; }
}

.featured-cta {
  display: block;
  margin-top: 10px;
  padding: 8px 12px;
  border-radius: 9px;
  border: 1.5px solid var(--gold);
  background: var(--gold);
  color: #fff;
  font-size: 12.5px; font-weight: 800;
  text-align: center;
  text-decoration: none;
  transition: all .13s ease;
}
.featured-cta:hover {
  background: var(--gold-deep);
  border-color: var(--gold-deep);
}

/* ── List ──────────────────────────────────────────────────────────────── */

.listwrap { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }

.listcount {
  margin: 0; padding: 11px 18px 7px;
  font-size: 11px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-soft);
}

.list { list-style: none; margin: 0; padding: 0 10px 4px; }

.item {
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: 11px;
  padding: 11px 10px;
  border-radius: 11px;
  cursor: pointer;
  transition: background .13s ease;
  position: relative;
}
.item:hover { background: var(--purple-soft); }
.item.is-active { background: var(--purple-soft); box-shadow: inset 0 0 0 1.5px #C9B6F5; }

.item__num {
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 12px; font-weight: 800; color: #fff;
  background: var(--pink);
  box-shadow: var(--shadow-sm);
  margin-top: 1px;
}
.item.is-featured .item__num {
  background: linear-gradient(150deg, #FFD24A, var(--gold-deep));
  box-shadow: 0 0 0 3px rgba(255,179,0,.22);
}

.item__name {
  font-size: 14.5px; font-weight: 700; line-height: 1.25;
  margin: 0;
}
.item__meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin-top: 5px;
  font-size: 11.5px; color: var(--ink-soft);
}
.item__cat {
  font-weight: 700;
  padding: 1.5px 7px; border-radius: 999px;
  background: var(--paper-2); border: 1px solid var(--line);
}
.item__addr { margin: 4px 0 0; font-size: 11.5px; color: var(--ink-soft); }

.badge-fx {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1.5px 7px; border-radius: 999px;
  background: linear-gradient(120deg, #FFF0C2, #FFE08A);
  border: 1px solid #F0C24A;
  color: #7A4A00;
  font-size: 10.5px; font-weight: 800; letter-spacing: .03em;
}

/* Sits under the listings at the bottom of the sidebar: the plain-text
   description of the boulevard, and the way into the two content pages. */
.about {
  margin: 14px 10px 0; padding: 16px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.about__title {
  margin: 0 0 8px;
  font-size: 13px; font-weight: 800; color: var(--ink);
}
.about p { margin: 0; font-size: 12px; line-height: 1.6; color: var(--ink-soft); }
.about b { color: var(--ink); }
.about .about__links {
  display: flex; flex-wrap: wrap; gap: 4px 14px;
  margin-top: 12px;
  font-size: 12px; font-weight: 700;
}
.about__links a { text-decoration: none; }
.about__links a:hover { text-decoration: underline; }

.disclaimer {
  margin: 6px 0 0; padding: 14px 20px 22px;
  font-size: 11px; line-height: 1.55; color: #8B7FA6;
  border-top: 1px solid var(--line);
}

.siteFooter {
  margin: 0; font-size: 11px; line-height: 1.5; color: #B0A5CB;
}
.siteFooter a { color: inherit; font-weight: 700; text-decoration: underline; }
.siteFooter--inline { padding: 0 20px 18px; margin-top: -8px; }

/* ── Star rating ───────────────────────────────────────────────────────── */

.stars {
  display: inline-flex; align-items: center; gap: 5px;
  font-variant-numeric: tabular-nums;
}
.stars__glyphs {
  position: relative;
  display: inline-block;
  font-size: 12px;
  letter-spacing: 1.5px;
  line-height: 1;
  color: #DCD3EC;
}
.stars__glyphs::before { content: "★★★★★"; }
.stars__fill {
  position: absolute; inset: 0;
  overflow: hidden;
  white-space: nowrap;
  color: var(--gold);
}
.stars__fill::before { content: "★★★★★"; }
.stars__val { font-weight: 800; font-size: 11.5px; color: var(--ink); }
.stars__count { font-size: 11px; color: var(--ink-soft); }

/* ══════════════════════════════════════════════════════════════════════════
   MAP MARKERS
   ══════════════════════════════════════════════════════════════════════════ */

.leaflet-container { font-family: var(--font); background: #E8E3F5; }

/* Reset Leaflet's divIcon box so our pin can overflow freely */
.pin-icon { background: none; border: 0; }

.pin {
  position: relative;
  width: 34px; height: 44px;
  cursor: pointer;
}

/* teardrop body */
.pin__body {
  position: absolute; left: 0; top: 0;
  width: 34px; height: 44px;
  filter: drop-shadow(0 3px 5px rgba(27,16,48,.35));
  transform-origin: 50% 100%;
  transition: transform .16s cubic-bezier(.34,1.56,.64,1);
}
.pin:hover .pin__body { transform: scale(1.16) translateY(-2px); }
.pin__body svg { display: block; width: 100%; height: 100%; }

.pin__num {
  position: absolute; top: 7px; left: 0; right: 0;
  text-align: center;
  font-size: 13px; font-weight: 800; color: #fff;
  pointer-events: none;
}

/* label beside the pin, like the reference poster */
.pin__label {
  position: absolute; top: 6px;
  font-size: 12px; font-weight: 800;
  color: var(--pink);
  white-space: nowrap;
  pointer-events: none;
  text-shadow:
     0 0 3px #fff,  0 0 3px #fff,  1px 1px 2px #fff, -1px -1px 2px #fff,
     1px -1px 2px #fff, -1px 1px 2px #fff;
  opacity: 0;
  transition: opacity .2s ease;
}
.pin__label--right { left: 38px; }
.pin__label--left  { right: 38px; }
/* labels only appear once you're zoomed in enough to read them */
.labels-on .pin__label { opacity: 1; }

.pin.is-selected .pin__body { transform: scale(1.22) translateY(-3px); }

/* ── Always-on blinking banner above a pin (data.js `banner`) ──────────── */
/* Sized like the festival landmark label so the two read as the same class
   of marker, but blinking and never zoom-gated — it shows at every zoom. */
.pin__banner {
  position: absolute;
  left: 50%; bottom: 52px;
  transform: translateX(-50%);
  background: linear-gradient(135deg, var(--purple), var(--pink));
  color: #fff;
  padding: 7px 13px;
  border-radius: 12px;
  border: 1.5px solid rgba(255,255,255,.9);
  white-space: nowrap;
  text-align: center;
  pointer-events: none;
  box-shadow: 0 6px 18px rgba(123,44,255,.45);
  animation: bannerBlink 1.1s steps(1, end) infinite;
}
/* little tail pointing down at the pin head */
.pin__banner::after {
  content: '';
  position: absolute;
  left: 50%; top: 100%;
  transform: translateX(-50%);
  border: 7px solid transparent;
  border-top-color: var(--pink);
}
.pin__banner-text {
  font-weight: 900; font-size: 13px; letter-spacing: .01em;
}
.pin__banner-dates {
  margin-top: 1px;
  font-weight: 700; font-size: 11px; letter-spacing: .05em;
  color: #FFD24A;
}
@keyframes bannerBlink {
  0%, 55%  { opacity: 1; }
  56%, 100% { opacity: .18; }
}
@media (prefers-reduced-motion: reduce) {
  .pin__banner { animation: none; }
}



/* ── Featured / paid: twinkle ──────────────────────────────────────────── */

.pin.is-featured .pin__label { color: var(--gold-deep); }

/* pulsing halo under the pin tip */
.pin.is-featured::before,
.pin.is-featured::after {
  content: "";
  position: absolute;
  left: 50%; bottom: -3px;
  width: 20px; height: 20px;
  margin-left: -10px;
  border-radius: 50%;
  border: 2px solid var(--gold);
  opacity: 0;
  animation: halo 2.6s cubic-bezier(.2,.6,.3,1) infinite;
  pointer-events: none;
}
.pin.is-featured::after { animation-delay: 1.3s; }

@keyframes halo {
  0%   { transform: scale(.4)  translateY(0); opacity: 0; }
  18%  { opacity: .85; }
  100% { transform: scale(2.6) translateY(0); opacity: 0; }
}

/* the pin itself breathes */
.pin.is-featured .pin__body { animation: bob 2.6s ease-in-out infinite; }
@keyframes bob {
  0%, 100% { transform: translateY(0)    scale(1); }
  46%      { transform: translateY(-4px) scale(1.06); }
}
.pin.is-featured:hover .pin__body { animation-play-state: paused; }

/* four-point sparkles orbiting the pin */
.spark {
  position: absolute;
  width: 10px; height: 10px;
  pointer-events: none;
  opacity: 0;
  animation: twinkle 2.2s ease-in-out infinite;
}
.spark svg { display: block; width: 100%; height: 100%; fill: #FFD24A; }
.spark--a { top: -5px;  left: -6px;  animation-delay: 0s;    }
.spark--b { top:  2px;  right: -8px; animation-delay: .55s; width: 8px; height: 8px; }
.spark--c { top: 20px;  left: -9px;  animation-delay: 1.1s; width: 7px; height: 7px; }
.spark--d { top: -8px;  right: 2px;  animation-delay: 1.6s; width: 9px; height: 9px; }

@keyframes twinkle {
  0%, 100% { opacity: 0;   transform: scale(.3) rotate(0deg); }
  40%      { opacity: 1;   transform: scale(1.15) rotate(45deg); }
  60%      { opacity: .9;  transform: scale(1) rotate(70deg); }
}

@media (prefers-reduced-motion: reduce) {
  .pin.is-featured::before,
  .pin.is-featured::after,
  .pin.is-featured .pin__body,
  .spark { animation: none; }
  .spark { opacity: .95; }
  .pin.is-featured::before { opacity: .5; transform: scale(1.6); }
}

/* ── Street label chips (cross streets) ────────────────────────────────── */

.xstreet-icon { background: none; border: 0; }
.xstreet {
  font-size: 10.5px; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(61,15,134,.82);
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
  /* right-anchored so the chip always sits clear to the west of the pins */
  transform: translate(-100%, -50%);
  box-shadow: var(--shadow-sm);
}

/* ── The blvd ribbon along Yonge ───────────────────────────────────────── */

.blvd-icon { background: none; border: 0; }
.blvd-tag {
  font-weight: 900; font-size: 11px; letter-spacing: .16em;
  color: #fff;
  background: linear-gradient(100deg, var(--purple), var(--pink));
  padding: 4px 12px;
  border-radius: 999px;
  white-space: nowrap;
  transform: translate(-50%, -50%) rotate(-90deg);
  box-shadow: 0 3px 12px rgba(123,44,255,.45);
  border: 1.5px solid rgba(255,255,255,.9);
}

/* ── Festival landmark ─────────────────────────────────────────────────── */

.event-icon { background: none; border: 0; }

/* The marker's own box is exactly the badge's box, so the Leaflet iconAnchor
   stays pinned to the badge regardless of label content. The label is
   absolutely positioned off the left edge — it bleeds leftward, away from
   the BTS Blvd ribbon/road running along the marker's right side, without
   ever shifting where the badge itself sits on the map. */
.event-marker {
  position: relative;
  width: 66px; height: 66px;
  cursor: pointer;
}

.event-badge {
  position: absolute;
  left: 0; top: 0;
  width: 60px; height: 60px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: linear-gradient(135deg, var(--red) 0%, var(--red) 48%, var(--blue) 52%, var(--blue) 100%);
  border: 3px solid #fff;
  box-shadow: 0 6px 20px rgba(0,0,0,.3);
  transition: transform .16s cubic-bezier(.34,1.56,.64,1);
}
.event-marker:hover .event-badge { transform: scale(1.08); }

.event-badge__emoji {
  font-size: 26px;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.35));
}

.event-badge__ring {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 2px solid #fff;
  opacity: 0;
  animation: eventPulse 2.8s ease-out infinite;
}
.event-badge__ring--2 { animation-delay: 1.4s; }
@keyframes eventPulse {
  0%   { transform: scale(1);    opacity: .8; }
  100% { transform: scale(1.55); opacity: 0; }
}

.event-label {
  position: absolute;
  right: 100%;
  top: 50%;
  transform: translateY(-50%);
  margin-right: 10px;
  background: rgba(27,16,48,.86);
  backdrop-filter: blur(3px);
  color: #fff;
  padding: 7px 13px;
  border-radius: 12px;
  white-space: nowrap;
  box-shadow: var(--shadow-md);
}
.event-label__name {
  font-weight: 800; font-size: 13px; letter-spacing: .01em;
}
.event-label__dates {
  margin-top: 1px;
  font-weight: 700; font-size: 11px; letter-spacing: .05em;
  color: #FFD24A;
}

.card--event .card__top {
  background: linear-gradient(135deg, var(--red), var(--blue));
}

@media (prefers-reduced-motion: reduce) {
  .event-badge__ring { animation: none; opacity: .5; }
}

/* ── Popup ─────────────────────────────────────────────────────────────── */

.leaflet-popup-content-wrapper {
  border-radius: var(--radius);
  padding: 0;
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  border: 1.5px solid var(--line);
}
.leaflet-popup-content { margin: 0; width: 268px !important; line-height: 1.45; }
.leaflet-popup-tip { box-shadow: var(--shadow-md); }
.leaflet-popup-close-button {
  width: 26px !important; height: 26px !important;
  font-size: 20px !important; color: #fff !important;
  padding: 2px 0 0 !important;
  opacity: .85;
  /* stays legible whether it's sitting on the purple header or a photo */
  text-shadow: 0 1px 4px rgba(0,0,0,.5);
}
.leaflet-popup-close-button:hover { opacity: 1; }

.card__photo {
  position: relative;
  height: 140px;
  background: var(--purple-soft);
}
.card__photo img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
}
.card__photoCredit {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 3px 10px;
  font-size: 9.5px; font-weight: 600; color: #fff;
  background: linear-gradient(transparent, rgba(0,0,0,.55));
}

.card__top {
  padding: 12px 14px 11px;
  background: linear-gradient(135deg, var(--purple), var(--purple-deep));
  color: #fff;
}
.card.is-featured .card__top {
  background: linear-gradient(135deg, #FFB300, #E06A00);
}
.card__cat {
  font-size: 10.5px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase;
  opacity: .92;
  display: flex; align-items: center; gap: 5px;
  padding-right: 24px; /* clear of Leaflet's close button */
}
.card__name {
  margin: 3px 0 0;
  font-size: 18px; font-weight: 800; line-height: 1.2;
  padding-right: 18px;
}

.card__body { padding: 11px 14px 12px; background: #fff; }
.card__blurb {
  margin: 0 0 8px; font-size: 12.5px; color: var(--ink-soft);
}
.card__row { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
.card__addr {
  margin: 0 0 10px;
  font-size: 11.5px; color: var(--ink-soft);
  display: flex; gap: 5px; align-items: flex-start;
}
.card__addr svg { width: 12px; height: 12px; flex: none; margin-top: 2px; fill: var(--pink); }

.card__links { display: flex; flex-wrap: wrap; gap: 6px; }
.lnk {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 10px;
  border-radius: 8px;
  border: 1.5px solid var(--line);
  background: var(--paper-2);
  color: var(--ink);
  font-size: 11.5px; font-weight: 700;
  text-decoration: none;
  transition: all .13s ease;
}
.lnk:hover { border-color: var(--purple); background: var(--purple-soft); color: var(--purple-deep); }
.lnk svg { width: 13px; height: 13px; }
.lnk--ig:hover { border-color: #C13584; background: #FCE9F4; color: #A02A6B; }
.lnk--ig svg { fill: #C13584; }
.lnk--map { border-color: #C9B6F5; }
.lnk--soon { opacity: .5; cursor: default; pointer-events: none; }

.card__note {
  margin: 9px 0 0; padding-top: 8px;
  border-top: 1px dashed var(--line);
  font-size: 10.5px; color: #9A8FB2;
}

/* ── Onboarding tip ────────────────────────────────────────────────────── */
/* First-visit hint pointing new users at the pins — pops in shortly after
   load, sits in the middle of the map, and stays there until the first
   touch anywhere on the screen. It never grabs the gesture itself
   (pointer-events stay off), so the tap that dismisses it still lands on
   the pin underneath. */

.onboardTip {
  position: absolute;
  top: 50%; left: 50%;
  z-index: 900;
  max-width: 240px;
  padding: 12px 18px;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font-size: 13px; font-weight: 700; line-height: 1.3; text-align: center;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(.85);
  transition: opacity .25s ease, transform .25s ease;
}
.onboardTip.is-visible {
  opacity: 1;
  animation: onboardPop .55s cubic-bezier(.34,1.56,.64,1) forwards;
}
.onboardTip.is-hidden {
  opacity: 0;
  transform: translate(-50%, -50%) scale(.9);
}
@keyframes onboardPop {
  0%   { transform: translate(-50%, -50%) scale(.4); opacity: 0; }
  55%  { transform: translate(-50%, -50%) scale(1.08); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}

/* ── Idle pin nudge ────────────────────────────────────────────────────── */
/* The tip above is a one-shot; this one comes back. It's anchored to a real
   pin (JS sets left/top from the marker's screen position), so it needs a
   tail pointing at it — `--nudge-arrow` carries how far the pin sits from
   the bubble's centre once the bubble has been clamped inside the map. */

.pinNudge {
  --nudge-arrow: 0px;
  position: absolute;
  left: 0; top: 0;
  z-index: 900;
  max-width: min(66vw, 250px);
  padding: 10px 15px;
  border-radius: 14px;
  background: var(--ink);
  color: #fff;
  font-size: 13px; font-weight: 700; line-height: 1.3; text-align: center;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  pointer-events: none;   /* the tap it asks for must reach the pin */
  transform: translate(-50%, -100%) scale(.9);
  transform-origin: calc(50% + var(--nudge-arrow)) 100%;
  transition: opacity .22s ease, transform .22s ease;
}
/* tail */
.pinNudge::after {
  content: "";
  position: absolute;
  left: calc(50% + var(--nudge-arrow));
  top: 100%;
  margin-left: -7px;
  border: 7px solid transparent;
  border-top-color: var(--ink);
}
.pinNudge.is-visible {
  opacity: 1;
  transform: translate(-50%, -100%) scale(1);
  animation: nudgeBob 1.9s ease-in-out .3s infinite;
}
/* pin too close to the top edge — flip the bubble under it */
.pinNudge.is-below {
  transform: translate(-50%, 0) scale(.9);
  transform-origin: calc(50% + var(--nudge-arrow)) 0;
}
.pinNudge.is-below.is-visible { transform: translate(-50%, 0) scale(1); }
.pinNudge.is-below::after {
  top: auto; bottom: 100%;
  border-top-color: transparent;
  border-bottom-color: var(--ink);
}
@keyframes nudgeBob {
  0%, 100% { transform: translate(-50%, -100%) scale(1); }
  50%      { transform: translate(-50%, calc(-100% - 5px)) scale(1); }
}
.pinNudge.is-below.is-visible { animation-name: nudgeBobBelow; }
@keyframes nudgeBobBelow {
  0%, 100% { transform: translate(-50%, 0) scale(1); }
  50%      { transform: translate(-50%, 5px) scale(1); }
}

/* the pin being pointed at hops so the eye finds it */
.pin.is-nudged .pin__body {
  animation: nudgeHop .9s cubic-bezier(.34,1.56,.64,1) infinite;
}
@keyframes nudgeHop {
  0%, 60%, 100% { transform: translateY(0) scale(1); }
  30%           { transform: translateY(-7px) scale(1.14); }
}

@media (prefers-reduced-motion: reduce) {
  .pinNudge.is-visible,
  .pinNudge.is-below.is-visible { animation: none; }
  .pin.is-nudged .pin__body { animation: none; transform: scale(1.14); }
}

/* ── Legend & FAB ──────────────────────────────────────────────────────── */

.legend {
  position: absolute; left: 14px; bottom: 26px;
  z-index: 450;
  background: rgba(255,255,255,.94);
  backdrop-filter: blur(6px);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 9px 12px;
  box-shadow: var(--shadow-md);
  font-size: 11.5px; font-weight: 600; color: var(--ink-soft);
}
.legend__row { display: flex; align-items: center; gap: 8px; }
.legend__row + .legend__row { margin-top: 6px; }
.legend__pin {
  width: 12px; height: 12px; border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  flex: none;
}
.legend__pin--std { background: var(--pink); }
.legend__pin--fx  {
  background: linear-gradient(150deg, #FFD24A, var(--gold-deep));
  box-shadow: 0 0 0 3px rgba(255,179,0,.25);
  animation: legendPulse 2.6s ease-in-out infinite;
}
@keyframes legendPulse {
  0%,100% { box-shadow: 0 0 0 2px rgba(255,179,0,.18); }
  50%     { box-shadow: 0 0 0 5px rgba(255,179,0,.32); }
}

.legend__divider { height: 1px; margin: 7px 0; background: var(--line); }
.legend__line { width: 16px; height: 3px; border-radius: 2px; flex: none; }
.legend__line--blvd  { background: linear-gradient(90deg, var(--purple), var(--pink)); }

.fab {
  display: none;
  position: absolute; right: 14px; bottom: 22px;
  z-index: 1200; /* stays tappable on top of the open sheet */
  border: 0; border-radius: 999px;
  padding: 12px 20px;
  background: var(--purple);
  color: #fff;
  font: inherit; font-size: 14px; font-weight: 700;
  box-shadow: var(--shadow-md);
  cursor: pointer;
}
.fab__map { display: none; }

/* ── Mobile detail overlay ─────────────────────────────────────────────── */
/* Lives outside #map on purpose — Leaflet pans the map pane with its own
   CSS transform, which would hijack `position: fixed` centering if this
   sat inside it. */

.detailModal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 2100; /* above the sheet (1100) and FAB (1200) */
  align-items: center;
  justify-content: center;
  padding: 24px;
  padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
}
body.has-vh .detailModal__box { max-height: calc(var(--app-h) * .82); }
.detailModal.is-open { display: flex; }

.detailModal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(27,16,48,.5);
  backdrop-filter: blur(2px);
}

.detailModal__box {
  position: relative;
  width: 100%;
  max-width: 320px;
  max-height: 82vh;
  max-height: 82dvh;
  overflow-y: auto;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  background: var(--paper);
}

.detailModal__close {
  position: absolute;
  top: 8px; right: 8px;
  z-index: 1;
  width: 28px; height: 28px;
  border: 0; border-radius: 50%;
  background: rgba(0,0,0,.35);
  color: #fff;
  font-size: 15px; line-height: 1;
  cursor: pointer;
  display: grid; place-items: center;
}

/* ── Responsive ────────────────────────────────────────────────────────── */

@media (max-width: 820px) {
  .app { grid-template-columns: 1fr; }

  /* The panel becomes a transparent overlay: the header keeps its place at the
     top of the screen, and only the sheet below it moves. */
  .panel {
    grid-column: 1; grid-row: 1;
    position: absolute; inset: 0;
    background: transparent;
    border-right: 0;
    box-shadow: none;
    pointer-events: none;
  }
  .mapwrap { grid-column: 1; grid-row: 1; }

  .brand {
    pointer-events: auto;
    padding: max(14px, env(safe-area-inset-top)) 18px 14px;
    border-radius: 0 0 20px 20px;
    box-shadow: 0 8px 26px rgba(27,16,48,.28);
    max-height: 240px;
    transition: max-height .32s cubic-bezier(.4,0,.2,1),
                padding .32s cubic-bezier(.4,0,.2,1),
                opacity .24s ease, transform .32s cubic-bezier(.4,0,.2,1),
                box-shadow .32s ease;
  }
  body.brand-hidden .brand {
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
    opacity: 0;
    transform: translateY(-16px);
    box-shadow: none;
    pointer-events: none;
  }
  .brand__bts, .brand__blvd { font-size: 34px; }
  .brand__tagline { margin-top: 7px; font-size: 15px; }
  .brand__dates { margin-top: 9px; padding: 4px 10px; font-size: 11px; }

  .sheet {
    pointer-events: auto;
    border-radius: 20px 20px 0 0;
    box-shadow: 0 -10px 40px rgba(27,16,48,.26);
    transform: translateY(102%);
    transition: transform .28s cubic-bezier(.4,0,.2,1);
  }
  body.panel-open .sheet { transform: translateY(0); }

  .controls { border-radius: 20px 20px 0 0; }
  /* keep the last listing clear of the floating "Map" button */
  .listwrap { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }

  /* lift the button and the legend above any home-indicator / gesture bar */
  .fab { display: block; bottom: calc(22px + env(safe-area-inset-bottom, 0px)); }
  body.panel-open .fab { background: var(--ink); }
  body.panel-open .fab__list { display: none; }
  body.panel-open .fab__map  { display: inline; }

  .legend {
    bottom: calc(22px + env(safe-area-inset-bottom, 0px));
    left: 12px; font-size: 11px; padding: 8px 10px;
  }
  .onboardTip { max-width: min(72vw, 260px); }
}

/* Leaflet chrome tuned to the theme */
.leaflet-control-zoom a {
  border-radius: 9px !important;
  color: var(--purple-deep) !important;
  font-weight: 700;
}
.leaflet-bar { border: 1px solid var(--line) !important; box-shadow: var(--shadow-sm) !important; }
.leaflet-control-attribution {
  font-size: 10px !important;
  background: rgba(255,255,255,.82) !important;
}
