html, body {
  height: 100%;
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

#topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: calc(1em + 20px);
  line-height: calc(1em + 20px);
  background: #0a1f44;
  /* Above the story bar, so its menus open over it. */
  z-index: 30;
  display: flex;
  align-items: center;
}

#topbar-content {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  color: #fff;
}

.topbar-name {
  font-weight: 600;
  margin-right: auto;
}

.topbar-link {
  appearance: none;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.5);
  color: #fff;
  border-radius: 4px;
  padding: 2px 10px;
  font-size: 13px;
  line-height: 1.6;
  cursor: pointer;
}

.topbar-link:hover {
  background: rgba(255, 255, 255, 0.1);
}

#map {
  position: absolute;
  top: calc(1em + 20px);
  left: 0;
  right: 0;
  bottom: 0;
}

.story-marker {
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  /* Deliberately NOT position:relative — MapLibre applies its own
     positioning transform directly to this element (it's what you pass as
     a Marker's `element`), and overriding its position here breaks that,
     blowing this box up to the full map width. The badge below anchors to
     .story-marker-thumb instead, which MapLibre never touches. */
}

/* Shown on a marker representing 2+ stories piled on the same location —
   click it to spiderfy (app.js's spiderfy()) instead of opening a story
   directly. Anchored to .story-marker-thumb (below), not .story-marker
   itself — see the comment above. */
.story-marker-count-badge {
  position: absolute;
  bottom: -6px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  line-height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: #0a1f44;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  text-align: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

/* Replaces a piled marker while it's spiderfied — click it to collapse
   back to the single badged marker. */
.spider-center-marker {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #0a1f44;
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
  cursor: pointer;
}

/* Full-viewport overlay for the thin connector lines drawn from a
   spiderfied pile's shared point out to each of its leg markers. Sits
   above the map/markers but below the topbar and any modal panel. */
#pile-connector-svg {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 15;
}

.pile-connector-line {
  stroke: #fff;
  stroke-width: 1.5px;
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.6));
}

/* "Show Connected To" lasso lines — see connections.js. Same overlay SVG
   as the spiderfy connector lines above, distinguished by color/weight. */
.lasso-connector-line {
  stroke: #d90000;
  stroke-width: 2px;
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.5));
}





.connections-checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-size: 12px;
  padding: 3px 0;
  cursor: pointer;
}

.connections-checkbox-row input {
  margin-top: 2px;
}

.story-marker-headline {
  max-width: 100px;
  font-size: 11px;
  font-weight: 600;
  text-align: center;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 4px;
  padding: 2px 4px;
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.story-marker-thumb {
  width: 56px;
  height: 56px;
  border-radius: 8px;
  object-fit: cover;
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
  position: relative; /* anchors .story-marker-count-badge, safe here (unlike .story-marker) */
}

.story-marker-video-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #333;
  color: #fff;
  font-size: 20px;
}

.story-marker-live-thumb {
  background: #000;
}

.story-marker-live-tag {
  color: #e60000;
  font-weight: 800;
}

#detail-panel {
  position: fixed;
  top: 5%;
  left: 50%;
  transform: translateX(-50%);
  width: min(600px, 90vw);
  /* `vh` on mobile browsers is measured against the "large" viewport —
     the page's size as if the browser's own address/nav bar were already
     hidden — even while that bar is actually still showing on screen.
     That's what let the panel's true bottom edge (and the buffer padding
     below) end up rendered underneath the browser's own chrome rather
     than genuinely visible. `dvh` (dynamic viewport height) tracks the
     real, currently-visible viewport instead, shrinking to match when the
     browser bar is present; declared second so it overrides the `vh`
     fallback in every browser that supports it (all current ones), while
     older browsers that don't recognize `dvh` simply keep the line above. */
  max-height: 85vh;
  max-height: 85dvh;
  overflow-y: auto;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
  /* Extra bottom padding (vs. the 24px on every other side) so at least
     ~2 lines of clear space (.detail-body is 16px/1.5 line-height = 24px
     per line) always shows below the last piece of content — text,
     gallery, video, or audio — instead of it butting right up against the
     panel's edge, which read as "cut off" even though the panel already
     scrolls (overflow-y: auto). */
  padding: 24px 24px 72px;
  z-index: 20;
}

#detail-panel.hidden {
  display: none;
}

#detail-close {
  position: absolute;
  top: 12px;
  right: 16px;
  border: none;
  background: none;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  color: #333;
}

.detail-headline {
  font-size: 28px;
  font-weight: 800;
  margin: 0 32px 4px 0;
}

.detail-live-tag {
  color: #e60000;
}

.detail-date {
  color: #666;
  font-size: 13px;
  margin-bottom: 16px;
}

.detail-byline {
  text-align: left;
  color: #666;
  font-size: 12px;
  line-height: 1.6;
  margin-bottom: 16px;
}

.detail-author {
  color: #333;
  font-weight: 600;
  margin-top: 4px;
}

.detail-last-edited-link {
  color: #666;
  text-decoration: underline;
  cursor: pointer;
}

.history-list {
  list-style: none;
  padding: 0;
  margin: 16px 0;
  font-size: 14px;
  color: #333;
}

.history-list li {
  padding: 8px 0;
  border-bottom: 1px solid #eee;
}

.history-back {
  display: inline-block;
  font-size: 14px;
  color: #0a1f44;
  text-decoration: none;
  cursor: pointer;
}

.detail-body {
  font-size: 16px;
  line-height: 1.5;
  white-space: pre-wrap;
}

.detail-gallery {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  margin: 16px 0;
}

.detail-gallery img {
  height: 200px;
  border-radius: 6px;
  object-fit: cover;
  cursor: zoom-in;
}

/* Photos placed inline in the story text — full width of the panel, click
   for full size (see openImageViewer in app.js). */
.detail-inline-image {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: 6px;
  margin: 8px 0;
  cursor: zoom-in;
}

/* A photo with its credit line underneath (addPhotoCredits in app.js). */
.detail-photo {
  margin: 8px 0;
}
.detail-photo .detail-inline-image {
  margin: 0;
}
.detail-photo-credit {
  font-size: 12px;
  color: #666;
  margin-top: 4px;
  line-height: 1.35;
}

.detail-media-caption {
  font-size: 14px;
  font-weight: 600;
  margin-top: 8px;
  white-space: normal;
}

/* Audio, video, and documents placed inline in the story text — the
   browser's own standard players/links, just sized to the panel. */
.detail-body audio {
  display: block;
  width: 100%;
  margin: 8px 0;
}

.detail-body video {
  display: block;
  width: 100%;
  max-height: 70vh;
  border-radius: 6px;
  background: #000;
  margin: 8px 0;
}

.detail-body a[href^="/uploads/inline/"] {
  display: inline-block;
  padding: 10px 14px;
  margin: 4px 0;
  border: 1px solid #d0d7e2;
  border-radius: 8px;
  background: #f5f7fb;
  color: #0a1f44;
  text-decoration: none;
  font-size: 14px;
  white-space: normal;
}

.detail-body a[href^="/uploads/inline/"]::before {
  content: "📄 ";
}

.detail-documents {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 16px;
}

.detail-documents a {
  color: #0a1f44;
  font-size: 14px;
}

.image-viewer {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(0, 0, 0, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: zoom-out;
}

.image-viewer img {
  max-width: 100vw;
  max-height: 100dvh;
  object-fit: contain;
}

.detail-video {
  width: 100%;
  border-radius: 6px;
  margin-top: 16px;
}

.detail-audio {
  width: 100%;
  margin-top: 16px;
}

#auth-panel,
#profile-panel {
  position: fixed;
  top: 5%;
  left: 50%;
  transform: translateX(-50%);
  width: min(400px, 90vw);
  max-height: 85vh;
  overflow-y: auto;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
  padding: 24px;
  z-index: 20;
}

#auth-panel.hidden,
#profile-panel.hidden {
  display: none;
}

#auth-close,
#profile-close {
  position: absolute;
  top: 12px;
  right: 16px;
  border: none;
  background: none;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  color: #333;
}

