/* ============================================================
   base.css — near-universal rules extracted from inline <style>
   blocks + curated accessibility overrides.

   Every HTML file still has its original inline <style> block
   as a complete byte-for-byte fallback. This file is loaded
   AFTER the inline <style>, so its rules override on browsers
   that successfully fetch it (equal specificity, later cascade
   origin). If this file ever 404s, the inline fallback kicks
   in and nothing visually breaks (except for the a11y
   overrides at the bottom — those are live-only).

   Do NOT edit by hand. Run:
     python3 scripts/build-base-css.py
   ============================================================ */

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

.nav-hamburger { display: none; }

.nav-hamburger:focus-visible span { background: var(--gold); }

.nav-mobile { display: none; }

.nav-search-icon { position: absolute; left: 0.7rem; top: 50%; transform: translateY(-50%); font-size: 0.75rem; color: rgba(255,255,255,0.3); pointer-events: none; }

.nav-search-input { width: 100%; padding: 0.45rem 0.8rem 0.45rem 2rem; border-radius: 20px; border: 1px solid rgba(255,255,255,0.12); background: rgba(255,255,255,0.06); color: var(--white); font-family: var(--sans); font-size: 0.78rem; outline: none; transition: all 0.2s; }

.nav-search-input::placeholder { color: rgba(255,255,255,0.3); }

.nav-search-input:focus { border-color: var(--gold); background: rgba(255,255,255,0.1); }

.skip-link:focus { top: 0; outline: 2px solid var(--gold); outline-offset: 2px; }

/* Accessibility — skip link and focus-visible affordances */ .skip-link { position: absolute; top: -100px; left: 0; background: var(--ink); color: var(--gold); padding: 0.8rem 1.2rem; z-index: 300; font-size: 0.85rem; font-weight: 500; text-decoration: none; border-radius: 0 0 4px 0; }

/* Search bar in nav */ .nav-search { position: relative; flex: 1; max-width: 260px; margin: 0 1rem; }

:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

@media (max-width: 768px) { .nav-search { display: none; } }

/* ============================================================
   FADE-IN SAFETY NET
   Every page uses `.fade-in { opacity: 0 }` + IntersectionObserver
   to progressively reveal content as it scrolls into view. But if
   ANY JS error happens before the observer runs (CSP block, typo,
   network issue), the observer never runs and every .fade-in
   element stays hidden forever — the entire page appears blank.
   This CSS animation kicks in after 1.5s and reveals the content
   even if no JS executes. The observer's .visible class cancels
   this animation immediately if the JS path works.
   ============================================================ */
.fade-in {
  animation: fade-in-fallback 0.6s ease 1.5s forwards;
}
.fade-in.visible {
  animation: none;
}
@keyframes fade-in-fallback {
  to { opacity: 1; transform: none; }
}

/* ============================================================
   Accessibility / WCAG AA overrides
   These rules are NOT in the extracted near-universal set but
   are curated here to enforce minimum contrast ratios (4.5:1
   for normal text) on top of whatever inline CSS exists.
   ============================================================ */

/* Inline body text links use --gold-dark (4.88:1 on cream)
   instead of --gold (2.01:1 on cream, fails AA). Decorative gold
   is preserved for nav/logo/buttons via the overrides below. */
a { color: var(--gold-dark); }
a:hover { color: var(--gold-dark); text-decoration: underline; }

/* Decorative gold accents — preserve the bright brand color on
   dark backgrounds where contrast is fine (ink header/footer).
   These are the elements you WANT to look gold even though their
   raw color fails AA on cream. */
.nav-logo, .nav-logo:hover,
.nav-mobile a,
.skip-link {
  color: var(--gold);
}
.nav-logo span {
  color: var(--white);
}

/* Nav links on dark bg — increase alpha from 0.7 to 0.85 for
   better contrast (7.0:1 → 10.8:1 on ink). */
.nav-links a {
  color: rgba(255, 255, 255, 0.85);
}
.nav-links a:hover,
.nav-links a[aria-current="page"] {
  color: var(--gold);
}
.nav-back {
  color: rgba(255, 255, 255, 0.75);
}
.nav-back:hover {
  color: var(--gold);
}

