:root {
  --bg: #faf9f7;
  --text: #2b2b2b;
  --text-muted: #6b6b6b;
  --accent: #E07A5F;
  --border: #e7e2d6;
  --editorial-bg: #f5f1ea;
  --font-display: 'Playfair Display', Georgia, serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --transition: 250ms ease;
  --shadow-sidebar: -4px 0 24px rgba(0, 0, 0, 0.10);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  font-family: var(--font-body);
  color: var(--text);
  background: var(--bg);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

#map {
  position: absolute;
  inset: 0;
}

.narrative-done .app-header,
.narrative-done .legend {
  opacity: 1 !important;
  pointer-events: auto !important;
}

/* Header */
.app-header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 14px 22px;
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 16px;
}
.app-title {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
}
.app-subtitle {
  font-size: 13px;
  color: var(--text-muted);
  font-style: italic;
}

/* Sidebar */
.sidebar {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 440px;
  max-width: 100%;
  background: #fff;
  box-shadow: var(--shadow-sidebar);
  transform: translateX(100%);
  transition: transform var(--transition);
  overflow-y: auto;
  z-index: 10;
}
.sidebar.is-open {
  transform: translateX(0);
}
.sidebar-inner {
  padding: 24px 28px 48px;
}
.sidebar-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
  border: none;
  background: transparent;
  border-radius: 50%;
  cursor: pointer;
  font-size: 22px;
  line-height: 1;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  transition: background var(--transition), color var(--transition);
}
.sidebar-close:hover {
  background: rgba(0, 0, 0, 0.05);
  color: var(--text);
}

/* Place card */
.place-type-badge {
  display: inline-block;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--accent);
  color: white;
  margin-bottom: 16px;
}
.place-name {
  font-family: var(--font-display);
  font-size: 32px;
  line-height: 1.05;
  font-weight: 700;
  margin: 0 0 18px;
  letter-spacing: -0.015em;
}
.place-soul {
  font-size: 17px;
  line-height: 1.55;
  margin: 0 0 22px;
  color: #353535;
}
.place-meta {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 22px;
  flex-wrap: wrap;
}

.rating {
  position: relative;
  display: inline-block;
  font-size: 17px;
  letter-spacing: 1px;
  line-height: 1;
  vertical-align: middle;
}
.rating-empty {
  color: #e0d8c8;
}
.rating-filled {
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
  white-space: nowrap;
  color: var(--accent);
}
.rating-num {
  font-weight: 600;
  font-size: 14px;
  color: var(--text);
  margin-left: 8px;
  vertical-align: middle;
}
.review-count {
  color: var(--text-muted);
  font-size: 13px;
}

.place-editorial {
  font-size: 14px;
  color: #5a5a5a;
  font-style: italic;
  margin: 0 0 22px;
  padding: 12px 14px;
  background: var(--editorial-bg);
  border-radius: 6px;
  border-left: 3px solid var(--accent);
}

/* Atmosphere pills */
.atmosphere {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 24px;
}
.pill {
  font-size: 12px;
  font-weight: 500;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--editorial-bg);
  color: var(--text);
  border: 1px solid var(--border);
}

/* Section headings */
.section-title {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-muted);
  margin: 24px 0 12px;
}

/* Kindred Places */
.kindred {
  display: grid;
  gap: 8px;
  grid-template-columns: 1fr;
}
.kindred-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 14px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: background var(--transition), border-color var(--transition);
}
.kindred-card:hover {
  background: var(--editorial-bg);
  border-color: var(--accent);
}
.kindred-name {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.2;
}
.kindred-type {
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Error overlay */
#error {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: white;
  padding: 16px 20px;
  border-radius: 6px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
  max-width: 460px;
  font-size: 14px;
  line-height: 1.5;
  display: none;
  z-index: 20;
}

/* Loading overlay */
#loading {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: white;
  padding: 12px 20px;
  border-radius: 6px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
  font-size: 14px;
  display: none;
  z-index: 20;
}