.auth-heading {
  font-size: 22px;
  font-weight: 800;
  margin: 0 32px 16px 0;
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.auth-input {
  padding: 8px 10px;
  border: 1px solid #ccc;
  border-radius: 6px;
  font-size: 15px;
}

.auth-error {
  color: #c00;
  font-size: 13px;
  min-height: 1em;
}

.auth-submit {
  appearance: none;
  border: none;
  background: #0a1f44;
  color: #fff;
  border-radius: 6px;
  padding: 10px;
  font-size: 15px;
  cursor: pointer;
}

.auth-submit:disabled {
  opacity: 0.6;
  cursor: default;
}

.profile-meta {
  color: #666;
  font-size: 13px;
  margin-bottom: 16px;
}

.profile-privileges {
  margin: 0 0 16px;
  padding-left: 20px;
  font-size: 14px;
}

.profile-stories {
  list-style: none;
  padding: 0;
  margin: 0;
}

.profile-stories li {
  padding: 10px 0;
  border-bottom: 1px solid #eee;
}

.profile-stories a {
  font-weight: 600;
  color: #0a1f44;
  text-decoration: none;
}

.profile-story-dates {
  font-size: 12px;
  color: #666;
  margin-top: 2px;
}

/* The Filters menu (filters.js), under the Filters button in the search box. */
#view-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 340px;
  max-height: 70vh;
  overflow-y: auto;
  background: #fff;
  color: #222;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
  padding: 10px;
  z-index: 20;
  line-height: 1.4;
}

#view-dropdown.hidden {
  display: none;
}

.view-select-row {
  display: flex;
  gap: 6px;
  margin: 10px 0 6px;
}

.view-small-button {
  font-size: 12px;
  padding: 3px 8px;
  border: 1px solid #b8c2d6;
  border-radius: 4px;
  background: #f3f5fa;
  color: #0a1f44;
  cursor: pointer;
}

/* One filter / search step (filters.js); each later step searches within
   the results above it. */
.view-step {
  border: 1px solid #dfe4ee;
  border-radius: 6px;
  padding: 8px;
  margin-bottom: 8px;
  background: #fafbfd;
}

.view-step-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-bottom: 4px;
}

/* How a filter joins the ones above it: with / without, AND / OR / NOT. */
.view-step-op {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  font-weight: 700;
  color: #0a1f44;
  border: 1px solid #c9d1e0;
  border-radius: 5px;
  padding: 3px 4px;
  background: #fff;
}

.view-step-remove {
  border: none;
  background: none;
  color: #8a93a6;
  font-size: 15px;
  line-height: 1;
  padding: 2px 4px;
  cursor: pointer;
}

.view-step-remove:hover {
  color: #c0392b;
}

.view-step-field,
.view-step-words,
.view-step-where,
.view-step-type {
  width: 100%;
  box-sizing: border-box;
  font-size: 13px;
  padding: 4px;
}

/* Words: where to look; Name: the type. Each sits above its box. */
.view-step-where,
.view-step-type {
  margin-bottom: 4px;
}

.view-step-value {
  margin-top: 6px;
}

.view-step-value .view-select-row {
  margin: 0 0 4px;
}

.view-step-dates {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
  font-size: 12px;
}

.view-step-empty {
  font-size: 12px;
  color: #8a93a6;
}

.view-step-count {
  font-size: 11px;
  color: #2459d6;
  margin-top: 4px;
}

.view-step-count:empty {
  display: none;
}

.view-add-step {
  width: 100%;
  font-size: 13px;
  font-weight: 600;
  padding: 6px;
  border: 1px dashed #9fb0d0;
  border-radius: 6px;
  background: #fff;
  color: #2459d6;
  cursor: pointer;
}

.view-summary {
  font-size: 11px;
  color: #5d6677;
  margin: 8px 0 0;
}

/* While a story is open, other stories' pins and groups (app.js,
   applyStoryVisibility; Map View sets which). The map library sets each
   marker's opacity inline, so these must win. */
.pin-hidden {
  display: none !important;
}

.pin-faded {
  opacity: 0.3 !important;
}

#focus-bar {
  position: fixed;
  top: calc(1em + 28px);
  left: 50%;
  transform: translateX(-50%);
  max-width: min(640px, calc(100vw - 32px));
  display: flex;
  flex-direction: column;
  background: #0a1f44;
  color: #fff;
  border-radius: 999px;
  padding: 6px 8px 6px 16px;
  font-size: 13px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
  z-index: 15;
}

#focus-bar.hidden {
  display: none;
}

#focus-bar-text {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.focus-bar-button {
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.6);
  background: transparent;
  color: #fff;
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 12px;
  cursor: pointer;
}

.focus-pin-wrap {
  /* No position here (2026-10-08): this is a MapLibre marker element, which
     the library positions itself (absolute). "position: relative" put each
     event's pin in normal flow, so pin 2 was drawn 28 px below its real spot,
     pin 3 56 px, and so on (same lesson as .story-marker above). */
  width: 28px;
  height: 28px;
}

.focus-pin {
  position: relative;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  /* The event's own color (story-focus.js). */
  background: var(--ev, #2459d6);
  color: #fff;
  font: 700 13px/28px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  text-align: center;
  border: 2px solid #fff;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
  box-sizing: border-box;
  z-index: 2;
}


/* Approximate place: a soft circle, never a sharp point. */
.focus-halo {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
  border-radius: 50%;
  background: rgba(204, 51, 51, 0.12);
  border: 1px dashed rgba(204, 51, 51, 0.6);
  z-index: 1;
}

/* The bubbles' own layer over the map; story-focus.js places each one. */
.focus-bubble-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}

.focus-label {
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: auto;
  width: max-content;
  max-width: min(220px, 60vw);
  max-height: 45vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: rgba(255, 255, 255, 0.86);
  color: #172033;
  border-radius: 8px;
  padding: 6px 8px;
  font: 12px/1.35 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.3);
  z-index: 3;
}

.focus-label.raised {
  z-index: 4;
  background: rgba(255, 255, 255, 0.97);
}

.focus-label-title {
  font-weight: 700;
}

/* The pin's number, in the pin's color, at the start of its bubble. */
.focus-label-number {
  display: inline-block;
  min-width: 18px;
  height: 18px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--ev, #2459d6);
  color: #fff;
  font-size: 11px;
  line-height: 18px;
  text-align: center;
  vertical-align: 1px;
}



.focus-label-mention {
  color: #5b6472;
  font-style: italic;
  margin-top: 1px;
}

.focus-label-time {
  color: #2459d6;
  font-weight: 600;
  margin-top: 2px;
}

.focus-label-names {
  margin-top: 4px;
  color: #3b4456;
}

.focus-more {
  margin-top: 2px;
  border: none;
  background: none;
  color: #2459d6;
  padding: 0;
  font-size: 12px;
  cursor: pointer;
}



/* Short button text on small screens (see index.html). */
.label-short {
  display: none;
}

/* Phones and narrow windows: compact top bar, menus as full-width panels
   just below it (fit.js still checks they fit the visible screen). */
@media (max-width: 640px) {
  #topbar-content {
    gap: 6px;
    padding: 0 8px;
  }

  .topbar-link {
    padding: 2px 7px;
    font-size: 12px;
  }


  .label-long {
    display: none;
  }

  .label-short {
    display: inline;
  }

  #view-dropdown {
    position: fixed;
    top: calc(1em + 26px);
    left: 8px;
    right: 8px;
    width: auto;
    max-height: calc(var(--vvh, 100dvh) - 1em - 44px);
    -webkit-overflow-scrolling: touch;
  }

  #focus-bar {
    font-size: 12px;
  }
}

/* The base map's color grade (owner, 2026-10-01): 75% saturation, 80%
   brightness. Only the map image itself — pins, labels, the event line
   (its own layer, .focus-line-layer), menus, and panels are untouched. */
.maplibregl-canvas {
  filter: saturate(0.75) brightness(0.8);
}

.focus-line-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}

/* Annotation red (75% saturation, 80% brightness), full strength. */
.focus-line {
  fill: none;
  stroke: #cc3333;
  stroke-width: 3;
  stroke-dasharray: 8 6;
  stroke-linecap: round;
}