/* Footer contrast boost — raise alphas from 0.4/0.25 (failing) to
   0.65/0.65 (passing). Footer links stay muted-white, not gold,
   so they don't fail on #110f0d. */
footer {
  color: rgba(255, 255, 255, 0.65) !important;
}
.footer-links a {
  color: rgba(255, 255, 255, 0.65);
}
.footer-links a:hover {
  color: var(--gold);
}

/* Breadcrumb contrast — current page in --ink for max contrast,
   links in --slate (8.26:1). */
.breadcrumbs a { color: var(--slate); }
.breadcrumbs a:hover { color: var(--gold-dark); }
.breadcrumbs .current { color: var(--ink); }

/* ============================================================
   Map popup styles — shared across homepage + district pages.
   District pages used to open the full Instagram store modal on
   every map-pin click, which blocked the map and felt heavy. We
   now use Leaflet's native bindPopup with a compact dark card
   (same pattern as homepage map) so the popup floats next to the
   pin instead of obscuring the map. "View details" button inside
   still opens the full store modal for users who want the
   Instagram embed + longer description.
   ============================================================ */
.leaflet-popup-content-wrapper {
  background: var(--ink) !important;
  border: 1px solid var(--gold) !important;
  border-radius: 10px !important;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5) !important;
  color: var(--white) !important;
  font-family: var(--sans) !important;
  padding: 0 !important;
}
.leaflet-popup-tip { background: var(--gold) !important; }
.leaflet-popup-close-button {
  color: var(--gold) !important;
  font-size: 18px !important;
  padding: 6px 8px !important;
}
.leaflet-popup-content { margin: 0 !important; }