#replay-narrative {
  /* Previously margin-left:auto pushed the buttons to the right edge.
     The new .search-container (margin-left:auto + margin-right:auto)
     between subtitle and this button now provides the spacer that
     centers the search and keeps the buttons flush right, so this
     margin-left must be 0 — otherwise it would steal half the
     available space and shift the search off-center. */
  margin-left: 0;
  background: transparent;
  border: 1px solid rgba(43,43,43,0.3);
  color: var(--text-muted);
  padding: 6px 14px;
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: 12px;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}
#replay-narrative:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Empty state in sidebar */
.empty-state {
  padding: 40px 20px;
  text-align: center;
  color: var(--text-muted);
  font-size: 15px;
  font-style: italic;
  line-height: 1.6;
}

/* Legend */
.legend {
  position: fixed;
  bottom: 40px;
  left: 16px;
  z-index: 5;
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  padding: 12px 14px;
  border-radius: 8px;
  border: 1px solid var(--border);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}
.legend-title {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--text-muted);
  margin-top: 8px;
  margin-bottom: 8px;
}
.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  margin-bottom: 5px;
}
.legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.legend-title-second {
  margin-top: 12px;
}
.legend-size {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 2px 4px;
}
.legend-size-dot {
  display: inline-block;
  background: #888;
  border-radius: 50%;
  flex-shrink: 0;
}
.legend-caption {
  font-size: 10px;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

.legend-top {
  display: flex;
  align-items: center;
}
.legend-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 1;
  background: transparent;
  border: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.legend-toggle:hover { opacity: 0.8; }
/* Theme toggle — circular button next to the legend label. Swaps the
   Mapbox basemap lightPreset between 'day' and 'night' and adds
   body.theme-night so the rest of the chrome's dark-mode overrides
   below take effect. Icon swaps between ☾ (when on day, inviting night)
   and ☼ (when on night, inviting day). */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--accent);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  color: var(--accent);
  padding: 0;
  font: inherit;
  line-height: 1;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.theme-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
  filter: brightness(0.85);
}
.theme-toggle-icon {
  font-size: 14px;
  line-height: 1;
}
/* Horizontal row inside legend-content that holds the theme + 3D
   toggles side by side. */
.legend-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
/* 3D objects toggle — same circular silhouette as the theme toggle so
   the two read as a paired control. Inherits .theme-toggle base by
   sharing the same dimensions/border treatment via this rule. The
   .is-active state lights up when 3D is on (default); clicking flips
   to the dim "off" look. */
.three-d-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 26px;
  padding: 0 6px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: transparent;
  cursor: pointer;
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.three-d-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.three-d-toggle.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}
.three-d-toggle.is-active:hover {
  filter: brightness(0.85);
}
.legend-toggle-icon {
  font-size: 26px;
  opacity: 0.7;
}
.legend-content {
  overflow: hidden;
  transition: max-height 0.25s ease, opacity 0.25s ease;
  max-height: 500px;
  opacity: 1;
}
.legend-content.is-collapsed {
  max-height: 0;
  opacity: 0;
}
@media (max-width: 640px) {
  .legend-toggle {
    display: flex;
  }
}

/* Reposition Mapbox controls */
.mapboxgl-ctrl-bottom-right {
  bottom: 20px;
  right: 20px;
}
/* Zoom controls stay out of the way during the scrollytelling intro —
   the narrative drives the camera and any user-initiated zoom would
   fight the scripted flyTo/easeTo passes. */
body.narrative-active .mapboxgl-ctrl-group {
  display: none !important;
}

/* Kindred section header — keeps the section title and the second-tier
   toggle on one row inside the sidebar. */
.kindred-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 24px 0 12px;
}
.kindred-header .section-title {
  margin: 0;
}

/* Second-tier kindred-web toggle — pill button that sits next to the
   Kindred Places header. Reuses the same accent-on-active treatment as
   the existing sidebar pills. */
.second-tier-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
  white-space: nowrap;
}
.second-tier-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.second-tier-toggle.is-active {
  background: var(--accent);
  color: #ffffff;
  border-color: var(--accent);
}
.second-tier-toggle.is-active:hover {
  filter: brightness(0.92);
}
.second-tier-icon {
  font-size: 13px;
  line-height: 1;
}

/* About panel — slides in from the right opposite the sidebar. Higher
   z-index than the sidebar so it overlays cleanly if both are open. */