.focus-bar-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* Desktop: the list and its collapse button are phone-only. */
#focus-list,
#focus-collapse {
  display: none;
}

/* Phones: the story bar becomes a bottom panel listing the events. */
#focus-bar.compact {
  top: auto;
  left: 8px;
  right: 8px;
  transform: none;
  max-width: none;
  border-radius: 14px;
  padding: 0;
  overflow: hidden;
}

#focus-bar.compact .focus-bar-row {
  padding: 8px 8px 8px 14px;
}

#focus-bar.compact #focus-collapse {
  display: inline-block;
}

#focus-bar.compact #focus-list {
  display: block;
  background: #fff;
  color: #172033;
  max-height: calc(var(--vvh, 100vh) * 0.35);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

#focus-bar.compact.collapsed #focus-list {
  display: none;
}

#focus-bar.compact.collapsed #focus-collapse {
  transform: rotate(180deg);
}

.focus-list-item {
  position: relative;
  padding: 8px 12px 8px 44px;
  border-top: 1px solid #e3e7ef;
  font: 13px/1.35 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  cursor: pointer;
}

.focus-list-item.selected {
  background: #fdecec;
}

.focus-list-number {
  position: absolute;
  left: 10px;
  top: 8px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--ev, #2459d6);
  color: #fff;
  font-weight: 700;
  font-size: 12px;
  line-height: 24px;
  text-align: center;
}


/* Size limits include padding and border, so a menu capped to the screen
   (fit.js) really ends inside it. */
#view-dropdown,
#focus-bar,
.focus-label {
  box-sizing: border-box;
}

/* ===================================================================
   Reader map Phase 1 (2026-10-04): header with search, filter chips,
   results list, split story view, new pins and groups, quick preview.
   These rules come last and take over from the older ones above.
   =================================================================== */

:root {
  --topbar-h: 56px;
  --chips-h: 0px;
  /* News sections row: at most half the header's height (owner, 2026-10-06). */
  --sections-h: 28px;
  --map-top: calc(var(--topbar-h) + var(--sections-h) + var(--chips-h));
  --side-w: 360px;
  --story-w: min(50vw, 680px);
  --ink: #1d2433;
  --muted: #5d6677;
  --line: #e3e7ef;
  --accent: #2459d6;
}

/* Worked out on body (not :root) so it picks up the chips row's height. */
body {
  --map-top: calc(var(--topbar-h) + var(--sections-h) + var(--chips-h));
}

body.has-chips {
  --chips-h: 44px;
}

#topbar {
  height: var(--topbar-h);
  line-height: normal;
  padding: 0 12px;
  gap: 14px;
}

#topbar-brand {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: #fff;
  white-space: nowrap;
  flex-shrink: 0;
}

.brand-name {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: 0.2px;
}

.brand-rev {
  font-size: 11px;
  font-weight: 700;
  color: #0a1f44;
  background: #ffd166;
  border-radius: 999px;
  padding: 1px 8px;
}

#search-wrap {
  position: relative;
  flex: 1;
  max-width: 600px;
  margin: 0 auto;
}

#search-box {
  width: 100%;
  box-sizing: border-box;
  height: 38px;
  border: none;
  border-radius: 19px;
  padding: 0 112px 0 38px; /* room for "/" and the Filters button */
  font-size: 15px;
  color: var(--ink);
  background: #fff;
  outline: none;
}

#search-box:focus {
  box-shadow: 0 0 0 3px rgba(255, 209, 102, 0.8);
}

.search-icon {
  position: absolute;
  left: 13px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 14px;
  opacity: 0.55;
  pointer-events: none;
}

.search-key {
  position: absolute;
  right: 106px;
  top: 50%;
  transform: translateY(-50%);
  font: 600 11px/1 -apple-system, sans-serif;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 3px 6px;
  pointer-events: none;
}

#search-box:focus ~ .search-key,
#search-box:not(:placeholder-shown) ~ .search-key {
  display: none;
}

#search-suggestions {
  position: absolute;
  top: 44px;
  left: 0;
  right: 0;
  max-height: min(70vh, 520px);
  overflow-y: auto;
  background: #fff;
  color: var(--ink);
  border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.3);
  padding: 6px 0;
  z-index: 45;
}

#search-suggestions.hidden {
  display: none;
}

.suggestion-header {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--muted);
  padding: 10px 14px 4px;
}

.suggestion {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  font-size: 14px;
  cursor: pointer;
}

.suggestion.active,
.suggestion:hover {
  background: #eef3ff;
}

.suggestion-icon {
  width: 20px;
  text-align: center;
  flex-shrink: 0;
}

.suggestion-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.suggestion-search .suggestion-label {
  font-weight: 600;
}

.suggestion-detail {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}

#topbar-tools {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

#topbar-tools .topbar-link {
  text-decoration: none;
  white-space: nowrap;
}

#topbar-content {
  flex: 0 0 auto;
  padding: 0;
  gap: 8px;
}

#topbar-content:empty {
  display: none;
}

#view-dropdown {
  top: calc(100% + 10px);
}

.connections-type-heading {
  margin: 10px 0 2px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #2459d6;
}

.connections-type-heading:first-child {
  margin-top: 4px;
}

.connections-intro {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 6px;
}


/* Active filters, under the header. */
#chips-bar {
  position: fixed;
  top: calc(var(--topbar-h) + var(--sections-h));
  left: 0;
  right: 0;
  height: var(--chips-h);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  overflow-x: auto;
  background: #fff;
  border-bottom: 1px solid var(--line);
  z-index: 26;
  scrollbar-width: none;
}

#chips-bar.hidden {
  display: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  border: 1px solid #c9d6f2;
  background: #eef3ff;
  border-radius: 999px;
  font-size: 13px;
  color: #13306b;
}

.chip-label,
.chip-remove,
.chip-action {
  appearance: none;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.chip-label {
  padding: 5px 4px 5px 12px;
  white-space: nowrap;
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chip-remove {
  padding: 5px 10px 5px 6px;
  font-size: 12px;
  color: #5d6f99;
}

.chip-remove:hover {
  color: #c0392b;
}

.chip-action {
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  padding: 5px 8px;
  white-space: nowrap;
}

.chip-clear {
  color: var(--muted);
}

#map {
  top: var(--map-top);
}

/* The results list. */
#results-panel {
  position: fixed;
  top: var(--map-top);
  left: 0;
  bottom: 0;
  width: var(--side-w);
  display: flex;
  flex-direction: column;
  background: #fff;
  color: var(--ink);
  box-shadow: 2px 0 12px rgba(0, 0, 0, 0.18);
  z-index: 20;
  transition: width 0.2s ease, height 0.2s ease;
}

#results-panel.collapsed {
  bottom: auto;
  width: auto;
  border-radius: 0 0 10px 0;
}

#results-panel.collapsed #results-list,
#results-panel.collapsed .results-sort {
  display: none;
}

body.story-open #results-panel {
  display: none;
}

#results-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
}

#results-toggle {
  appearance: none;
  border: none;
  background: none;
  font: 700 14px/1.2 -apple-system, sans-serif;
  color: var(--ink);
  cursor: pointer;
  padding: 2px 0;
}

#results-panel.collapsed .results-caret {
  display: inline-block;
  transform: rotate(-90deg);
}

.results-sort {
  font-size: 12px;
  color: var(--muted);
}

.results-sort select {
  font-size: 12px;
  margin-left: 4px;
}

