/* Scrollytelling intro overlay. Loads on first visit, skipped on return via
   localStorage flag set when the user clicks the CTA. */

#narrative-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 100;
  background: transparent;
  overflow-y: scroll;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  transition: opacity 0.8s ease;
  /* Hidden by default so return visitors (no `narrative-active` on body)
     don't see a transparent overlay briefly blocking map clicks. Shown
     either while the narrative is active or while it's mid-exit-fade. */
  display: none;
}
body.narrative-active #narrative-overlay,
#narrative-overlay.is-leaving {
  display: block;
}
#narrative-overlay.is-leaving {
  opacity: 0;
}

#narrative-scroll-container {
  position: relative;
  width: 100%;
  height: 100vh;
  pointer-events: none;
}

#narrative-skip {
  position: fixed;
  top: 16px;
  right: 16px;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.5);
  color: rgba(255,255,255,0.7);
  padding: 8px 20px;
  border-radius: 4px;
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  cursor: pointer;
  pointer-events: auto;
  transition: border-color 0.2s, color 0.2s;
  z-index: 40;
}
#narrative-skip:hover {
  border-color: rgba(255,255,255,0.9);
  color: #ffffff;
}

.narrative-step {
  position: absolute;
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.narrative-text {
  position: absolute;
  width: 100%;
  max-width: 680px;
  padding: 48px 56px;
  text-align: center;
  pointer-events: none;
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 32px;
  line-height: 1.35;
  color: #ffffff;
  text-shadow: 0 0 4px rgba(0,0,0,1), 0 0 8px rgba(0,0,0,1), 0 0 12px rgba(0,0,0,1);
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.8s ease, transform 0.8s ease;
  border-radius: 0;
  border: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.narrative-text.is-active {
  opacity: 1;
  transform: translateY(0);
}

.narrative-text p {
  margin: 0 0 18px;
  text-shadow: 0 0 4px rgba(0,0,0,1), 0 0 8px rgba(0,0,0,1), 0 0 12px rgba(0,0,0,1);
}
.narrative-text p:last-child {
  margin-bottom: 0;
}

.narrative-sub {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 18px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.85);
  font-weight: 400;
  text-shadow: 0 0 4px rgba(0,0,0,1), 0 0 8px rgba(0,0,0,1), 0 0 12px rgba(0,0,0,1);
}

.narrative-text blockquote {
  font-family: 'Playfair Display', Georgia, serif;
  font-style: italic;
  font-size: 28px;
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.92);
  margin: 0 0 8px;
  padding: 0;
  quotes: none;
  text-shadow: 0 0 4px rgba(0,0,0,1), 0 0 8px rgba(0,0,0,1), 0 0 12px rgba(0,0,0,1);
}
.narrative-text blockquote::before,
.narrative-text blockquote::after {
  content: none;
}

.narrative-text cite {
  display: block;
  margin-top: 12px;
  margin-bottom: 28px;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-style: normal;
  font-size: 14px;
  letter-spacing: 0.05em;
  color: rgba(255, 255, 255, 0.9);
  text-shadow: 0 0 4px rgba(0,0,0,1), 0 0 8px rgba(0,0,0,1), 0 0 12px rgba(0,0,0,1);
}

.narrative-count {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 42px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: #ffffff;
  margin-bottom: 18px !important;
  text-shadow: 0 0 4px rgba(0,0,0,1), 0 0 8px rgba(0,0,0,1), 0 0 12px rgba(0,0,0,1);
}

#narrative-cta {
  pointer-events: auto;
  display: inline-block;
  margin-top: 32px;
  padding: 16px 48px;
  background: #ffffff;
  color: #2b2b2b;
  border: none;
  border-radius: 4px;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.6s ease, transform 0.2s ease, background-color 0.2s ease;
}
#narrative-cta.is-visible {
  opacity: 1;
}
#narrative-cta:hover {
  background: #f3f3f3;
  transform: translateY(-1px);
}
#narrative-cta:active {
  transform: translateY(0);
}

/* Hero place card in step 4 — separate fixed element so the camera reframe
   doesn't push it around with the step layout. */
#narrative-place-card {
  position: fixed;
  bottom: 80px;
  left: 40px;
  max-width: 360px;
  background: rgba(0, 0, 0, 0.7);
  color: #ffffff;
  padding: 24px;
  border-radius: 8px;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.5s ease, transform 0.5s ease;
  z-index: 101;
  pointer-events: none;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}
#narrative-place-card.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.narrative-place-name {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 22px;
  font-weight: 700;
  line-height: 1.15;
  margin-bottom: 10px;
}
.narrative-place-soul {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.92);
}