#about-btn {
  margin-left: 8px;
  background: transparent;
  border: 1px solid rgba(43, 43, 43, 0.3);
  color: var(--text-muted);
  padding: 6px 14px;
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: 12px;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}
#about-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

#about-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 480px;
  max-width: 100%;
  background: #ffffff;
  box-shadow: -4px 0 24px rgba(0, 0, 0, 0.10);
  transform: translateX(100%);
  transition: transform 250ms ease;
  overflow-y: auto;
  z-index: 12;
}
#about-panel.is-open {
  transform: translateX(0);
}
.about-inner {
  padding: 32px 32px 64px;
}
.about-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
  border: none;
  background: transparent;
  border-radius: 50%;
  cursor: pointer;
  font-size: 22px;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--transition), color var(--transition);
}
.about-close:hover {
  background: rgba(0, 0, 0, 0.05);
  color: var(--text);
}
.about-title {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 700;
  margin: 0 0 6px;
  letter-spacing: -0.01em;
}
.about-subtitle {
  font-size: 14px;
  color: var(--text-muted);
  font-style: italic;
  margin: 0 0 32px;
}
.about-section {
  margin-bottom: 28px;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--border);
}
.about-section:last-child {
  border-bottom: none;
  margin-bottom: 0;
}
.about-section h3 {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  margin: 0 0 10px;
  color: var(--text);
}
.about-section p {
  font-size: 14px;
  line-height: 1.65;
  color: #444;
  margin: 0 0 10px;
}
.about-section p:last-child { margin-bottom: 0; }
.about-section ul {
  font-size: 14px;
  line-height: 1.65;
  color: #444;
  padding-left: 20px;
  margin: 8px 0;
}
.about-section li { margin-bottom: 4px; }
.about-sources p {
  font-size: 13px;
  color: var(--text-muted);
}
.about-sources a {
  color: var(--accent);
  text-decoration: none;
}
.about-sources a:hover { text-decoration: underline; }

/* Vibe chart — atmosphere icons + community identity tags. */
.vibe-chart { margin-bottom: 24px; }
.vibe-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 8px;
}
.vibe-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 48px;
  padding: 6px 0;
}
.vibe-item svg { display: block; }
.vibe-item.is-false svg { opacity: 0.2; }
.vibe-item-label {
  font-size: 10px;
  text-align: center;
  line-height: 1.2;
  color: var(--text-muted);
}
.vibe-item.is-true .vibe-item-label { color: var(--text); }
.vibe-item.is-null { display: none; }
.vibe-community {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.vibe-community-tag {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 500;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--editorial-bg);
  border: 1px solid var(--border);
  color: var(--text);
}

/* Kindred type breakdown — colored dots + legend below the kindred cards. */
.kindred-type-breakdown {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.kindred-type-dots {
  display: flex;
  gap: 6px;
  margin-bottom: 8px;
}
.kindred-type-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  display: inline-block;
  cursor: default;
}
.kindred-type-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.kindred-type-legend-item {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: var(--text-muted);
}
.kindred-type-legend-swatch {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  display: inline-block;
  flex-shrink: 0;
}

/* Community tag filter mode — the sidebar's kindred section is replaced
   by a header with tag name + sub-filter controls and a scrollable list
   of matching places. Driven by enterFilterMode in main.js. */