#results-list {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.result-row {
  display: block;
  width: 100%;
  text-align: left;
  appearance: none;
  background: #fff;
  border: none;
  border-bottom: 1px solid var(--line);
  border-left: 4px solid var(--cat, #888);
  padding: 12px 14px 12px 12px;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.result-row:hover,
.result-row:focus {
  background: #f5f8ff;
  outline: none;
}

.result-headline {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
}

.result-live {
  color: #e60000;
  font-size: 11px;
  font-weight: 800;
  margin-right: 6px;
}

.result-meta,
.result-names,
.result-connected,
.result-noplace {
  font-size: 12px;
  color: var(--muted);
  margin-top: 4px;
}

.result-names {
  color: #33415c;
}

.result-connected {
  color: var(--accent);
}

.results-empty {
  padding: 18px 14px;
}

.results-empty-title {
  font-weight: 700;
  margin-bottom: 10px;
}

.results-empty-action {
  display: block;
  width: 100%;
  text-align: left;
  appearance: none;
  border: 1px solid var(--line);
  background: #f8fafd;
  border-radius: 8px;
  padding: 9px 12px;
  margin-bottom: 8px;
  font-size: 13px;
  color: var(--accent);
  cursor: pointer;
}

/* Opening a story: the story on the left, its place on the map on the right. */
#detail-panel {
  top: var(--map-top);
  left: 0;
  bottom: 0;
  transform: none;
  width: var(--story-w);
  max-height: none;
  border-radius: 0;
  box-shadow: 4px 0 16px rgba(0, 0, 0, 0.22);
  z-index: 22;
  box-sizing: border-box;
}

body.story-open #focus-bar {
  left: calc(var(--story-w) + (100vw - var(--story-w)) / 2);
  max-width: calc(100vw - var(--story-w) - 32px);
}

#focus-bar {
  top: calc(var(--map-top) + 10px);
}

/* Pins. */
.story-marker {
  align-items: center;
}

.story-marker-thumb {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 2px solid #fff;
  box-sizing: border-box;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
  transition: transform 0.15s ease;
}

.story-marker-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cat, #5b6b85);
  color: #fff;
  font-size: 15px;
  line-height: 1;
}

.story-marker-photo {
  border: 3px solid var(--cat, #5b6b85);
}

/* The headline floats just above the pin (2026-10-08), out of the pin's own
   box: when it was part of the box, showing it (hover, or zoomed in) made the
   box taller, and since the map centers the box on the story's spot, the
   icon slid down off that spot. The marker element itself is positioned by
   MapLibre (absolute), so it anchors this label without any position rule
   of its own. */
.story-marker-headline {
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  max-width: 160px;
  font-size: 12px;
  color: var(--ink);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
  margin-bottom: 0;
  pointer-events: none;
}

#map.show-labels .story-marker-headline,
.story-marker.pin-highlight .story-marker-headline {
  display: block;
}

.story-marker:hover .story-marker-thumb,
.story-marker:focus .story-marker-thumb,
.story-marker.pin-highlight .story-marker-thumb {
  transform: scale(1.25);
}

.story-marker.pin-highlight {
  z-index: 5;
}

.story-marker.pin-old .story-marker-thumb {
  opacity: 0.6;
}

.story-marker.pin-fresh .story-marker-thumb {
  animation: pin-pulse 1.8s ease-out infinite;
}

.story-marker.pin-live .story-marker-thumb {
  background: #e60000;
  animation: pin-pulse-live 1.4s ease-out infinite;
}

@keyframes pin-pulse {
  0% { box-shadow: 0 0 0 0 var(--cat, #2459d6), 0 2px 6px rgba(0, 0, 0, 0.45); }
  100% { box-shadow: 0 0 0 12px transparent, 0 2px 6px rgba(0, 0, 0, 0.45); }
}

@keyframes pin-pulse-live {
  0% { box-shadow: 0 0 0 0 rgba(230, 0, 0, 0.8), 0 2px 6px rgba(0, 0, 0, 0.45); }
  100% { box-shadow: 0 0 0 14px rgba(230, 0, 0, 0), 0 2px 6px rgba(0, 0, 0, 0.45); }
}

/* Unread story (2026-10-06): one quick pulse with a ripple spreading out,
   then still for a few seconds, then again. Owner, 2026-10-07: half as
   strong (lighter ripple, smaller swell) and 75% speed (4 s → 5.33 s). */
.story-marker.pin-unread:not(.pin-fresh):not(.pin-live) .story-marker-thumb {
  animation: pin-unread 5.33s ease-out infinite;
}

@keyframes pin-unread {
  0% { scale: 1; box-shadow: 0 0 0 0 color-mix(in srgb, var(--cat, #2459d6) 35%, transparent), 0 0 0 0 color-mix(in srgb, var(--cat, #2459d6) 20%, transparent), 0 2px 6px rgba(0, 0, 0, 0.45); }
  8% { scale: 1.075; }
  16% { scale: 1; }
  40% { box-shadow: 0 0 0 16px transparent, 0 0 0 26px transparent, 0 2px 6px rgba(0, 0, 0, 0.45); }
  100% { scale: 1; box-shadow: 0 0 0 16px transparent, 0 0 0 26px transparent, 0 2px 6px rgba(0, 0, 0, 0.45); }
}

.story-cluster.pin-unread {
  animation: cluster-unread 5.33s ease-out infinite;
}

/* Ripple only, no swell: a group is the map's own marker element, which the
   map places with a transform, so scaling it slid it sideways (2026-10-07). */
@keyframes cluster-unread {
  0% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--cat, #5b6b85) 30%, transparent), 0 0 0 4px color-mix(in srgb, var(--cat, #5b6b85) 35%, transparent), 0 2px 8px rgba(0, 0, 0, 0.4); }
  40%, 100% { box-shadow: 0 0 0 20px transparent, 0 0 0 4px color-mix(in srgb, var(--cat, #5b6b85) 35%, transparent), 0 2px 8px rgba(0, 0, 0, 0.4); }
}

body.pins-still .story-cluster {
  animation: none !important;
}

/* Map View → "Animated pins" off (the default when the device asks for
   reduced motion): no pin moves. */
body.pins-still .story-marker .story-marker-thumb {
  animation: none !important;
}

.story-cluster {
  width: var(--size, 36px);
  height: var(--size, 36px);
  border-radius: 50%;
  background: var(--cat, #5b6b85);
  color: #fff;
  font: 800 14px/1 -apple-system, sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid #fff;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--cat, #5b6b85) 35%, transparent), 0 2px 8px rgba(0, 0, 0, 0.4);
  cursor: pointer;
  box-sizing: border-box;
}

/* A group shows the hovered story's headline above it (app.js,
   showGroupHeadline); placed like a single pin's (.story-marker-headline),
   with its own type, since the group's is the big white count. */
.story-cluster > .story-cluster-headline {
  display: block;
  font: 600 12px/1.35 system-ui, -apple-system, sans-serif;
  color: var(--ink);
}

.story-cluster.pin-highlight {
  box-shadow: 0 0 0 6px #ffd166, 0 2px 8px rgba(0, 0, 0, 0.4);
}

.viewer-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #1a73e8;
  border: 3px solid #fff;
  box-shadow: 0 0 0 6px rgba(26, 115, 232, 0.25), 0 1px 4px rgba(0, 0, 0, 0.4);
}

.near-me-button {
  font-size: 18px !important;
  line-height: 1 !important;
}

/* Quick look at a pin. */
#pin-preview {
  position: fixed;
  width: 290px;
  background: #fff;
  color: var(--ink);
  border-radius: 12px;
  border-top: 4px solid var(--cat, #5b6b85);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.3);
  overflow: hidden;
  z-index: 35;
  pointer-events: none;
}

#pin-preview.hidden {
  display: none;
}

#pin-preview.preview-sheet {
  pointer-events: auto;
  left: 8px;
  right: 8px;
  bottom: 12px;
  width: auto;
}

.preview-photo {
  width: 100%;
  height: 140px;
  object-fit: cover;
  display: block;
}

.preview-body {
  padding: 10px 14px 12px;
}

.preview-category {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--cat, #5b6b85);
}

.preview-headline {
  font-size: 16px;
  font-weight: 800;
  line-height: 1.25;
  margin-top: 2px;
}

.preview-from,
.preview-meta {
  font-size: 12px;
  color: var(--muted);
  margin-top: 4px;
}

.preview-read {
  margin-top: 10px;
  width: 100%;
  appearance: none;
  border: none;
  background: var(--accent);
  color: #fff;
  font: 700 15px/1 -apple-system, sans-serif;
  padding: 12px;
  border-radius: 8px;
  cursor: pointer;
}

.preview-close {
  position: absolute;
  top: 8px;
  right: 8px;
  appearance: none;
  border: none;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 50%;
  width: 30px;
  height: 30px;
  cursor: pointer;
}

/* Phones and narrow windows: the search box gets its own row; the results
   list and an open story slide up from the bottom, the map above them. */
@media (max-width: 640px) {
  :root {
    --topbar-h: 98px;
  }

  #topbar {
    flex-wrap: wrap;
    align-content: center;
    row-gap: 8px;
    padding: 6px 10px;
    box-sizing: border-box;
  }

  #topbar-brand {
    flex: 1;
    min-width: 0;
    gap: 6px;
  }

  .brand-name {
    font-size: 14px;
  }

  .brand-rev {
    font-size: 10px;
    padding: 1px 6px;
  }

  #topbar-tools {
    gap: 6px;
  }

  #topbar-tools .topbar-link {
    padding: 3px 8px;
    font-size: 12px;
  }

  #search-wrap {
    order: 3;
    flex: 1 0 100%;
    max-width: none;
  }

  .search-key {
    display: none;
  }

  #connections-map-link {
    display: none;
  }

  #view-dropdown {
    top: calc(var(--map-top) + 6px);
    max-height: calc(var(--vvh, 100dvh) - var(--map-top) - 16px);
  }

  #results-panel {
    top: auto;
    right: 0;
    width: auto;
    height: 52dvh;
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.2);
  }

  #results-panel.collapsed {
    bottom: 0;
    height: auto;
    border-radius: 14px 14px 0 0;
  }

  /* The map's credit line (required by its data licenses) stays visible
     above the collapsed "N stories" bar. */
  body:not(.story-open) .maplibregl-ctrl-bottom-right,
  body:not(.story-open) .maplibregl-ctrl-bottom-left {
    bottom: 50px;
  }

  #results-panel.collapsed .results-caret {
    transform: rotate(180deg);
  }

  #results-head {
    padding: 12px 16px;
  }

  #results-toggle {
    font-size: 15px;
  }

  .result-row {
    padding: 14px 16px 14px 12px;
  }

  #detail-panel {
    top: auto;
    right: 0;
    width: auto;
    height: 62dvh;
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.25);
    padding: 20px 18px 40px;
  }

  body.story-open #focus-bar {
    left: 50%;
    max-width: calc(100vw - 32px);
  }

  .story-marker-thumb {
    width: 38px;
    height: 38px;
  }
}