.map-popup {
  padding: 1rem 1.2rem 1rem;
  min-width: 200px;
  max-width: 260px;
}
.map-popup-tag {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--gold);
  font-weight: 600;
  margin-bottom: 0.3rem;
}
.map-popup-name {
  font-family: var(--serif);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--white);
  margin-bottom: 0.4rem;
  line-height: 1.2;
}
.map-popup-desc {
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.72);
  line-height: 1.5;
  margin-bottom: 0.7rem;
}
.map-popup-meta {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.7rem;
  color: rgba(255, 255, 255, 0.55);
  margin-bottom: 0.8rem;
}
.map-popup-actions {
  display: flex;
  gap: 0.5rem;
}
.map-popup-btn {
  flex: 1;
  font-size: 0.7rem;
  padding: 0.45rem 0.6rem;
  border-radius: 6px;
  font-family: var(--sans);
  cursor: pointer;
  font-weight: 600;
  text-align: center;
  transition: all 0.2s;
  border: none;
  text-decoration: none !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.map-popup-btn.primary {
  background: var(--gold);
  color: var(--ink) !important;
}
.map-popup-btn.primary:hover { background: var(--gold-lt, #e8c96b); }
.map-popup-btn.secondary {
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.9) !important;
  border: 1px solid rgba(255, 255, 255, 0.15);
}
.map-popup-btn.secondary:hover { background: rgba(255, 255, 255, 0.14); }

/* ============================================================
   Hotel carousel — shares all markup + styling with the existing
   .restaurant-carousel. We just need the wrapper margin and the
   blue .rest-btn.book variant for the "Book" affiliate button.
   See scripts/build-hotels.py for the data + injection logic.
   ============================================================ */
.hotel-carousel { margin-bottom: 3rem; overflow: hidden; }
.rest-btn.book {
  background: #1c4a7e;
  color: #fff !important;
  text-decoration: none !important;
}
.rest-btn.book:hover { background: #173e69; }

/* ============================================================
   Drag-to-scroll for horizontal carousels.
   Adds click-and-drag on desktop (touch devices already get
   native swipe). The .dragging class disables scroll-snap while
   dragging so the carousel doesn't fight the user's finger.
   ============================================================ */
.carousel-scroll,
.iconic-carousel,
.michelin-carousel { cursor: grab; }
.carousel-scroll.dragging,
.iconic-carousel.dragging,
.michelin-carousel.dragging { cursor: grabbing; scroll-snap-type: none; user-select: none; }

/* ============================================================
   Mobile responsiveness fixes — touch targets, carousel cards,
   grids, and modal padding for phones ≤480px.
   ============================================================ */
@media (max-width: 600px) {
  .rest-btn, .store-btn, .rest-card-actions a,
  .michelin-card-btn, .iconic-card-btn {
    padding: 0.55rem 0.85rem;
    font-size: 0.72rem;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .store-filter, .guide-filter-btn, .eat-filter-btn {
    padding: 0.55rem 1rem;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .rest-card { flex: 0 0 calc(100vw - 3rem); }
  .michelin-card { flex: 0 0 calc(100vw - 3rem); }
  .iconic-card { flex: 0 0 calc(100vw - 3rem); }
  .stores-grid { grid-template-columns: 1fr; }
  .guides-grid { grid-template-columns: 1fr; }
  .restaurant-grid { grid-template-columns: 1fr; }
  .district-nav-grid { grid-template-columns: repeat(2, 1fr); }
  .store-modal { padding: 0.75rem; }
  .modal-content { gap: 1rem; }
  .footer-links { gap: 1rem; }
}

/* ============================================================
   MICHELIN Key badge — shown on hotel cards for hotels in the
   MICHELIN Key guide. 1-Key = dark pill with gold text. 2-Key
   = inverted (gold pill, dark text) to signal elevated status.
   See CLONING.md "Hotel curation policy" for the rule.
   ============================================================ */
/* ============================================================
   Coffee & Drinks section — small card grid between the hotel
   carousel and the guide prose. See scripts/build-coffee-bars.py.
   ============================================================ */
.coffee-bars-section { margin-bottom: 3rem; }
.cb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1rem;
}
.cb-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem 1.1rem;
  display: flex;
  gap: 0.8rem;
  transition: all 0.22s;
}
.cb-card:hover {
  border-color: var(--gold);
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.06);
}
.cb-icon { font-size: 1.4rem; flex-shrink: 0; line-height: 1; padding-top: 0.1rem; }
.cb-info { flex: 1; min-width: 0; }
.cb-name { font-family: var(--serif); font-size: 0.95rem; font-weight: 700; margin-bottom: 0.1rem; }
.cb-type { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--rust); font-weight: 600; margin-bottom: 0.35rem; }
.cb-desc { font-size: 0.78rem; color: var(--muted); line-height: 1.5; margin-bottom: 0.4rem; }
.cb-meta { font-size: 0.7rem; color: var(--muted); margin-bottom: 0.5rem; }
.cb-actions { display: flex; gap: 0.4rem; }
.cb-btn {
  font-size: 0.65rem;
  font-family: var(--sans);
  font-weight: 600;
  padding: 0.3rem 0.6rem;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--slate);
  text-decoration: none;
  transition: all 0.2s;
}
.cb-btn:hover { border-color: var(--gold); color: var(--ink); }

.mkey-badge {
  display: inline-block;
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.22rem 0.55rem;
  border-radius: 12px;
  background: #1a1a1a;
  color: var(--gold);
  margin-bottom: 0.5rem;
  line-height: 1.2;
}
.mkey-badge.two {
  background: var(--gold);
  color: #1a1a1a;
}

/* ============================================================
   Inline guide components — photos, pull-quotes, editor mentions.
   Used inside <div class="guide-prose"> to break up long-form
   editorial content and make guides visually dynamic.
   ============================================================ */
.inline-image {
  margin: 2rem 0;
  border-radius: 10px;
  overflow: hidden;
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--warm);
}
/* ============================================================
   Instagram embed trim — clips the bottom chrome (likes, comments,
   "View more on Instagram", action bar) from every IG embed
   site-wide. Works across all container types:
     .inline-image      — guide pages
     .featured-shop-embed — Michelin guide
     .modal-instagram   — district store modals
   ============================================================ */
.inline-image:has(.instagram-media),
.modal-instagram,
.featured-shop-embed {
  overflow: hidden;
}
.inline-image:has(.instagram-media) {
  aspect-ratio: auto;
  background: none;
  border-radius: 10px;
}
.inline-image .instagram-media,
.inline-image iframe,
.modal-instagram .instagram-media,
.modal-instagram iframe,
.featured-shop-embed .instagram-media,
.featured-shop-embed iframe {
  margin-bottom: -140px !important;
}
.inline-image .instagram-media {
  margin: 0 auto !important;
  width: 100% !important;
  max-width: 540px !important;
  min-width: 0 !important;
}
.inline-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.inline-image-caption {
  font-size: 0.72rem;
  color: var(--muted);
  margin-top: 0.5rem;
  text-align: center;
  line-height: 1.4;
}
.inline-image-caption a {
  color: var(--gold-dark);
  border-bottom: none !important;
}