/* Hide the main-experience chrome while the narrative is running so the
   overlay reads as cinematic. Restored when the user clicks the CTA.
   Transition lives on the base selector so it fires in BOTH directions
   (fade out when class is added, fade back in when class is removed). */
.app-header,
.legend {
  transition: opacity 0.4s ease;
}
body.narrative-active .app-header,
body.narrative-active .legend {
  opacity: 0;
  pointer-events: none;
}

/* Narrative needs the map to stay visible behind the scrolling overlay.
   Keep the original absolute positioning — fixed/absolute both stay parked
   on the viewport because the overlay handles its own scroll. */

/* Floating tooltip for the Beat 3 constellation interaction. Positioned
   in JS at cursor location; CSS just handles look + fade. */
#constellation-tooltip {
  position: fixed;
  pointer-events: none;
  background: rgba(0, 0, 0, 0.7);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: #ffffff;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 13px;
  padding: 6px 12px;
  border-radius: 4px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  opacity: 0;
  transition: opacity 0.15s ease;
  z-index: 200;
  white-space: nowrap;
}
#constellation-tooltip.is-visible {
  opacity: 1;
}

/* --- 9-beat right-side cards (Beats 4-8) ---
   Two stacked cards on the right edge. The kindred card sits at the same
   bottom offset as the place card; when both are present, the place card
   gets .is-slid-up to translate it 180px upward so the kindred card
   appears beneath it without overlap. */

#narrative-right-card {
  position: fixed;
  right: 24px;
  bottom: 120px;
  max-width: 320px;
  background: rgba(0, 0, 0, 0.75);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  color: #ffffff;
  padding: 20px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  z-index: 101;
  pointer-events: none;
  opacity: 0;
  transform: translateX(120%);
  transition: transform 0.4s ease, opacity 0.4s ease;
}
#narrative-right-card.is-visible {
  opacity: 1;
  transform: translateX(0);
  /* Restore hit-testing only once the card is on-screen — the base rule
     keeps it off so the off-screen translateX(120%) state doesn't eat
     map clicks at the right edge of the viewport. */
  pointer-events: auto;
}
#narrative-right-card.is-slid-up {
  /* Apply alongside .is-visible — combines with translateX(0) into a
     compound translate. Fixed -180px offset matches the typical kindred
     card height (it'll vary slightly by content, but this looks clean
     across the place name + 14px soul summary range). */
  transform: translate(0, -300px);
}

#narrative-kindred-card {
  position: fixed;
  right: 24px;
  bottom: 120px;
  width: 320px;
  background: rgba(0, 0, 0, 0.75);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  color: #ffffff;
  padding: 20px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  z-index: 101;
  pointer-events: none;
  opacity: 0;
  /* 200ms delay before fade so the place card has a beat to slide up
     first — feels like the kindred card emerges from beneath it. */
  transition: opacity 0.5s ease 0.2s;
}
#narrative-kindred-card.is-visible {
  opacity: 1;
  /* Restore hit-testing only once the card is on-screen — same reasoning
     as #narrative-right-card.is-visible. Without this the kindred items
     receive no clicks and beat-advance fires through them. */
  pointer-events: auto;
}

.narrative-place-name {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.15;
  margin-bottom: 8px;
}
.narrative-place-soul {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.9);
}

.narrative-kindred-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.narrative-kindred-title {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.5);
}
/* Pulses + glows only when the .is-pulsing class is on the title —
   Beat 5 sets it on the "LGBTQ+ Welcoming" header to call out the new
   side panel. Beats 6/7 reuse the kindred card with the default
   "Kindred Places" title and no pulse, so attention can shift to the
   Web active button. Same easing and dual-shadow technique as
   .narrative-web-badge.is-active but in a softer warm cream so the
   two pulses don't compete when they're both visible. */
/* Beat 5 only — the "LGBTQ+ Welcoming" title is wrapped in a warm-
   gold pill so it reads as a tag/identity badge rather than just a
   section heading. The pill background + border animate in the same
   keyframes as the text glow, so the whole pill breathes together. */
.narrative-kindred-title.is-pulsing {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 240, 180, 0.25);
  background: rgba(255, 240, 180, 0.05);
  animation: kindred-title-pulse 2.4s ease-in-out infinite;
}
@keyframes kindred-title-pulse {
  0%, 100% {
    color: rgba(255, 255, 255, 0.55);
    text-shadow: 0 0 4px rgba(255, 240, 180, 0.2);
    background: rgba(255, 240, 180, 0.05);
    border-color: rgba(255, 240, 180, 0.25);
  }
  50% {
    color: rgba(255, 247, 200, 0.95);
    text-shadow:
      0 0 10px rgba(255, 240, 180, 0.7),
      0 0 18px rgba(255, 240, 180, 0.4);
    background: rgba(255, 240, 180, 0.18);
    border-color: rgba(255, 240, 180, 0.55);
  }
}
/* Respect reduced-motion preference — drop the pulse but keep a
   slightly brighter mid-state so the title still reads as "alive"
   while it has .is-pulsing. The pill background/border stay visible. */