/* ===================================================================
   Reader map Phase 2 (2026-10-04): the story's reading layout (the classic
   one stays, switchable), share, trust labels, names you can tap, a
   name's card, connected stories.
   =================================================================== */

.layout-switch {
  appearance: none;
  border: 1px solid var(--line);
  background: #f5f7fb;
  color: var(--accent);
  font-size: 12px;
  border-radius: 999px;
  padding: 4px 10px;
  margin-bottom: 12px;
  cursor: pointer;
}

.reading-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 36px 14px 0;
}

.reading-tool {
  appearance: none;
  border: 1px solid #c9d6f2;
  background: #eef3ff;
  color: #13306b;
  font: 600 13px/1 -apple-system, sans-serif;
  border-radius: 999px;
  padding: 7px 12px;
  cursor: pointer;
}

.reading-tool-quiet {
  background: #fff;
  border-color: var(--line);
  color: var(--muted);
  font-weight: 500;
}

.reading-share-box {
  flex-basis: 100%;
  font-size: 13px;
  padding: 6px;
}

.reading-category {
  display: inline-block;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--cat, #5b6b85);
  border-bottom: 2px solid var(--cat, #5b6b85);
  padding-bottom: 2px;
  margin-bottom: 8px;
}

.reading-headline {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 32px;
  line-height: 1.15;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 10px;
}

.reading-dek {
  font-size: 15px;
  font-weight: 600;
  color: #33415c;
}

.reading-byline {
  margin: 6px 0 18px;
  font-size: 12px;
  color: var(--muted);
}

.reading-section-title {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 10px;
}

.reading-events {
  border: 1px solid var(--line);
  background: #fafbfd;
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 20px;
}

.reading-event + .reading-event {
  border-top: 1px solid var(--line);
  margin-top: 10px;
  padding-top: 10px;
}

.reading-event-name {
  font-weight: 700;
  color: var(--ink);
}

.reading-event-meta {
  font-size: 13px;
  color: var(--muted);
  margin-top: 2px;
}

.reading-event-help {
  font-size: 12px;
  color: #7a5a00;
  margin-top: 6px;
}

.reading-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
}

.badge {
  font-size: 11px;
  font-weight: 700;
  border-radius: 999px;
  padding: 3px 9px;
  border: 1px solid transparent;
}