.pull-quote {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  font-weight: 500;
  font-style: italic;
  line-height: 1.35;
  color: var(--ink);
  border-left: 4px solid var(--gold);
  padding: 0.5rem 0 0.5rem 1.4rem;
  margin: 2rem 0;
  max-width: 640px;
}

.editor-mention {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.2rem 1.4rem;
  margin: 1.2rem 0;
  transition: all 0.22s;
}
.editor-mention:hover {
  border-color: var(--gold);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.05);
}
.editor-mention-label {
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--rust);
  font-weight: 700;
  margin-bottom: 0.35rem;
}
.editor-mention-name {
  font-family: var(--serif);
  font-size: 1.05rem;
  line-height: 1.3;
  margin-bottom: 0.5rem;
}
.editor-mention p {
  font-size: 0.88rem;
  color: var(--slate);
  line-height: 1.6;
  margin: 0;
}

/* ============================================================
   DESIGN SYSTEM — unified card styling, section rhythm, mobile
   nav upgrade, and loading skeletons. Applied site-wide via
   base.css to ensure visual consistency across all pages.
   ============================================================ */

/* 1. Unified card treatment — normalize border-radius, bg, shadow,
   and hover across ALL card types so every page feels cohesive. */
.guide-card, .restaurant-card, .store-card, .stay-card,
.rest-card, .district-card, .news-post {
  border-radius: 10px !important;
  border: 1px solid var(--border) !important;
  transition: all 0.25s ease !important;
}
.guide-card:hover, .restaurant-card:hover, .store-card:hover,
.stay-card:hover, .rest-card:hover, .district-card:hover,
.news-post:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 36px rgba(26,23,20,0.1);
}

/* 2. Section rhythm — consistent vertical spacing between major
   page sections. Prevents cramped-then-spacious feeling. */
section, .district-section, .guide-section,
.newsletter-section, .district-nav-section {
  margin-bottom: clamp(2rem, 5vw, 4rem);
}
section + section { padding-top: clamp(1.5rem, 4vw, 3rem); }

/* 3. Section dividers — subtle gold line between homepage sections */
.section-inner + .section-inner::before,
section + section::before {
  content: '';
  display: block;
  width: 60px;
  height: 1px;
  background: var(--gold);
  margin: 0 auto clamp(2rem, 4vw, 3rem);
  opacity: 0.3;
}

/* 4. Mobile nav upgrade — slide-in drawer from right instead of
   full-screen overlay. Gold accent border, backdrop blur. */
@media (max-width: 600px) {
  .nav-mobile {
    display: none;
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: 280px;
    background: rgba(26,23,20,0.98);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    z-index: 150;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    padding: 5rem 2rem 2rem;
    gap: 1.5rem;
    border-left: 2px solid var(--gold);
    transform: translateX(100%);
    transition: transform 0.3s ease;
    inset: auto;
  }
  .nav-mobile.open {
    display: flex;
    transform: translateX(0);
  }
  .nav-mobile a {
    font-family: var(--serif);
    font-size: 1.3rem;
    color: var(--white);
    transition: color 0.2s;
    padding: 0.3rem 0;
    border-bottom: 1px solid rgba(255,255,255,0.06);
    width: 100%;
  }
  .nav-mobile a:hover, .nav-mobile a[aria-current="page"] { color: var(--gold); }
  .nav-mobile-close {
    position: absolute; top: 1.2rem; right: 1.2rem;
    font-size: 1.5rem; color: rgba(255,255,255,0.6);
    cursor: pointer; background: none; border: none;
  }
}

/* 5. Loading skeletons — shimmer placeholder for IG embeds and
   images while they load. Applied via CSS animation. */