@media (prefers-reduced-motion: reduce) {
  .narrative-kindred-title.is-pulsing {
    animation: none;
    color: rgba(255, 247, 200, 0.9);
    background: rgba(255, 240, 180, 0.12);
    border-color: rgba(255, 240, 180, 0.4);
  }
}
.narrative-web-badge {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 11px;
  color: #ffe066;
  opacity: 0;
  /* Inert until Beat 7 activates the web — without this, a stray
     hover over the (invisible) button area would trigger the :hover
     rule below and reveal the button at 0.8 opacity. .is-visible
     restores pointer-events: auto so the toggle becomes clickable
     once the narrative actually surfaces it. */
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.narrative-web-badge.is-visible {
  opacity: 1;
  pointer-events: auto;
}
/* Web badge is rendered as a <button> from Beat 7 onward so it can toggle
   the second-tier arcs on/off. Strip the browser defaults so it visually
   matches the original span. */
button.narrative-web-badge {
  background: transparent;
  border: none;
  font: inherit;
  cursor: pointer;
  padding: 0;
}
button.narrative-web-badge:hover {
  opacity: 0.8;
}
/* While the web is active, "◎ Web active" is wrapped in a warm-gold
   pill that pulses in sync with the text glow — matches the LGBTQ+
   Welcoming pill treatment in Beat 5 but in the bolder gold palette.
   The pill chassis (padding, radius, base border/background) lives on
   the static rule; the keyframes drive color + text-shadow + background
   + border-color together so the whole pill breathes. When the user
   toggles the web off (.is-active removed), the underlying
   button.narrative-web-badge rule re-wins (background: transparent,
   border: none, padding: 0) and the button reverts to plain text. */
.narrative-web-badge.is-active {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 224, 102, 0.3);
  background: rgba(255, 224, 102, 0.08);
  animation: web-active-pulse 1.6s ease-in-out infinite;
}
@keyframes web-active-pulse {
  0%, 100% {
    color: #ffe066;
    text-shadow: 0 0 4px rgba(255, 224, 102, 0.5);
    background: rgba(255, 224, 102, 0.08);
    border-color: rgba(255, 224, 102, 0.3);
  }
  50% {
    color: #fff7c0;
    text-shadow:
      0 0 14px rgba(255, 224, 102, 0.95),
      0 0 22px rgba(255, 224, 102, 0.55);
    background: rgba(255, 224, 102, 0.22);
    border-color: rgba(255, 224, 102, 0.7);
  }
}
/* Reduced-motion: drop the pulse but keep a static mid-intensity pill
   so it still reads as the "alive" state vs. the plain "Web off" text. */
@media (prefers-reduced-motion: reduce) {
  .narrative-web-badge.is-active {
    animation: none;
    color: #fff7c0;
    background: rgba(255, 224, 102, 0.18);
    border-color: rgba(255, 224, 102, 0.55);
  }
}
.narrative-kindred-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 6px;
  margin: 0 -6px;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.85);
  cursor: default;
  border-radius: 4px;
  transition: background 0.15s;
}
/* Items rendered with a data-place-id are wired up by
   attachKindredCardInteraction — clicking re-centers the map and updates
   the right-side place card. */
.narrative-kindred-item[data-place-id] {
  cursor: pointer;
}
.narrative-kindred-item[data-place-id]:hover {
  background: rgba(255, 255, 255, 0.1);
}
.narrative-kindred-item.is-selected {
  background: rgba(255, 249, 196, 0.15);
}
.narrative-kindred-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

@media (max-width: 640px) {
  .narrative-text {
    font-size: 24px;
    padding: 32px 24px;
  }
  .narrative-sub { font-size: 16px; }
  .narrative-text blockquote { font-size: 22px; }
  .narrative-count { font-size: 32px; }
  #narrative-place-card {
    left: 16px;
    right: 16px;
    bottom: 24px;
    max-width: none;
  }
  /* Beat-4+ right-side place card — full-width strip along the bottom
     on phones, same pattern as #narrative-place-card. */
  #narrative-right-card {
    left: 16px;
    right: 16px;
    bottom: 80px;
    max-width: none;
  }
  /* Kindred card is hidden entirely on small screens — there isn't room
     for it stacked beneath the place card. */
  #narrative-kindred-card {
    display: none;
  }
}