.filter-header {
  padding: 16px 0 12px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 8px;
}
.filter-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 10px;
}
.filter-tag-name {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
}
.filter-count {
  font-size: 13px;
  color: var(--text-muted);
}
.filter-controls {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.filter-select {
  font-family: var(--font-body);
  font-size: 12px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: white;
  color: var(--text);
  cursor: pointer;
}
.filter-done-btn {
  font-family: var(--font-body);
  font-size: 12px;
  padding: 5px 12px;
  border: 1px solid var(--accent);
  border-radius: 4px;
  background: white;
  color: var(--accent);
  cursor: pointer;
  margin-left: auto;
}
.filter-done-btn:hover { background: var(--accent); color: white; }
.filter-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 400px;
  overflow-y: auto;
}
.filter-place-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-radius: 4px;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: background var(--transition);
}
.filter-place-item:hover { background: var(--editorial-bg); }
.filter-place-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.filter-place-name {
  font-size: 14px;
  font-weight: 500;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.filter-place-meta {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}
.filter-empty {
  padding: 16px 10px;
  font-size: 13px;
  color: var(--text-muted);
  font-style: italic;
}

/* Make community tag pills clickable when they carry a data-filter-tag.
   Plain pills without the attribute keep their default inert styling. */
.vibe-community-tag[data-filter-tag] {
  cursor: pointer;
  transition: all 0.15s;
}
.vibe-community-tag[data-filter-tag]:hover {
  border-color: var(--accent);
  background: var(--editorial-bg);
}
.vibe-community-tag[data-filter-tag].is-active {
  background: var(--accent);
  color: white;
  border-color: var(--accent);
}

/* Mobile bottom-sheet drag handle. Hidden on desktop; the @media block below
   shows it on small screens. JS attaches touch listeners only when mobile. */
.sidebar-drag-handle {
  display: none;
  width: 36px;
  height: 4px;
  background: rgba(0,0,0,0.2);
  border-radius: 2px;
  margin: 12px auto 4px;
  flex-shrink: 0;
  cursor: grab;
}

/* Mobile */
@media (max-width: 640px) {
  .app-header {
    padding: 10px 16px;
  }
  .app-title { font-size: 18px; }
  .app-subtitle { font-size: 12px; }
  .sidebar {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 40vh;
    max-width: 100%;
    transform: translateY(100%);
    transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -4px 24px rgba(0,0,0,0.15);
    overflow-y: auto;
  }
  .sidebar.is-open {
    transform: translateY(0);
  }
  .sidebar.is-expanded {
    height: 85vh;
  }
  .sidebar-drag-handle {
    display: block;
  }
  .sidebar-inner { padding: 20px 20px 32px; }
  .place-name { font-size: 26px; }
  .place-soul { font-size: 16px; }
}

/* Feedback button in header */
#feedback-btn {
  margin-left: 8px;
  background: transparent;
  border: 1px solid rgba(43, 43, 43, 0.3);
  color: var(--text-muted);
  padding: 6px 14px;
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: 12px;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}
#feedback-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Feedback modal */
.feedback-modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s;
}
.feedback-modal.is-open {
  opacity: 1;
  pointer-events: auto;
}
.feedback-modal-inner {
  background: white;
  border-radius: 8px;
  padding: 28px;
  width: 480px;
  max-width: calc(100vw - 32px);
  position: relative;
  box-shadow: 0 8px 32px rgba(0,0,0,0.2);
}
.feedback-modal-close {
  position: absolute;
  top: 12px; right: 12px;
  width: 32px; height: 32px;
  border: none; background: transparent;
  font-size: 20px; cursor: pointer;
  color: var(--text-muted);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.feedback-modal-close:hover { background: rgba(0,0,0,0.05); }
.feedback-modal-title {
  font-family: var(--font-display);
  font-size: 20px; font-weight: 700;
  margin: 0 0 4px;
}
.feedback-modal-subtitle {
  font-size: 14px; color: var(--text-muted);
  margin: 0 0 16px;
  font-style: italic;
}
.feedback-textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 14px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  resize: vertical;
  outline: none;
  box-sizing: border-box;
  line-height: 1.5;
}
.feedback-textarea:focus { border-color: var(--accent); }
.feedback-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
}
.feedback-cancel-btn {
  font-family: var(--font-body);
  font-size: 14px;
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: white;
  cursor: pointer;
  color: var(--text-muted);
}
.feedback-submit-btn {
  font-family: var(--font-body);
  font-size: 14px;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background: var(--accent);
  color: white;
  cursor: pointer;
}
.feedback-submit-btn:disabled { opacity: 0.6; cursor: default; }
.feedback-success {
  margin-top: 12px;
  font-size: 14px;
  color: #2d7a2d;
  text-align: center;
  padding: 8px;
  background: #f0faf0;
  border-radius: 4px;
}
.place-feedback-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-body);
  font-size: 11px;
  color: var(--text-muted);
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  margin-left: 8px;
  margin-bottom: 12px;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.place-feedback-btn:hover { color: var(--accent); }