.inline-image::before,
.featured-shop-embed::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    var(--warm) 25%,
    rgba(255,255,255,0.4) 50%,
    var(--warm) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite linear;
  z-index: 0;
  border-radius: inherit;
}
.inline-image img, .inline-image iframe,
.inline-image .instagram-media,
.featured-shop-embed iframe,
.featured-shop-embed .instagram-media {
  position: relative;
  z-index: 1;
}
@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* 6. Emoji removal cleanup — hide empty icon spans, add CSS search icon */
.district-nav-icon:empty { display: none; }
.nav-search-icon:empty::before { content: '5'; }
.breadcrumbs { display: none !important; }

/* Typography contrast — editorial feel via serif weight + kerning */
h1, h2, .section-title, .district-name, .guide-title,
.featured-guide-title, .news-post-headline, .store-name {
  letter-spacing: -0.02em;
}
h1 em, h2 em, .section-title em {
  font-weight: 400;
  font-style: italic;
}
.section-label, .hero-eyebrow, .districts-hero-eyebrow,
.guides-hero-eyebrow, .map-hero-eyebrow, .news-hero-eyebrow {
  letter-spacing: 0.2em !important;
  font-weight: 500 !important;
}

/* Featured store cards — editorial callout with photo + blurb */
.store-card.featured-store {
  grid-column: span 2 !important;
  border-left: 4px solid var(--gold) !important;
  background: var(--card-bg) !important;
  position: relative;
  padding: 0 !important;
  display: grid !important;
  grid-template-columns: 200px 1fr;
  gap: 0;
}
.store-card.featured-store .store-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 0;
}
.store-card.featured-store .store-photo-wrap {
  overflow: hidden;
  background: linear-gradient(135deg, var(--warm) 0%, var(--gold) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 180px;
}
.store-card.featured-store .store-photo-wrap .placeholder-text {
  font-family: var(--serif);
  font-size: 0.9rem;
  font-style: italic;
  color: var(--ink);
  opacity: 0.5;
  text-align: center;
  padding: 1rem;
}
.store-card.featured-store .store-content {
  padding: 1.4rem 1.6rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.store-card.featured-store .store-pick-badge {
  font-size: 0.55rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--gold);
  margin-bottom: 0.4rem;
}
.store-card.featured-store .store-name {
  font-size: 1.15rem !important;
}
.store-card.featured-store .store-editorial {
  font-size: 0.82rem;
  font-style: italic;
  color: var(--slate);
  line-height: 1.5;
  margin-top: 0.5rem;
  border-top: 1px solid var(--border);
  padding-top: 0.5rem;
}
@media (max-width: 600px) {
  .store-card.featured-store {
    grid-column: span 1 !important;
    grid-template-columns: 1fr !important;
  }
  .store-card.featured-store .store-photo-wrap { min-height: 140px; }
}

/* 7. Photo hover zoom — subtle scale on card photos across all types */
.guide-photo, .district-photo, .stay-card-poster,
.featured-guide-photo-img {
  transition: transform 0.6s ease !important;
}
.guide-card:hover .guide-photo,
.district-card:hover .district-photo,
.stay-card:hover .stay-card-poster,
.featured-guide:hover .featured-guide-photo-img {
  transform: scale(1.04) !important;
}

/* 7. Button polish — consistent pill radius + subtle lift on all CTA buttons */
.btn-primary, .btn-secondary, .rest-btn, .store-btn,
.featured-shop-btn, .stay-btn, .comment-submit {
  border-radius: 8px !important;
  transition: all 0.2s ease !important;
}
.btn-primary:hover, .rest-btn.primary:hover,
.featured-shop-btn.primary:hover, .stay-btn.primary:hover,
.comment-submit:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}

/* 8. Smooth scroll offset — prevent sticky nav from covering
   anchor targets when clicking internal links */
[id] { scroll-margin-top: 80px; }

/* 9. Image loading polish — prevent layout shift with aspect-ratio
   hints on card photos before they load */
.guide-photo, .district-photo {
  aspect-ratio: 5 / 2;
  background: var(--warm);
}

/* ═══════════════════════════════════════════════════════════════════
   SHARED MAP SYSTEM
   Used by the homepage map, /map.html, and every district page.
   Lives here so every page stays visually consistent — the pill, POI,
   and store-pin styles are a single source of truth.
   ═══════════════════════════════════════════════════════════════════ */

