:root {
  /* Palette — "Quiet Luxury" (Monocle-inspired): warm bone base, soft warm-black,
     deep indigo accent. Per CLAUDE.md the base is never pure white, the text
     never pure black. */
  --bg: #FEFDFB;
  --header-bg: #2D2A26;
  --primary: #3D4A5C;
  --primary-hover: #2D3848;
  --primary-light: #5C6B7E;
  --accent: #3D4A5C;
  --text: #2D2A26;
  --text-secondary: #5C5550;
  --text-muted: #78716C;
  --border: #ECE9E4;
  --border-light: #F3F1ED;
  --shadow: 0 4px 6px rgba(45,42,38,0.08);
  --shadow-elevated: 0 12px 16px -4px rgba(45,42,38,0.10);
  --radius-card: 16px;
  --radius-pill: 9999px;
  --radius-btn: 8px;
  /* Type roles. Display = UI / headlines. Body = long-form prose only. */
  --font-display: 'Familjen Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-body: 'EB Garamond', Georgia, 'Times New Roman', serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
body {
  font-family: var(--font-display);
  height: 100dvh; overflow: hidden;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  touch-action: manipulation;
}

/* ── Header ── */
.header {
  min-height: 56px; display: flex; align-items: center; gap: 16px;
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: 0;
  padding-left: max(20px, env(safe-area-inset-left));
  padding-right: max(20px, env(safe-area-inset-right));
  background: var(--header-bg); color: #fff;
  z-index: 1000; position: relative;
}
.header .logo {
  font-family: var(--font-display); font-size: 18px; font-weight: 600;
  white-space: nowrap; letter-spacing: -0.3px;
  display: flex; align-items: center; gap: 6px;
}
.header .logo span { color: var(--primary-light); }
.destination-select {
  font-family: var(--font-display); font-size: 18px; font-weight: 600;
  color: #fff; background: transparent; border: none; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  padding: 4px 22px 4px 0; letter-spacing: -0.3px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2360a5fa' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right center;
}
.destination-select:focus { outline: none; }
.destination-select option {
  background: var(--header-bg); color: #fff; font-size: 15px;
}
.header-right { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.blog-link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 16px; border-radius: var(--radius-pill);
  background: rgba(255,255,255,0.1); color: #fff;
  font-size: 13px; font-weight: 500; text-decoration: none;
  transition: background 0.15s;
  min-height: 44px;
}
.blog-link:hover { background: rgba(255,255,255,0.18); }
.spot-count { font-size: 13px; color: rgba(255,255,255,0.5); white-space: nowrap; }

/* ── Main layout ── */
.main { display: flex; height: calc(100dvh - 56px - env(safe-area-inset-top, 0px)); }

/* ── Sidebar ── */
.sidebar {
  width: 380px; min-width: 380px; background: var(--bg);
  display: flex; flex-direction: column;
  border-right: 1px solid var(--border); z-index: 500;
  -webkit-overflow-scrolling: touch;
}
.filters { padding: 16px; border-bottom: 1px solid var(--border); }
.filter-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--text-muted); margin-bottom: 8px;
}
.category-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 600; font-family: inherit;
  cursor: pointer; border: 1px solid var(--border);
  background: var(--bg); color: var(--text-secondary);
  transition: all 0.15s; user-select: none;
  min-height: 44px;
}
.chip .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-right: 2px; position: static; }
.chip.active { border: 2.5px solid var(--cat-color); color: var(--cat-color); }
.chip:not(.active):hover { border-color: #d1d5db; }
.chip.active:hover { opacity: 0.85; }
.chip:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.city-select {
  width: 100%; padding: 10px 12px; border: 1.5px solid var(--border);
  border-radius: var(--radius-btn); font-size: 13px;
  font-family: inherit; background: var(--bg); color: var(--text);
  cursor: pointer; min-height: 44px;
}
.sort-distance-btn {
  width: 100%; margin: 8px 0 4px; padding: 9px 12px;
  border: 1.5px solid var(--border); border-radius: var(--radius-btn);
  background: transparent; color: var(--text-muted);
  font-size: 13px; font-family: inherit; cursor: pointer;
  transition: all 0.2s; text-align: center; min-height: 44px;
}
.sort-distance-btn.active {
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.sort-distance-btn:hover:not(.active) {
  border-color: var(--text-muted); color: var(--text);
}
.search-wrap { position: relative; margin-bottom: 12px; }

.spot-search {
  width: 100%; padding: 10px 34px 10px 12px;
  border: 1px solid var(--border); border-radius: var(--radius-btn);
  font-family: inherit; font-size: 14px;
  background: var(--bg); color: var(--text);
  min-height: 44px; transition: border-color 0.2s;
  -webkit-appearance: none; appearance: none;
}
.spot-search::placeholder { color: var(--text-muted); }
.spot-search:focus { outline: none; border-color: var(--text-secondary); }
.spot-search::-webkit-search-cancel-button { display: none; }
.spot-search-clear {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  width: 24px; height: 24px; padding: 0; border: none; background: transparent;
  color: var(--text-muted); font-size: 20px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center; border-radius: 50%;
}
.spot-search-clear:hover { color: var(--text); background: var(--border); }
.spot-search-clear:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.spot-search-clear[hidden] { display: none; }

/* ── Spot list ── */
.spot-list { flex: 1; overflow-y: auto; padding: 8px; }
.spot-card {
  padding: 14px; border-radius: var(--radius-card); cursor: pointer;
  transition: all 0.15s; border: 1px solid transparent;
  margin-bottom: 4px; width: 100%; text-align: left; font-family: inherit;
  background: none;
}
.spot-card:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.spot-card:hover { background: #f9fafb; border-color: var(--border); box-shadow: var(--shadow); }
.spot-card.active { background: #F1F2F5; border-color: var(--accent); box-shadow: var(--shadow-elevated); }
.card-top { display: flex; align-items: start; gap: 12px; }
.card-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0;
  font-size: 14px; font-weight: 700; color: #fff;
}
.card-info { flex: 1; min-width: 0; }
.card-name {
  font-size: 14px; font-weight: 600; color: var(--text);
  line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.card-korean {
  font-family: 'Noto Sans KR', var(--font-display);
  font-size: 12px; color: var(--text-muted); margin-top: 1px;
}
.spot-card mark {
  background: #fef3c7; color: inherit; padding: 0 1px; border-radius: 2px;
}
.spot-empty-state {
  padding: 24px 18px;
  text-align: center;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.5;
}
.spot-empty-reset {
  margin-top: 14px;
  min-height: 44px;
  padding: 9px 16px;
  border: 1.5px solid var(--text);
  border-radius: var(--radius-btn);
  background: var(--text);
  color: var(--bg);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.spot-empty-reset:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.spot-empty-reset:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.card-hero {
  width: 56px; height: 56px; border-radius: 10px; flex-shrink: 0;
  background-size: cover; background-position: center; background-color: #f3f4f6;
  position: relative; overflow: hidden;
}
.card-hero-fallback {
  width: 56px; height: 56px; border-radius: 10px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700; color: #fff;
}
.card-hero .card-fav-mini {
  position: absolute; top: 2px; right: 2px;
  width: 22px; height: 22px; border-radius: 50%; border: none;
  background: rgba(0,0,0,0.55); color: #fff; padding: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center; font-size: 11px;
}

/* ── Autocomplete suggestions ── */
.search-suggest {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 50;
  background: var(--bg-card, #fff); border: 1px solid var(--border);
  border-radius: var(--radius-btn); margin-top: 4px; max-height: 320px;
  overflow-y: auto; box-shadow: var(--shadow-elevated);
}
.search-suggest-group { padding: 4px 0; }
.search-suggest-group + .search-suggest-group { border-top: 1px solid var(--border-light, #eee); }
.search-suggest-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-muted); padding: 8px 12px 4px;
}
.search-suggest-item {
  width: 100%; text-align: left; padding: 8px 12px; background: none; border: none;
  font-family: inherit; font-size: 13px; color: var(--text); cursor: pointer;
  display: flex; align-items: center; gap: 10px;
}
.search-suggest-item:hover,
.search-suggest-item.sel { background: #f3f4f6; }
.search-suggest-icon { width: 20px; flex-shrink: 0; text-align: center; }
.search-suggest-meta { margin-left: auto; font-size: 11px; color: var(--text-muted); }

/* ── Category spotlight: dim non-matching when filtering ── */
.spotlight-active .mapboxgl-canvas-container::before {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: rgba(250, 249, 247, 0.35);
}

/* ── Map photo-tile markers ───────────────────────────────────────────────
   Replaces Mapbox circle layers with HTML markers showing spot thumbnails.
   Three variants: single (unclustered), grid (2–9 spots), dense (10–99). */
.map-tile {
  position: relative; cursor: pointer;
  display: inline-block; /* hug content so absolutely-positioned badge lands on the tile */
  transition: transform 0.15s ease;
}
.map-tile:hover { transform: translateY(-2px) scale(1.04); z-index: 3; }

/* Single-spot tile: 44x44 rounded square with a big category icon.
   Icons are emoji; `filter` whitens them on colored backgrounds via a
   slight saturation boost + white shadow so they read against the tint. */
.map-tile-single {
  width: 44px; height: 44px; border-radius: 12px;
  background: var(--cat-color, #666);
  box-shadow: 0 2px 6px rgba(0,0,0,0.25), inset 0 0 0 2px #fff;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; line-height: 1;
}

/* Cluster grid tile: 2x2 of small category icons — tells the brain what's
   inside the cluster at a glance ("3 coffees + 1 bar") instead of a number. */
.map-tile-grid {
  width: 54px; height: 54px; border-radius: 12px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0,0,0,0.28);
  padding: 2px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
}
.map-tile-grid-cell {
  background-color: var(--cell-color, #666);
  border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; line-height: 1;
}

/* Dense cluster (10+): colored circle with big count overlay. */
.map-tile-dense {
  width: 60px; height: 60px; border-radius: 50%;
  background: var(--cat-color, #666);
  box-shadow: 0 2px 8px rgba(0,0,0,0.3), inset 0 0 0 3px #fff;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 18px; font-weight: 800;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}

/* Plain count circle (100+ spots): keep the old visual for readability. */
.map-tile-big {
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--header-bg); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700; box-shadow: 0 2px 6px rgba(0,0,0,0.3);
  border: 2px solid #fff;
}

/* Count badge overlay shared by grid/dense variants */
.map-tile-count {
  position: absolute; bottom: -4px; right: -4px;
  background: var(--text); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 1;
  padding: 3px 6px; border-radius: 999px;
  border: 2px solid #fff; min-width: 22px; text-align: center;
}

/* Active/selected state (when popup open) */
.map-tile.selected { z-index: 4; }
.map-tile.selected .map-tile-single,
.map-tile.selected .map-tile-grid,
.map-tile.selected .map-tile-dense {
  box-shadow: 0 0 0 3px #1d4ed8, 0 4px 16px rgba(29,78,216,0.3);
}

.card-meta { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.card-rating { font-size: 12px; font-weight: 600; color: #f59e0b; }
.card-city { font-size: 11px; color: var(--text-muted); }
.card-cat-label {
  font-size: 10px; font-weight: 600; padding: 2px 8px;
  border-radius: var(--radius-pill); text-transform: uppercase; letter-spacing: 0.3px;
}

/* ── Map ── */
.map-container { flex: 1; position: relative; }
#map { width: 100%; height: 100%; }

/* ── Map empty state ────────────────────────────────────────────────────
   Shown when Mapbox fails (bad token, CSP block, offline, timeout).
   Frames the failure as recoverable: the sidebar list still works, and
   geolocation-driven "near me" doesn't depend on the map either. */
.map-empty-state {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  height: 100%; padding: 32px 24px; box-sizing: border-box;
  background: var(--bg); text-align: center;
}
.map-empty-icon {
  font-size: 44px; margin-bottom: 14px; opacity: 0.55;
}
.map-empty-title {
  font-family: var(--font-display);
  font-size: 19px; font-weight: 700;
  color: var(--text); margin-bottom: 8px; letter-spacing: -0.005em;
}
.map-empty-body {
  font-family: var(--font-body);
  font-size: 17px; line-height: 1.5;
  color: var(--text-secondary);
  max-width: 360px; margin-bottom: 20px;
}
.map-empty-body strong { color: var(--text); font-weight: 500; }
.map-empty-actions {
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center;
  width: 100%; max-width: 320px;
}
.map-empty-cta {
  font-family: var(--font-display);
  font-size: 13.5px; font-weight: 600;
  padding: 10px 16px;
  border-radius: var(--radius-btn);
  cursor: pointer;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text);
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px;
}
.map-empty-cta:hover { background: var(--border-light); border-color: var(--text-muted); }
.map-empty-cta.primary {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.map-empty-cta.primary:hover {
  background: var(--primary-hover); border-color: var(--primary-hover);
}
.map-empty-cta.mobile-only { display: none; }
@media (max-width: 768px) {
  /* Mobile: smaller hero icon, tighter padding, and full-width stacked buttons
     so neither CTA gets clipped at the viewport edge on narrow phones. */
  .map-empty-state { padding: 20px 16px; }
  .map-empty-icon { font-size: 36px; margin-bottom: 8px; }
  .map-empty-title { font-size: 17px; margin-bottom: 6px; }
  .map-empty-body { font-size: 15px; margin-bottom: 14px; }
  .map-empty-actions { flex-direction: column; gap: 8px; }
  .map-empty-cta { width: 100%; }
  .map-empty-cta.mobile-only { display: inline-flex; }
}

/* ──────────────────────────────────────────────────────────────────────── */
/* Place Detail UI — mobile bottom sheet + desktop side panel               */
/* Replaces the legacy floating Mapbox popup. Same data, viewport-adaptive  */
/* chrome. Driven by showPlaceDetail / openMobileSheet / openDesktopPanel.  */
/* ──────────────────────────────────────────────────────────────────────── */
.place-sheet,
.place-panel {
  --pd-surface: #FAF9F7;
  --pd-surface-card: rgba(255,255,255,0.6);
  --pd-text: var(--text);
  --pd-text-2: var(--text-secondary);
  --pd-text-3: var(--text-muted);
  --pd-border: var(--border);
  --pd-border-soft: var(--border-light);
  --pd-radius: 16px;
  --pd-radius-inner: 12px;
  --pd-cta-bg: #03C75A;
  font-family: var(--font-display);
  color: var(--pd-text);
  z-index: 900;
}
.place-sheet[hidden], .place-panel[hidden] { display: none !important; }

/* Mobile bottom sheet */
.place-sheet {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 14px;
  background: var(--pd-surface);
  border: 1px solid rgba(232, 229, 225, 0.95);
  border-radius: 22px;
  box-shadow: 0 24px 70px rgba(15, 23, 42, 0.22), 0 4px 18px rgba(15, 23, 42, 0.08);
  display: flex; flex-direction: column;
  max-height: min(430px, calc(100dvh - 92px));
  overflow: hidden;
  transform: translateY(0); opacity: 1;
  transition: max-height 0.25s ease-out, transform 0.25s ease-out, opacity 0.2s ease-out;
  padding-bottom: 0;
}
.place-sheet[data-state="expanded"] { max-height: calc(100dvh - 82px); }
.place-sheet.is-opening { transform: translateY(100%); opacity: 0; }
.place-sheet.is-closing { transform: translateY(100%); opacity: 0; }

/* Desktop side panel — anchored to the top-right; height tracks the surface's
   content. With max-height capping at viewport, long spots scroll inside the
   body and the CTA stays at the bottom of the visible panel. Short spots make
   the panel a compact card without dead space below the CTA. */
.place-panel {
  position: fixed;
  top: calc(72px + env(safe-area-inset-top, 0px));
  right: 24px;
  bottom: auto;
  max-height: calc(100dvh - 96px - env(safe-area-inset-top, 0px));
  width: 420px;
  background: var(--pd-surface);
  border: 1px solid rgba(232, 229, 225, 0.95);
  box-shadow: 0 24px 70px rgba(15, 23, 42, 0.16), 0 6px 24px rgba(15, 23, 42, 0.08);
  border-radius: 18px;
  display: flex; flex-direction: column;
  overflow: hidden;
  transform: translateX(0); opacity: 1;
  transition: transform 0.25s ease-out, opacity 0.2s ease-out;
}
.place-panel.is-opening { transform: translateX(100%); opacity: 0; }
.place-panel.is-closing { transform: translateX(100%); opacity: 0; }

/* Drag handle (mobile only — hidden on desktop panel) */
.pd-handle {
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 24px; padding: 8px 0 2px;
  background: none; border: none; cursor: pointer; font-family: inherit;
}
.pd-handle::before {
  content: ''; width: 44px; height: 5px;
  border-radius: 999px; background: #d4d4d8;
  transition: background 0.15s;
}
.pd-handle:hover::before, .pd-handle:focus-visible::before { background: #a1a1aa; }
.pd-handle:focus-visible { outline: none; }
.place-panel .pd-handle { display: none; }

/* Close button (top-right both surfaces) */
.pd-close {
  position: absolute; top: 12px; right: 14px;
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(245, 242, 238, 0.92);
  border: none; border-radius: 9999px;
  color: var(--pd-text-2);
  cursor: pointer; transition: background 0.15s;
}
.pd-close svg { width: 18px; height: 18px; }
.pd-close:hover { background: rgba(0,0,0,0.08); }
.pd-close:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.place-sheet .pd-close { top: 8px; }

/* Scrollable body + sticky CTA bar (shared between sheet and panel)
   .pd-body uses flex:0 1 auto so it shrinks to its content height — when the
   spot has minimal info the surface stays compact and the CTA sits naturally
   below the content with no empty band above it. With long content the body
   hits the surface's max-height (compact preview / expanded sheet / panel) and its own
   overflow-y kicks in to scroll. CTA stays a sibling so it's always pinned
   to the bottom of the surface regardless of content length. */
.pd-body {
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 20px 12px;
  scrollbar-gutter: stable;
}
.place-sheet .pd-body { padding-top: 0; }
.place-panel .pd-body { padding-top: 18px; }
.pd-cta-bar {
  flex: 0 0 auto;
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--pd-surface);
  border-top: 1px solid var(--pd-border-soft);
}
.pd-cta {
  flex: 1 1 auto;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px;
  padding: 12px 16px;
  border-radius: var(--pd-radius-inner);
  font-family: inherit; font-size: 14px; font-weight: 700;
  color: #fff; text-decoration: none; cursor: pointer;
  background: var(--pd-cta-bg);
  border: none;
  transition: filter 0.15s, transform 0.1s;
  letter-spacing: 0.01em;
}
.pd-cta:hover { filter: brightness(0.92); }
.pd-cta:active { transform: translateY(1px); }
.pd-cta svg { flex-shrink: 0; }

/* Header */
.pd-header { padding-top: 4px; padding-right: 40px; }
.pd-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 9px; }
.pd-chip {
  display: inline-flex; align-items: center;
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.5px;
  padding: 4px 10px;
  border-radius: 9999px;
  white-space: nowrap;
}
.pd-name {
  font-family: var(--font-display);
  font-size: 22px; font-weight: 650;
  color: var(--pd-text); line-height: 1.2;
  margin: 0;
}
.place-panel .pd-name { font-size: 22px; }
.pd-local-name {
  font-family: 'Noto Sans KR', var(--font-display);
  font-size: 14px; color: var(--pd-text-3);
  margin-top: 4px;
}
.pd-rating {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 8px; font-size: 13px;
}
.pd-rating .stars { color: #f59e0b; letter-spacing: 1px; }
.pd-rating .val { font-weight: 600; color: var(--pd-text-2); }
.pd-meta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 4px 10px;
  margin-top: 9px;
  font-size: 12px; color: var(--pd-text-3);
}
.pd-meta-item { display: inline-flex; align-items: center; gap: 4px; }
.pd-meta-item strong { color: var(--pd-text-2); font-weight: 600; }
.pd-meta .stars { color: #f59e0b; letter-spacing: 0.5px; font-size: 12px; }
.pd-meta-item.is-rating strong { color: var(--pd-text); font-size: 12.5px; }
.pd-meta-dot {
  width: 3px; height: 3px; border-radius: 999px;
  background: currentColor; opacity: 0.5;
  flex-shrink: 0;
}

/* Description (clamped on mobile preview).
   Long-form prose uses the editorial serif (Quiet Luxury palette) — gives the
   description weight and character vs. the surrounding sans UI chrome. */
.pd-desc {
  margin-top: 12px;
  font-family: var(--font-body);
  font-size: 16px; color: var(--pd-text-2);
  line-height: 1.65;
}
.place-sheet[data-state="preview"] .pd-desc {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Review banner (top blog-post link) */
.pd-review-banner {
  display: flex; align-items: center; gap: 8px;
  margin-top: 12px;
  padding: 10px 12px;
  background: #F1F2F5;
  border-radius: var(--pd-radius-inner);
  font-size: 13px; color: var(--accent); font-weight: 600;
  text-decoration: none;
  transition: background 0.15s;
}
.pd-review-banner:hover { background: #E5E7EB; }
.pd-review-banner svg { flex-shrink: 0; }

/* Compact utility action row — small icon+label buttons aligned in one flex row.
   Replaces the previous oversized stacked-card layout. The row holds 4–5 items
   depending on data: View on map (always), Instagram (if links.instagram),
   Reserve (if links.catchTable), Copy address (always), Share (always). */
.pd-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 13px;
}
.pd-action {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 8px 4px;
  background: #ffffff;
  border: 1px solid var(--pd-border);
  border-radius: 10px;
  font-family: inherit; font-size: 11.5px; font-weight: 500;
  color: var(--pd-text-2);
  text-decoration: none; cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.1s;
  min-height: 38px;
  white-space: nowrap;
}
.pd-action:hover { background: #fafaf9; border-color: var(--pd-text-3); color: var(--pd-text); }
.pd-action:active { transform: scale(0.98); }
.pd-action:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.pd-action svg { flex-shrink: 0; width: 15px; height: 15px; }
.pd-action-label { line-height: 1.2; overflow: hidden; text-overflow: ellipsis; }

.place-sheet .pd-actions {
  gap: 0;
  padding: 8px 0;
  border-top: 1px solid #F2EFEA;
  border-bottom: 1px solid #F2EFEA;
}
.place-sheet .pd-action {
  min-height: 54px;
  border: 0;
  border-radius: 0;
  background: transparent;
  flex-direction: column;
  gap: 5px;
  font-size: 11px;
}
.place-sheet .pd-action + .pd-action { border-left: 1px solid #F2EFEA; }
.place-sheet .pd-action:hover { background: #fafaf9; border-color: #F2EFEA; }
.place-sheet .pd-action svg { width: 18px; height: 18px; }

.place-panel .pd-actions {
  margin-top: 10px;
  gap: 6px;
}
.place-panel .pd-action {
  min-height: 32px;
  padding: 6px 8px;
  border-radius: 8px;
  font-size: 11px;
}

/* Section title (shared) */
.pd-section { margin-top: 16px; }
.pd-section-title {
  font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.7px;
  color: var(--pd-text-3);
  margin-bottom: 8px;
}

/* Card primitive — used by Must Try, Good For, Practical info, Address, and
   the Related-posts list. Gives sections a soft container, subtle border,
   and consistent rhythm. */
.pd-card {
  margin-top: 12px;
  padding: 13px 14px;
  background: #ffffff;
  border: 1px solid #ECE9E4;
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(26,26,26,0.03);
}
.pd-card-accent-warm {
  background: linear-gradient(135deg, #FFFBEA 0%, #FFF7D6 100%);
  border-color: #F9D86A;
}
.pd-card-accent-warm .pd-section-title { color: #92400E; }
.pd-card-accent-warm .pd-must-try-text { color: #713f12; }

/* Must-try — content style (card chrome handled by .pd-card.pd-card-accent-warm) */
.pd-must-try-content {
  display: grid;
  grid-template-columns: 46px 1fr;
  gap: 10px;
  align-items: center;
}
.pd-must-icon {
  width: 46px;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  color: #8A4F16;
  background: rgba(255, 255, 255, 0.76);
  box-shadow: inset 0 0 0 1px rgba(146, 64, 14, 0.12);
}
.pd-must-icon svg { width: 24px; height: 24px; }
.pd-must-try-text { font-family: var(--font-body); font-size: 15.5px; line-height: 1.55; color: var(--pd-text); }

/* Good for (vibe tags) */
.pd-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.pd-tag {
  font-size: 12px; padding: 4px 10px;
  border-radius: 9999px;
  background: #F5F2EE;
  color: var(--pd-text-2);
}

/* Two-column grid for Must Try + Good For (desktop side panel only).
   Mobile sheet keeps cards stacked. Single-card grids span full width. */
.pd-grid-2 { margin-top: 12px; }
.pd-grid-2 > .pd-card { margin-top: 12px; }
.pd-grid-2 > .pd-card:first-child { margin-top: 0; }
@media (min-width: 768px) {
  .place-panel .pd-grid-2 {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: 10px;
    align-items: stretch;
  }
  .place-panel .pd-grid-2 > .pd-card { margin-top: 0; }
  .place-panel .pd-grid-2 > .pd-card:first-child { margin-top: 0; }
  .place-panel .pd-good-for {
    background: linear-gradient(180deg, #fff 0%, #FCFBFA 100%);
  }
}

/* Practical info row — 1 to 4 small cards, columns set via --cols inline. */
.pd-practical-row {
  display: grid;
  grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr));
  gap: 8px;
  margin-top: 12px;
}
.pd-practical-row > .pd-card { margin-top: 0; padding: 10px 12px; }
.pd-info-card {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: 7px;
  align-items: start;
}
.pd-info-card-icon {
  color: var(--pd-text-3);
  margin-top: 1px;
}
.pd-info-card-icon svg {
  width: 16px;
  height: 16px;
}
.pd-card-label {
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--pd-text-3);
  margin-bottom: 3px;
}
.pd-card-value {
  font-size: 12.5px; line-height: 1.35;
  color: var(--pd-text);
}

.place-panel .pd-practical-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  padding: 7px 10px;
  background: #ffffff;
  border: 1px solid #ECE9E4;
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(26,26,26,0.03);
}
.place-panel .pd-practical-row > .pd-card {
  flex: 1 1 50%;
  min-width: 0;
  padding: 8px 8px;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}
.place-panel .pd-practical-row > .pd-card:nth-child(even) { border-left: 1px solid #F2EFEA; }
.place-panel .pd-practical-row > .pd-card:nth-child(n+3) { border-top: 1px solid #F2EFEA; }
.place-panel .pd-info-card {
  grid-template-columns: 20px 1fr;
  gap: 7px;
}
.place-panel .pd-info-card-icon {
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #059669;
  background: #ECFDF5;
  border-radius: 999px;
}
.place-panel .pd-info-card-icon svg {
  width: 12px;
  height: 12px;
}
.place-panel .pd-card-label {
  font-size: 9.5px;
  margin-bottom: 2px;
}
.place-panel .pd-card-value {
  font-size: 11.5px;
  line-height: 1.3;
}

/* Hours card: compact "Today" line + collapsible full week below */
.pd-hours-today { font-weight: 600; }
.pd-hours-week-toggle {
  display: inline-block;
  margin-top: 4px;
  font-size: 11px;
  color: var(--pd-text-3);
  cursor: pointer;
  user-select: none;
  background: none; border: none; padding: 0;
  font-family: inherit;
}
.pd-hours-week-toggle:hover { color: var(--pd-text); }
.pd-hours-week-list {
  margin: 6px 0 0;
  padding: 6px 0 0;
  border-top: 1px solid #F2EFEA;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 10px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--pd-text-2);
}
.pd-hours-week-list > .pd-hours-day { font-weight: 600; color: var(--pd-text); }
.pd-hours-week-list > .pd-hours-day-today {
  font-weight: 700;
  color: #92400E;
}
.pd-hours-week-list > .pd-hours-time-today { color: #92400E; }

/* Permanently-closed banner */
.pd-closed-banner {
  margin-top: 12px;
  padding: 10px 14px;
  background: #FEF2F2;
  border: 1px solid #FECACA;
  border-radius: 12px;
  font-size: 13px; font-weight: 600;
  color: #991B1B;
  display: flex; align-items: center; gap: 8px;
}
.pd-closed-banner svg { width: 18px; height: 18px; flex-shrink: 0; }

/* Address card — list lives inside a .pd-card so it has no own border.
   .pd-addr-list rows are full-width buttons; subtle dividers between rows. */
.pd-addr-list { margin-top: 4px; }
.pd-addr-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%;
  padding: 8px 0;
  background: none; border: none;
  font-family: inherit; text-align: left;
  cursor: pointer;
  min-height: 44px;
  transition: opacity 0.12s;
}
.pd-addr-row + .pd-addr-row { border-top: 1px solid #F2EFEA; }
.pd-addr-row:hover { opacity: 0.78; }
.pd-addr-row:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; border-radius: 4px; }
.pd-addr-text { font-size: 13px; color: var(--pd-text); line-height: 1.4; flex: 1; min-width: 0; word-break: break-word; }
.pd-addr-text.is-ko { font-family: 'Noto Sans KR', var(--font-display); color: var(--pd-text-2); }
.pd-addr-list .copy-hint {
  font-size: 10px; font-weight: 600; letter-spacing: 0.4px; text-transform: uppercase;
  color: var(--pd-text-3);
  padding: 4px 8px;
  background: #F5F2EE;
  border-radius: 6px;
}
.pd-addr-loading {
  display: block; height: 14px; width: 70%;
  background: linear-gradient(90deg, #efeae3 0%, #f8f4ee 50%, #efeae3 100%);
  background-size: 200% 100%;
  animation: pdShimmer 1.2s infinite linear;
  border-radius: 4px;
}
@keyframes pdShimmer {
  from { background-position: 0 0; }
  to { background-position: -200% 0; }
}

/* Footer feedback links */
.pd-feedback {
  display: flex; gap: 16px; flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 12px;
  border-top: 1px solid var(--pd-border-soft);
}
.pd-feedback-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px; color: var(--pd-text-3);
  text-decoration: none;
  transition: color 0.15s;
}
.pd-feedback-link svg { width: 12px; height: 12px; }
.pd-feedback-link:hover { color: var(--pd-text-2); text-decoration: underline; }

/* Related blog posts — list lives inside a .pd-card so items sit on the
   white surface without their own border chrome. */
.pd-related-list { margin-top: 4px; display: flex; flex-direction: column; gap: 4px; }
.pd-related-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 4px;
  text-decoration: none;
  transition: opacity 0.15s;
  border-radius: 8px;
}
.pd-related-item + .pd-related-item { border-top: 1px solid #F2EFEA; }
.pd-related-item:hover { opacity: 0.82; }
.pd-related-thumb {
  width: 44px; height: 44px;
  border-radius: 8px;
  background: #F5F2EE center/cover no-repeat;
  flex-shrink: 0;
}
.pd-related-meta { min-width: 0; flex: 1; }
.pd-related-title { font-size: 13px; font-weight: 600; color: var(--pd-text); line-height: 1.3; }
.pd-related-date { font-size: 11px; color: var(--pd-text-3); margin-top: 2px; }

/* "More details" disclosure (mobile sheet only) */
.pd-more-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin: 14px auto 0;
  padding: 8px 16px; min-height: 44px;
  background: none; border: none;
  font-family: inherit; font-size: 13px; font-weight: 500;
  color: var(--pd-text-2);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.pd-more-toggle svg { width: 14px; height: 14px; }
.pd-more-toggle:focus-visible {
  outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px;
}
.place-sheet[data-state="expanded"] .pd-more-toggle,
.place-panel .pd-more-toggle { display: none; }

/* Mobile preview state — surface acts like a compact card hovering over the
   map. Body shrinks to its (preview-only) content so the sheet height tracks
   what's actually visible. Expanded-only blocks are hidden AND aria-hidden so
   focus can't reach them. */
.place-sheet[data-state="preview"] { max-height: min(360px, calc(100dvh - 116px)); }
.place-sheet[data-state="preview"] .pd-body {
  max-height: 240px;
  overflow: hidden;
}
.place-sheet[data-state="preview"] .pd-expanded-only { display: none; }

@media (max-width: 360px) {
  .place-sheet { left: 10px; right: 10px; bottom: 10px; border-radius: 18px; }
  .pd-body { padding-left: 14px; padding-right: 14px; }
  .pd-cta-bar { padding-left: 14px; padding-right: 14px; }
  .pd-name { font-size: 20px; }
  .pd-action { font-size: 11px; }
}

@media (prefers-reduced-motion: reduce) {
  .place-sheet, .place-panel { transition-duration: 0.01s; }
}

/* Narrow desktop: collapse the spot-list sidebar when detail panel is open */
@media (min-width: 769px) and (max-width: 1199px) {
  .sidebar.collapsed-by-detail {
    width: 0; min-width: 0;
    overflow: hidden;
    border-right: none;
    opacity: 0;
    transition: width 0.2s ease, opacity 0.15s ease;
  }
}

/* Shared utility classes still consumed by spot-list cards and the new place
   detail (e.g. copyToClipboard expects a `.copy-hint` span inside the row). */
.copy-hint { font-size: 10px; color: var(--text-muted); white-space: nowrap; flex-shrink: 0; }
.card-distance { font-size: 11px; color: var(--text-muted); }
.card-type-label {
  font-size: 10px; font-weight: 600; padding: 2px 8px;
  border-radius: var(--radius-pill); background: var(--border-light); color: var(--text-muted);
}
.card-michelin { font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: var(--radius-pill); }

/* ── View Toggle ── */
.view-toggle {
  display: none; /* shown on mobile */
  align-items: center;
  background: rgba(255,255,255,0.12);
  border-radius: var(--radius-pill);
  overflow: hidden;
  height: 44px;
}
.view-toggle-btn {
  display: flex; align-items: center; justify-content: center;
  padding: 0 12px; height: 100%;
  font-size: 12px; font-weight: 500; color: rgba(255,255,255,0.6);
  cursor: pointer; border: none; background: none;
  transition: all 0.15s; gap: 4px; min-width: 44px;
}
.view-toggle-btn.active {
  background: rgba(255,255,255,0.2); color: #fff;
}
.view-toggle-btn svg, .view-toggle-btn span { width: 14px; height: 14px; pointer-events: none; }

/* ── Mobile ── */
@media (max-width: 768px) {
  .main { flex-direction: column-reverse; }
  .sidebar {
    width: 100%; min-width: 100%; max-height: 45dvh;
    border-right: none; border-top: 1px solid var(--border);
    transition: max-height 0.3s ease, opacity 0.2s ease;
    overflow-y: auto; display: block;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .spot-list { overflow-y: visible; }
  .map-container { flex: 1; min-height: 0; }
  .spot-count { display: none; }
  .chip { min-height: 44px; padding: 10px 16px; font-size: 13px; }
  .city-select { min-height: 44px; }
  .view-toggle { display: flex; }
  .header-right { gap: 8px; }
  .toggle-label { display: none; }

  /* Collapse sidebar when popup is open */
  .sidebar.collapsed {
    max-height: 0; overflow: hidden; border-top: none;
  }

  /* View modes */
  .main.view-list .map-container { display: none; }
  .main.view-list .sidebar {
    max-height: 100%; flex: 1; border-top: none; overflow-y: auto;
  }
  .main.view-map .sidebar { display: none; }
  .main.view-map .map-container { flex: 1; }
}