.badge-status { background: #eef1f6; color: #33415c; }
.badge-occurred { background: #e3f5ea; color: #13703d; }
.badge-alleged { background: #fff3d6; color: #8a5a00; }
.badge-disputed { background: #fde7e7; color: #a12a2a; }
.badge-cancelled { background: #eee; color: #666; text-decoration: line-through; }
.badge-scheduled { background: #e8f0ff; color: #1f4fbf; }
.badge-good { background: #e3f5ea; color: #13703d; border-color: #b9e2c8; }
.badge-warn { background: #fff8e6; color: #8a5a00; border-color: #f0dca6; }
.badge-plain { background: #fff; color: var(--muted); border-color: var(--line); }

.reading-hint {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 8px;
}

.reading-body {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 18px;
  line-height: 1.65;
  color: #1f2533;
  max-width: 68ch;
}

.name-link {
  appearance: none;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  border-bottom: 2px solid #b7c8ef;
  background: linear-gradient(transparent 62%, #eaf0ff 62%);
}

.name-link:hover,
.name-link:focus {
  border-bottom-color: var(--accent);
  outline: none;
}

.name-Location { border-bottom-color: #a8dcc0; background: linear-gradient(transparent 62%, #e7f6ee 62%); }
.name-Organization { border-bottom-color: #e3c9a0; background: linear-gradient(transparent 62%, #fbf1e2 62%); }
.name-Event { border-bottom-color: #e7b3b3; background: linear-gradient(transparent 62%, #fbeaea 62%); }

.reading-connected {
  border-top: 1px solid var(--line);
  margin-top: 24px;
  padding-top: 18px;
}

.connected-row {
  display: block;
  width: 100%;
  text-align: left;
  appearance: none;
  border: 1px solid var(--line);
  border-left: 4px solid var(--cat, #888);
  background: #fff;
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 8px;
  font: inherit;
  cursor: pointer;
}

.connected-row:hover {
  background: #f5f8ff;
}

.connected-headline {
  font-weight: 700;
  font-size: 14px;
  color: var(--ink);
}

.connected-shared {
  font-size: 12px;
  color: var(--accent);
  margin-top: 3px;
}

.connected-date {
  font-size: 12px;
  color: var(--muted);
  margin-top: 2px;
}

/* A name's card, over the story. */
.name-card {
  position: fixed;
  top: calc(var(--map-top) + 56px);
  left: 16px;
  width: calc(var(--story-w) - 32px);
  max-height: calc(100dvh - var(--map-top) - 80px);
  overflow-y: auto;
  box-sizing: border-box;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 10px 36px rgba(0, 0, 0, 0.35);
  padding: 18px 18px 14px;
  z-index: 40;
  color: var(--ink);
}

.name-card-close {
  position: absolute;
  top: 10px;
  right: 12px;
  appearance: none;
  border: none;
  background: none;
  font-size: 18px;
  cursor: pointer;
  color: var(--muted);
}

.name-card-type {
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.name-card-name {
  font-size: 22px;
  margin: 4px 30px 4px 0;
}

.name-card-aliases {
  font-size: 13px;
  color: var(--muted);
}

.name-card-map {
  margin: 12px 0 4px;
  width: 100%;
  appearance: none;
  border: none;
  background: var(--accent);
  color: #fff;
  font: 700 14px/1 -apple-system, sans-serif;
  padding: 11px;
  border-radius: 8px;
  cursor: pointer;
}

.name-card-heading {
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted);
  margin: 16px 0 6px;
}

.name-card-timeline {
  list-style: none;
  margin: 0;
  padding: 0 0 0 14px;
  border-left: 2px solid var(--line);
}

.name-card-timeline li {
  position: relative;
  padding: 4px 0 8px 10px;
}

.name-card-timeline li::before {
  content: "";
  position: absolute;
  left: -20px;
  top: 10px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #b7c8ef;
}

.name-card-timeline li.current::before {
  background: var(--accent);
}

.name-card-date {
  display: block;
  font-size: 11px;
  color: var(--muted);
}

.name-card-story {
  appearance: none;
  border: none;
  background: none;
  padding: 0;
  text-align: left;
  font: 600 14px/1.3 -apple-system, sans-serif;
  color: var(--ink);
  cursor: pointer;
}

.name-card-timeline li.current .name-card-story {
  color: var(--accent);
}

.name-card-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.name-card-chip {
  appearance: none;
  border: 1px solid var(--line);
  background: #f8fafd;
  border-radius: 999px;
  padding: 5px 10px;
  font-size: 13px;
  cursor: pointer;
}

@media (max-width: 640px) {
  .reading-headline {
    font-size: 26px;
  }

  .reading-body {
    font-size: 17px;
  }

  .name-card {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-height: 75dvh;
    border-radius: 14px 14px 0 0;
  }
}

/* The story panel's events, numbered and colored like their pins (2026-10-05). */
.reading-event-mapped {
  border-left: 4px solid var(--ev, #2459d6);
  padding-left: 10px;
  margin-left: -14px;
  cursor: pointer;
}

.reading-event-mapped:hover .reading-event-name {
  text-decoration: underline;
}

.reading-event-number {
  min-width: 20px;
  height: 20px;
  line-height: 20px;
  font-size: 12px;
  vertical-align: 2px;
}


/* ===================================================================
   Side panels (map-view.js, 2026-10-05): folded, thin tabs stacked on the
   map's right edge (Map View, Map Data); open, a panel beside the tabs.
   =================================================================== */
#map-side {
  position: absolute;
  right: 0;
  top: 120px;
  z-index: 24;
  display: flex;
  align-items: flex-start;
  font: 13px/1.35 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

.map-side-tabs {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.map-side-tab {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  background: #0a1f44;
  color: #fff;
  border: none;
  border-radius: 0 8px 8px 0; /* rotated: rounds the side facing the map */
  padding: 12px 6px;
  font: 700 12px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 1px -1px 6px rgba(0, 0, 0, 0.3);
}

.map-side-tab.open {
  background: #2459d6;
}

.map-side-tab:focus-visible {
  outline: 3px solid #f5c542;
  outline-offset: 2px;
}

.map-side-bodies {
  display: flex;
}

.map-side-body {
  display: none;
  width: min(270px, calc(100vw - 60px));
  /* From 120px below the map's top to 60px above the screen's bottom; the
     rest scrolls inside. */
  max-height: calc(var(--vvh, 100dvh) - var(--map-top) - 180px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: #fff;
  color: #172033;
  border-radius: 0 0 0 10px;
  box-shadow: -2px 2px 10px rgba(0, 0, 0, 0.3);
  padding: 0 14px 12px;
  box-sizing: border-box;
}

.map-side-body.open {
  display: block;
}

.map-data-title {
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #5b6472;
}

.map-data-section #connections-search {
  margin-top: 8px;
}

.map-view-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 700;
  font-size: 15px;
  padding: 10px 0 4px;
}

.map-view-close {
  border: none;
  background: none;
  font-size: 22px;
  line-height: 1;
  padding: 2px 6px;
  cursor: pointer;
  color: #3b4456;
}

.map-view-group {
  border: none;
  border-top: 1px solid #e3e7ef;
  margin: 8px 0 0;
  padding: 8px 0 0;
}

.map-view-group legend {
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #5b6472;
  padding: 0;
  margin-bottom: 4px;
}

.map-view-group label {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 5px 0;
  cursor: pointer;
}

.map-view-sub {
  padding-left: 24px !important;
}

.map-view-sub:has(input:disabled) {
  color: #9aa1ad;
  cursor: default;
}

.map-view-note {
  margin: 10px 0 0;
  font-size: 11px;
  color: #5b6472;
}

@media (max-width: 640px) {
  #map-side {
    top: 110px;
  }

  /* Clear of the phone's "N stories" bar at the bottom. */
  .map-side-body {
    max-height: calc(var(--vvh, 100dvh) - var(--map-top) - 200px);
  }

  .map-view-group label {
    padding: 8px 0; /* bigger tap targets */
  }
}

/* The Filters button at the search box's right end (2026-10-05): funnel,
   "Filters", and a count badge while any are on; just the funnel and badge
   on phones. */
.search-filters {
  position: absolute;
  right: 4px;
  top: 4px;
  height: 30px;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 0 10px 0 9px;
  border: none;
  border-radius: 15px;
  background: #eef1f6;
  color: #172033;
  font: 600 13px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  cursor: pointer;
}

.search-filters:hover {
  background: #e1e6ef;
}

.search-filters:focus-visible {
  outline: 3px solid #f5c542;
  outline-offset: 1px;
}

.search-filters[aria-expanded="true"],
.search-filters.active {
  background: #0a1f44;
  color: #fff;
}

.search-filters-icon {
  width: 15px;
  height: 15px;
}

.search-filters-count {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  box-sizing: border-box;
  border-radius: 9px;
  background: #ffd166;
  color: #0a1f44;
  font-size: 11px;
  font-weight: 800;
  line-height: 18px;
  text-align: center;
}

.search-filters-count[hidden] {
  display: none;
}

/* "Filter by" rows in the suggestions. */
.suggestion-filter .suggestion-label {
  font-weight: 600;
}

@media (max-width: 640px) {
  #search-box {
    padding-right: 64px;
  }

  .search-filters-label {
    display: none;
  }

  .search-filters {
    padding: 0 9px;
  }
}

/* AND / OR / NOT on a filter chip (search.js); tap to switch. */
.chip-op {
  border: none;
  border-radius: 999px;
  padding: 2px 7px;
  margin: 0 2px 0 4px;
  font: 800 10px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  letter-spacing: 0.05em;
  cursor: pointer;
  color: #fff;
  background: #2459d6;
  align-self: center;
}

.chip-op-or {
  background: #1f8a4c;
}

.chip-op-not {
  background: #b3261e;
}

.chip-op:focus-visible {
  outline: 2px solid #f5c542;
  outline-offset: 1px;
}

/* ===================================================================
   News sections (2026-10-06, owner): a low row of tabs under the header
   (sections.js), and the chosen section's name in the results list.
   Colors are placeholders until the palette is chosen.
   =================================================================== */

#sections-bar {
  position: fixed;
  top: var(--topbar-h);
  left: 0;
  right: 0;
  height: var(--sections-h);
  box-sizing: border-box;
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 0 8px;
  overflow-x: auto;
  overflow-y: hidden;
  background: #fff;
  border-bottom: 1px solid var(--line);
  z-index: 27;
  scrollbar-width: none;
}

#sections-bar::-webkit-scrollbar {
  display: none;
}

.section-tab {
  appearance: none;
  flex-shrink: 0;
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  padding: 0 9px;
  font: 600 12.5px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  white-space: nowrap;
  cursor: pointer;
}

.section-tab:hover {
  color: var(--accent);
}

.section-tab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.section-tab.empty:not(.active) {
  color: #9aa2b1;
}

.section-tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -3px;
}

.section-tab.section-switch {
  color: var(--muted);
  font-weight: 500;
}

/* The results list's head: the count, then the section's name, then Sort. */
#results-head {
  flex-wrap: wrap;
  row-gap: 4px;
}

#results-toggle {
  flex: 1 0 100%;
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}

#results-section {
  flex: 1 0 100%;
  font: 800 21px/1.15 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  padding: 2px 0 6px;
  border-bottom: 2px solid var(--ink);
}

.results-sort {
  flex: 1 0 100%;
  text-align: right;
}

#results-panel.collapsed #results-section {
  display: none;
}

#results-panel.collapsed #results-toggle {
  font-size: 14px;
  color: var(--ink);
}

@media (max-width: 640px) {
  /* The search box at three quarters of its old width (owner, 2026-10-06),
     still on its own line under the name. */
  #topbar-brand {
    flex: 1 0 50%;
  }

  #search-wrap {
    flex: 0 0 75%;
    margin: 0 auto;
  }

  #results-section {
    font-size: 19px;
  }

  #results-panel.collapsed #results-toggle {
    font-size: 15px;
  }
}

/* Reader profile panel (reader.js, 2026-10-07): same card as the journalist
   panels. */
#reader-panel {
  position: fixed;
  top: 5%;
  left: 50%;
  transform: translateX(-50%);
  width: min(400px, 90vw);
  max-height: 85vh;
  overflow-y: auto;
  background: #fff;
  color: #1a1a1a;
  border-radius: 10px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
  padding: 24px;
  z-index: 40;
  box-sizing: border-box;
}