/* Named pill markers (districts, hotels, restaurants on the city map).
   Positioned via Leaflet at a 1×1 iconAnchor, visually centered through
   translate(-50%, -50%) on the inner element. */
.map-pin-leaflet { background: transparent !important; border: 0 !important; }
.map-pin-outer { position: relative; width: 0; height: 0; }
.map-pin {
  position: absolute; top: 0; left: 0;
  transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px 5px 9px;
  background: rgba(26,23,20,0.94);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 16px;
  font-family: var(--sans);
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
  white-space: nowrap;
  box-shadow: 0 3px 12px rgba(0,0,0,0.45);
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
}
.map-pin:hover {
  transform: translate(-50%, -50%) translateY(-1px);
  box-shadow: 0 6px 18px rgba(0,0,0,0.55);
  border-color: rgba(201,168,76,0.6);
  z-index: 500;
}
.map-pin-dot {
  width: 7px; height: 7px; border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.14);
}
.map-pin-label { line-height: 1; }
.map-pin-count {
  font-size: 9.5px; color: rgba(255,255,255,0.5);
  font-weight: 500; letter-spacing: 0.02em;
  border-left: 1px solid rgba(255,255,255,0.12);
  margin-left: 2px; padding-left: 6px;
}
.map-pin-featured {
  border-color: #c9a84c;
  box-shadow: 0 0 0 2px rgba(201,168,76,0.16), 0 4px 18px rgba(0,0,0,0.5);
}
.map-pin-ribbon {
  font-size: 8.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: #1a1714; background: #c9a84c;
  padding: 2px 6px; border-radius: 8px; font-weight: 700;
  margin-left: 2px;
}
.map-pin-in-route {
  background: #b5451b; border-color: #b5451b; color: #fff;
}
.map-pin-in-route .map-pin-dot {
  box-shadow: 0 0 0 2px rgba(255,255,255,0.3);
}

/* POI anchors — custom hand-crafted SVG illustrations on parchment
   circles. Used on the city map AND (optionally) on district pages. */
.map-poi {
  position: absolute; top: 0; left: 0;
  transform: translate(-50%, -50%);
  width: 38px; height: 38px;
  border-radius: 50%;
  background: #f5ecd8;
  border: 1.5px solid rgba(26,23,20,0.55);
  display: flex; align-items: center; justify-content: center;
  color: var(--ink);
  box-shadow: 0 2px 6px rgba(0,0,0,0.25);
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.map-poi:hover {
  transform: translate(-50%, -50%) scale(1.08);
  background: #fff;
  border-color: var(--gold);
  box-shadow: 0 5px 16px rgba(0,0,0,0.35);
}
.map-poi.map-poi-in-route {
  background: #b5451b;
  border-color: #b5451b;
  color: #fff;
}
.map-poi-icon { display: inline-flex; line-height: 0; }
.map-poi-icon svg { width: 22px; height: 22px; display: block; }
.map-poi-label {
  position: absolute;
  bottom: calc(100% + 6px); left: 50%;
  transform: translateX(-50%);
  background: rgba(26,23,20,0.95);
  color: #fff;
  font-family: var(--sans);
  font-size: 10px; font-weight: 500; letter-spacing: 0.03em;
  padding: 3px 8px;
  border-radius: 8px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
}
.map-poi:hover .map-poi-label { opacity: 1; }

/* District-page store pins — small refined dots in the site palette.
   Cream parchment outer ring with a category-colored inner dot. Replaces
   the generic 14px colored-circle pins that used to look templated. */
.store-pin {
  position: absolute; top: 0; left: 0;
  transform: translate(-50%, -50%);
  width: 18px; height: 18px;
  border-radius: 50%;
  background: #f5ecd8;
  border: 1.5px solid rgba(26,23,20,0.6);
  box-shadow: 0 2px 5px rgba(0,0,0,0.35);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.store-pin-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: currentColor;
}
.store-pin:hover {
  transform: translate(-50%, -50%) scale(1.25);
  border-color: var(--gold);
  box-shadow: 0 4px 10px rgba(0,0,0,0.45);
  z-index: 400;
}
.store-pin-featured {
  border-color: var(--gold);
  box-shadow: 0 0 0 2px rgba(201,168,76,0.25), 0 3px 8px rgba(0,0,0,0.4);
}