.about-feedback-btn {
  display: inline-block;
  margin-top: 12px;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 6px 14px;
  cursor: pointer;
  transition: all 0.2s;
}
.about-feedback-btn:hover { background: var(--accent); color: white; }

/* ---------- Header search ----------
   Two auto margins (left + right) on the search container, combined with
   the existing margin-left:auto on #replay-narrative being overridden to
   0 below, position the search bar in the visual middle of the header
   while the buttons stay flush right.
   The filters + results panels are absolutely positioned so toggling
   them open does NOT grow the search container — and therefore does not
   grow the header. Width on the input row is fixed for the same reason
   (no focus-induced shifting of neighboring buttons). */
.search-container {
  position: relative;
  margin-left: auto;
  margin-right: auto;
  z-index: 20;
}
.search-input-row {
  display: flex;
  align-items: center;
  background: var(--editorial-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0 10px;
  height: 34px;
  gap: 6px;
  transition: background 0.2s, border-color 0.2s, box-shadow 0.2s;
  width: 320px;
}
.search-input-row:focus-within {
  background: #ffffff;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(224, 122, 95, 0.12);
}
.search-icon {
  font-size: 13px;
  opacity: 0.7;
  flex-shrink: 0;
}
.search-input {
  background: transparent;
  border: none;
  outline: none;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13px;
  flex: 1;
  min-width: 0;
}
.search-input::placeholder { color: var(--text-muted); }
.search-clear {
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 16px;
  padding: 0;
  line-height: 1;
  flex-shrink: 0;
}
.search-clear:hover { color: var(--text); }
/* Filters live as an absolutely positioned dropdown so opening them
   doesn't grow the search container vertically (which would grow the
   header). Inline `display: flex` is set by JS on focus. */
.search-filters {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  min-width: 320px;
  gap: 6px;
  padding: 8px;
  flex-wrap: wrap;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
  z-index: 30;
}
.search-filter-select {
  font-family: var(--font-body);
  font-size: 11px;
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: #ffffff;
  color: var(--text);
  cursor: pointer;
  flex: 1;
  min-width: 80px;
}
.search-filter-select option { background: #ffffff; color: var(--text); }
/* Results panel sits below the filter strip. Since the JS only shows
   results when filters are also visible (focus is a prerequisite for
   typing), the fixed ~56px offset always clears the filter row — no
   :has() / dynamic offset needed. */
.search-results {
  position: absolute;
  top: calc(100% + 6px + 56px);
  left: 0;
  right: 0;
  min-width: 320px;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  overflow: hidden;
  z-index: 30;
}
.search-results-list {
  max-height: 360px;
  overflow-y: auto;
  padding: 4px;
}
.search-results-count {
  font-size: 11px;
  color: var(--text-muted);
  padding: 8px 10px 4px;
}
.search-result-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-radius: 4px;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: var(--text);
  transition: background 0.1s;
}
.search-result-item:hover { background: var(--editorial-bg); }
.search-result-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.search-result-name {
  font-size: 13px;
  font-weight: 500;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.search-result-meta {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  flex-shrink: 0;
}
.search-no-results {
  padding: 16px;
  text-align: center;
  color: var(--text-muted);
  font-size: 13px;
}
@media (max-width: 640px) {
  .search-container { display: none; }
}

/* ============================================================
   Night theme — applied when body.theme-night is set by initTheme.
   Pairs with the Mapbox basemap lightPreset: 'night' to keep the
   chrome and the map visually consistent.
   ============================================================ */
body.theme-night {
  --bg: #14141f;
  --text: #ececf2;
  --text-muted: #a0a0b0;
  --border: #353548;
  --editorial-bg: #20202e;
  --shadow-sidebar: -4px 0 28px rgba(0, 0, 0, 0.5);
}

/* Header — translucent so the dark basemap shows through, but
   dark enough that text reads cleanly. */
body.theme-night .app-header {
  background: rgba(20, 20, 30, 0.85);
  border-bottom-color: var(--border);
}

/* Sidebar (place detail) — solid dark panel. */
body.theme-night .sidebar {
  background: #1a1a26;
}
body.theme-night .place-soul {
  color: #d8d8e0;
}
body.theme-night .place-editorial {
  color: #c8c8d4;
  background: var(--editorial-bg);
}
body.theme-night .kindred-card {
  color: var(--text);
}
/* Sidebar close button hover — light wash instead of the dark wash that
   reads as "no hover" on a dark surface. */
body.theme-night .sidebar-close:hover {
  background: rgba(255, 255, 255, 0.08);
}

/* Legend panel. */
body.theme-night .legend {
  background: rgba(20, 20, 30, 0.85);
}

/* About panel — solid dark, matches sidebar. */
body.theme-night #about-panel {
  background: #1a1a26;
}
body.theme-night .about-section p,
body.theme-night .about-section ul {
  color: #c8c8d4;
}
body.theme-night .about-sources p {
  color: var(--text-muted);
}

/* Search input row + dropdown panels. The static rgb(255,249,196)
   filter-select rules from the original spec still apply; we just
   swap the panel backgrounds + input text for the dark theme. */
body.theme-night .search-input-row {
  background: var(--editorial-bg);
  border-color: var(--border);
}
body.theme-night .search-input-row:focus-within {
  background: #2c2c40;
}
body.theme-night .search-input { color: var(--text); }
body.theme-night .search-input::placeholder { color: var(--text-muted); }
body.theme-night .search-filters,
body.theme-night .search-results {
  background: #1a1a26;
  border-color: var(--border);
}
body.theme-night .search-filter-select {
  background: #2a2a3a;
  color: var(--text);
  border-color: var(--border);
}
body.theme-night .search-filter-select option {
  background: #2a2a3a;
  color: var(--text);
}

body.theme-night .filter-select {
  background: #1a1a2e;
  color: #e8e8f0;
  border-color: rgba(255, 255, 255, 0.15);
}

body.theme-night .filter-select option {
  background: #1a1a2e;
  color: #e8e8f0;
}

body.theme-night .filter-done-btn {
  background: transparent;
  color: var(--accent);
  border-color: var(--accent);
}

body.theme-night .filter-done-btn:hover {
  background: var(--accent);
  color: #0a0a12;
}

body.theme-night .filter-header {
  border-bottom-color: rgba(255, 255, 255, 0.1);
}

body.theme-night .filter-controls {
  background: transparent;
}

body.theme-night .search-result-item { color: var(--text); }
body.theme-night .search-result-item:hover { background: var(--editorial-bg); }

/* Feedback modal — kept the structure intact, just swap surfaces. */
body.theme-night .feedback-modal-content,
body.theme-night #feedback-modal-content,
body.theme-night .feedback-modal-inner {
  background: #1a1a26;
  color: var(--text);
}
body.theme-night .feedback-modal textarea,
body.theme-night #feedback-text {
  background: #2a2a3a;
  color: var(--text);
  border-color: var(--border);
}
body.theme-night .feedback-cancel-btn {
  color: var(--text-muted);
  border-color: var(--border);
}

/* Pills / vibe items / kindred breakdown — most of these already
   reference --editorial-bg + --border + --text so they switch
   automatically. A few hardcoded values need an explicit override. */
body.theme-night .vibe-item.is-true .vibe-item-label { color: var(--text); }
body.theme-night .vibe-community-tag {
  background: var(--editorial-bg);
  color: var(--text);
  border-color: var(--border);
}
body.theme-night .pill {
  background: var(--editorial-bg);
  color: var(--text);
  border-color: var(--border);
}

/* Header buttons — light borders so they read against the dark header. */
body.theme-night #replay-narrative,
body.theme-night #about-btn,
body.theme-night #feedback-btn {
  border-color: rgba(255, 255, 255, 0.25);
  color: rgba(255, 255, 255, 0.75);
}
body.theme-night #replay-narrative:hover,
body.theme-night #about-btn:hover,
body.theme-night #feedback-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Map's "faded overlay" — when a place is selected the layer fades to
   30% white over the basemap. In night mode that lightens the dark
   map, which is the desired effect (selection still visually pops),
   so we leave the layer's color alone. No CSS change needed. */