#reader-panel.hidden {
  display: none;
}

#reader-close {
  position: absolute;
  top: 12px;
  right: 16px;
  border: none;
  background: none;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  color: #333;
}

.reader-intro,
.reader-note {
  color: #555;
  font-size: 14px;
  margin: 0 0 14px;
}

.reader-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.reader-label {
  font-size: 13px;
  color: #444;
}

.reader-swap {
  font-size: 14px;
  margin: 14px 0 0;
}

.reader-text-button {
  appearance: none;
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  color: #0a4f8a;
  text-decoration: underline;
  cursor: pointer;
}

.reader-subhead {
  font-size: 15px;
  margin: 18px 0 6px;
}

.reader-saved {
  margin: 0 0 6px;
  padding-left: 20px;
  font-size: 14px;
}

.reader-inline-form {
  display: flex;
  gap: 8px;
}

.reader-inline-form .auth-input {
  flex: 1;
  min-width: 0;
}

.reader-secondary {
  appearance: none;
  border: 1px solid #bbb;
  background: #f4f4f4;
  color: #1a1a1a;
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 14px;
  cursor: pointer;
}

.reader-ok {
  color: #1d6b35;
}

.reader-actions {
  display: flex;
  flex-direction: column;
  margin-top: 20px;
}

.reader-danger {
  margin-top: 18px;
  font-size: 14px;
}

.reader-delete {
  color: #a40000;
}

.reader-delete-confirm {
  background: #a40000;
  border-color: #a40000;
  color: #fff;
}

.reader-forgot {
  align-self: center;
  font-size: 14px;
}

/* ---------- Reading lists (reading-list.js, 2026-10-07) ---------- */

.section-tab.section-reading-list {
  margin-left: auto;
  font-weight: 700;
}

body.rl-mode #results-list,
body.rl-mode .results-sort,
body.rl-mode #results-section {
  display: none;
}

#reading-lists {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 10px 14px 24px;
}

.rl-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 4px 0 10px;
}

.rl-title {
  font-size: 18px;
  margin: 0;
  overflow-wrap: anywhere;
}

.rl-rename {
  flex: 1;
}

.rl-list-head {
  display: block;
  width: 100%;
  text-align: left;
  appearance: none;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 8px;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.rl-list-head:hover {
  border-color: var(--accent);
}

.rl-list-name {
  display: block;
  font-weight: 700;
  font-size: 16px;
}

.rl-list-count,
.rl-row-meta {
  display: block;
  color: var(--muted);
  font-size: 13px;
  margin-top: 2px;
}

.rl-hint {
  color: var(--muted);
  font-size: 14px;
}

.rl-back,
.rl-text-button {
  appearance: none;
  border: none;
  background: none;
  padding: 4px 0;
  font: inherit;
  font-size: 14px;
  color: var(--accent);
  cursor: pointer;
}

.rl-list-tools {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.rl-danger {
  color: #a40000;
}

.rl-confirm-text {
  font-size: 14px;
}

/* The player, inside the Audio Reader side panel. */
.rl-player {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 4px;
}

.rl-audio-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.rl-audio-label {
  font-weight: 600;
}

.rl-listen {
  appearance: none;
  border: 1px solid #c5ccd9;
  background: #fff;
  color: var(--ink);
  border-radius: 16px;
  padding: 5px 12px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  margin-bottom: 10px;
}

a.reading-tool,
a.rl-listen {
  display: inline-block;
  text-decoration: none;
}

.rl-listen-page {
  margin-left: 6px;
}

.rl-listen:hover {
  border-color: var(--accent);
}

/* A dot on the folded Audio Reader tab while something is playing or paused. */
.map-side-tab.rl-tab-playing::after {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-top: 6px;
  border-radius: 50%;
  background: #4ade80;
}

.rl-player-status {
  font-size: 13px;
  color: var(--muted);
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.rl-player-controls {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.rl-ctl {
  appearance: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid #c5ccd9;
  background: #fff;
  color: var(--ink);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.rl-ctl-main {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.rl-ctl:disabled {
  opacity: 0.4;
  cursor: default;
}

.rl-ctl:focus-visible,
.rl-icon:focus-visible,
.rl-row-open:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.rl-continuous {
  font-size: 13px;
}

.rl-stories {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rl-row {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--line);
  border-left: 4px solid var(--cat, #888);
}

.rl-row.rl-current {
  background: #eef3ff;
}

.rl-row-open {
  flex: 1;
  min-width: 0;
  text-align: left;
  appearance: none;
  background: none;
  border: none;
  padding: 10px 8px 10px 10px;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.rl-row-headline {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.rl-unread {
  color: var(--accent);
  font-size: 10px;
  margin-right: 6px;
  vertical-align: 2px;
}

.rl-gone {
  color: var(--muted);
  font-weight: 400;
  font-style: italic;
}

.rl-row-tools {
  display: flex;
  align-items: center;
}

.rl-icon {
  appearance: none;
  border: none;
  background: none;
  width: 32px;
  height: 40px;
  font-size: 15px;
  color: var(--muted);
  cursor: pointer;
}

.rl-icon:hover:not(:disabled) {
  color: var(--ink);
}

.rl-icon:disabled {
  opacity: 0.3;
  cursor: default;
}

/* The "Add to reading list" card: same look as the reader account card. */
.pa-card {
  position: fixed;
  top: 5%;
  left: 50%;
  transform: translateX(-50%);
  width: min(420px, 90vw);
  max-height: 85vh;
  overflow-y: auto;
  background: #fff;
  color: #1a1a1a;
  border-radius: 10px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
  padding: 24px;
  z-index: 40;
  box-sizing: border-box;
}

.pa-card.hidden,
.reader-field.hidden,
.rl-choice.hidden {
  display: none;
}

.pa-card-close {
  position: absolute;
  top: 12px;
  right: 16px;
  border: none;
  background: none;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  color: #333;
}

.rl-dialog-story {
  font-weight: 600;
  margin: -6px 0 14px;
}

.rl-choice {
  border: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.rl-radio {
  font-size: 14px;
}

.preview-rl {
  margin-left: 6px;
}

.rl-voice {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
}

.rl-voice-label {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
}

.rl-voice-box {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.rl-voice-tip {
  font-size: 13px;
  color: #4a5568;
}

.rl-voice-tip summary {
  cursor: pointer;
  color: #2b5cab;
}

.rl-voice-tip p {
  margin: 6px 0 0;
  line-height: 1.4;
}

.rl-voice-select {
  flex: 1;
  min-width: 0;
  font: inherit;
  padding: 4px 6px;
  border: 1px solid #c5ccd9;
  border-radius: 6px;
  background: #fff;
}

/* ---------- Map FX (fx.js, 2026-10-07) ---------- */

/* The map's picture fades into a section's look; the layers sit just above
   it and under the pins. */
.maplibregl-canvas {
  transition: filter 0.6s ease;
}

.fx-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transition: opacity 0.6s ease;
}

.fx-shadows { mix-blend-mode: lighten; }     /* lifts the darks toward its color */
.fx-highlights { mix-blend-mode: darken; }   /* pulls the lights toward its color */
.fx-grain { mix-blend-mode: overlay; background-size: 160px 160px; }
.fx-vignette { background: radial-gradient(ellipse at center, transparent 55%, #000 100%); }

.map-side-tab.fx-tab-live::after,
.map-side-tab.fx-tab-off::after {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-top: 6px;
  border-radius: 50%;
}

.map-side-tab.fx-tab-live::after { background: #22c55e; } /* FX on */
.map-side-tab.fx-tab-off::after { background: #ef4444; }  /* FX off */

.fx-panel .fx-switch {
  display: flex;
  gap: 8px;
  align-items: center;
  font-weight: 600;
  padding: 6px 0 0;
}

.fx-tools {
  border-top: 1px solid #e3e7ef;
  margin-top: 10px;
  padding-top: 8px;
}

.fx-tools summary {
  font-weight: 700;
  cursor: pointer;
  padding: 4px 0;
}

.fx-group {
  margin-top: 10px;
}

.fx-subhead {
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #5b6472;
  margin-bottom: 2px;
}

/* RGB curves in a stack layer's card (fx.js, curvesEditor). */
.fx-curves {
  margin: 4px 0 10px;
}
.fx-curve-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 6px;
}
.fx-curve-tab {
  font: inherit;
  font-size: 12px;
  padding: 2px 8px;
  border: 1px solid #cfd5de;
  border-radius: 999px;
  background: #fff;
  color: var(--ink, #3a4150);
  cursor: pointer;
}
.fx-curve-tab.on {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
  font-weight: 600;
}
.fx-curve-canvas {
  display: block;
  touch-action: none;
  cursor: crosshair;
  border-radius: 6px;
}

.fx-row {
  display: grid;
  grid-template-columns: 70px 1fr 38px 18px;
  align-items: center;
  gap: 5px;
  padding: 3px 0;
}

.fx-row:has(.fx-color) {
  grid-template-columns: 70px 28px 1fr 38px 18px;
}

.fx-row input[type="range"] {
  width: 100%;
  min-width: 0;
}

.fx-label {
  font-size: 12px;
}

.fx-value {
  font-size: 11px;
  color: #5b6472;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.fx-color {
  width: 30px;
  height: 24px;
  padding: 0;
  border: 1px solid #c5ccd9;
  border-radius: 4px;
  background: none;
}

.fx-select {
  grid-column: 2 / -1;
  font: inherit;
  padding: 3px 4px;
  border: 1px solid #c5ccd9;
  border-radius: 6px;
}

.fx-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.fx-button {
  appearance: none;
  border: 1px solid #c5ccd9;
  background: #fff;
  border-radius: 6px;
  padding: 6px 10px;
  font: inherit;
  cursor: pointer;
  touch-action: none;
}

.fx-primary {
  background: #0a1f44;
  border-color: #0a1f44;
  color: #fff;
}

.fx-text {
  width: 100%;
  box-sizing: border-box;
  margin-top: 6px;
  font: 11px/1.3 ui-monospace, Menlo, monospace;
}

/* Masked filter (fx.js): the zone layer filters the map behind it, only
   where its gradient mask lets it through. */
.fx-zone {
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
  mask-size: 100% 100%;
  -webkit-mask-size: 100% 100%;
}

.fx-check {
  display: flex;
  gap: 6px;
  align-items: center;
  font-size: 12px;
  padding: 3px 0;
}

/* FX presets (fx.js) */
.fx-save {
  display: flex;
  gap: 6px;
  margin: 4px 0;
}

.fx-name {
  flex: 1;
  min-width: 0;
  font: inherit;
  padding: 5px 7px;
  border: 1px solid #c5ccd9;
  border-radius: 6px;
}

.fx-preset-list {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  max-height: 180px;
  overflow-y: auto;
}

.fx-preset {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 0;
  border-top: 1px solid #eef1f6;
}

.fx-preset-text {
  flex: 1;
  min-width: 0;
}

.fx-preset-name {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.fx-preset-by {
  font-size: 11px;
  color: #5b6472;
}

.fx-delete {
  color: #a40000;
}

.fx-link {
  appearance: none;
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  color: #2459d6;
  text-decoration: underline;
  cursor: pointer;
}

.fx-ok { color: #1d6b35; }
.fx-error { color: #a40000; }

/* FX: names (double-tap to reset), zoom links, distortion, labels copy. */
.fx-label {
  user-select: none;
  -webkit-user-select: none;
  cursor: default;
}

.fx-link-btn {
  appearance: none;
  border: none;
  background: none;
  padding: 0;
  font-size: 13px;
  line-height: 1;
  color: #9aa1ad;
  cursor: pointer;
}

.fx-link-btn.on {
  color: #2459d6;
}

.fx-zoom {
  margin-top: 8px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.fx-driver {
  margin: 2px 0 8px 10px;
  padding: 6px 8px;
  border-left: 3px solid #2459d6;
  background: #f3f6fd;
  border-radius: 0 6px 6px 0;
}

.fx-key {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 2px 0;
  font-size: 12px;
}

.fx-num {
  width: 58px;
  font: inherit;
  padding: 2px 4px;
  border: 1px solid #c5ccd9;
  border-radius: 4px;
}

.fx-key-label {
  color: #5b6472;
}

/* The labels-only copy of the map (fx.js), above or under the effects. */
.fx-labels.maplibregl-map,
.fx-labels {
  position: absolute !important;
  inset: 0;
  pointer-events: none;
  background: transparent;
}

.fx-subhead-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.fx-group-reset {
  appearance: none;
  border: none;
  background: none;
  padding: 0;
  font: 600 11px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  letter-spacing: 0;
  text-transform: none;
  color: #2459d6;
  cursor: pointer;
}

.fx-group-reset:disabled {
  color: #b5bbc6;
  cursor: default;
}

/* FX layer stack (fx.js): one card per layer. */
.fx-card {
  border: 1px solid #e3e7ef;
  border-radius: 8px;
  margin: 6px 0;
  background: #fff;
}

.fx-card.off .fx-card-title {
  color: #9aa1ad;
}

.fx-card-head {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 2px 4px;
}

.fx-card-title {
  flex: 1;
  min-width: 0;
  appearance: none;
  border: none;
  background: none;
  text-align: left;
  font: 600 12px/1.3 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  padding: 6px 4px;
  cursor: pointer;
  overflow-wrap: anywhere;
}

.fx-icon {
  appearance: none;
  border: none;
  background: none;
  width: 24px;
  height: 28px;
  font-size: 13px;
  color: #5b6472;
  cursor: pointer;
}

.fx-icon:disabled {
  opacity: 0.3;
  cursor: default;
}

.fx-card-body {
  padding: 0 8px 8px;
  border-top: 1px solid #eef1f6;
}

.fx-minihead {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #7a8291;
  margin: 8px 0 2px;
}

.fx-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  font-size: 12px;
  padding: 2px 0;
}

.fx-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  cursor: pointer;
}

.fx-add {
  width: 100%;
  margin-top: 6px;
}

/* Map copies for pixelated or masked layers: above the main map, under the
   effect overlays and the pins. */
.fx-copy {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.fx-copy-map,
.fx-copy-map.maplibregl-map {
  position: absolute !important;
  inset: 0;
  pointer-events: none;
  background: transparent;
}

.fx-offscreen {
  opacity: 0;
}

.fx-copy-out {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* FX master switch (fx.js). */
.fx-master {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0 2px;
}

.fx-master-label {
  font-weight: 700;
}

.fx-toggle {
  appearance: none;
  position: relative;
  width: 42px;
  height: 24px;
  flex-shrink: 0;
  border: none;
  border-radius: 12px;
  background: #b5bbc6;
  cursor: pointer;
  transition: background 0.15s;
}

.fx-toggle.on {
  background: #2459d6;
}

.fx-toggle-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: left 0.15s;
}

.fx-toggle.on .fx-toggle-knob {
  left: 21px;
}

.fx-toggle:focus-visible {
  outline: 2px solid #2459d6;
  outline-offset: 2px;
}
