:root {
  /* Forest-green theme. --accent drives every interactive accent (tabs, rings,
     buttons, links); keep manifest.json `theme_color` and icon.svg in sync with
     it. --track is the empty portion of the progress rings. */
  --accent: #2b7a4b;
  --bg: #f5f7f3;
  --card: #ffffff;
  --text: #2b2b2b;
  --muted: #777;
  --border: #ddd;
  --track: #e4ebe5;
  --error: #c0392b;
  --gold: #e0a106;

  /* category colours — kept in sync with data.json `categories[].color` */
  --c-library: #2563c9;
  --c-park: #2f9e44;
  --c-beach: #e0a106;
  --c-stairway: #b5446e;

  /* All stairway buckets share ONE colour (the default matches DEFAULT_STAIR_COLOR
     in app.js); the user can override it at runtime via store.ui.stairColor, which
     is applied through inline styles, so there's no per-tier CSS var anymore. */
  --c-stair-default: #e64980;
}

* { box-sizing: border-box; }

body {
  margin: 0 auto;
  /* No top padding — the sticky .topbar supplies its own so it can pin flush to
     the viewport top. Horizontal/bottom padding stays on the body. */
  padding: 0 1rem 1rem;
  max-width: 1100px;
  font-family: system-ui, -apple-system, sans-serif;
  background: var(--bg);
  color: var(--text);
}

/* While the detail sheet is open the body is pinned in place (JS sets `top` to the
   negative scroll offset and restores it on close) so scrolling the sheet can't
   drag the page behind it out of position. left/right:0 + the body's max-width and
   auto margins keep it centred on wide screens. */
body.sheet-open {
  position: fixed;
  left: 0;
  right: 0;
  overflow: hidden;
}

/* "Freeze panes": the title + tabs ride in one sticky bar pinned to the top of
   the page scroll, so the WHOLE top section stays put while the content below
   scrolls. Sticky (not a viewport lock) is the most reliable mobile approach —
   it pins to the visual viewport top on iOS Safari without fighting the dynamic
   toolbar. An opaque background masks content scrolling underneath it. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--bg);
  padding-top: 1rem;
  padding-bottom: 0.55rem;   /* breathing room + masks content scrolling under */
}

header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}

h1 { margin: 0.2rem 0; font-size: 1.6rem; white-space: nowrap; }

.home-link { color: var(--muted); text-decoration: none; }
.home-link:hover { color: var(--accent); }

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
}

/* ---- View switcher (pill segmented control) ---- */
/* Lives inside the sticky .topbar, so it's pinned along with the title. */
.tabbar {
  display: flex;
  width: fit-content;
  max-width: 100%;
  margin: 0.6rem auto 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
  background: var(--card);
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
}

.tabbar button {
  padding: 0.45rem 0.85rem;
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  border: none;
  border-right: 1px solid var(--border);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.tabbar button:last-child { border-right: none; }
.tabbar button:hover:not(.active) { color: var(--accent); }
.tabbar button.active { background: var(--accent); color: #fff; }

/* ---- View visibility ---- */
.view { display: none; }
.view.active { display: block; }

/* =================== Dashboard =================== */
.overall {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
}

/* progress ring rendered with a conic-gradient; --p is the percent 0..100 */
.overall-ring, .cat-ring {
  --p: 0;
  --ring: var(--accent);
  flex: none;
  border-radius: 50%;
  background:
    conic-gradient(var(--ring) calc(var(--p) * 1%), var(--track) 0);
  display: grid;
  place-items: center;
}
.overall-ring { width: 84px; height: 84px; }
.overall-ring::before {
  content: "";
  width: 64px; height: 64px;
  border-radius: 50%;
  background: var(--card);
}
.overall-text { min-width: 0; }
.overall-pct { font-size: 2rem; font-weight: 700; line-height: 1; }
.overall-sub { color: var(--muted); font-size: 0.9rem; margin-top: 0.3rem; }

.cat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.8rem;
}

/* A card is a column: a clickable header row (ring + meta + ⚙) and a collapsible
   config panel below it. */
.cat-card {
  display: flex;
  flex-direction: column;
  transition: border-color 0.12s ease;
}
.cat-card:hover { border-color: var(--cat); }
.cat-card-head {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.9rem 1rem;
  cursor: pointer;
  transition: transform 0.08s ease;
}
.cat-card-head:active { transform: scale(0.99); }
/* Opted out of summary stats: dim the progress, keep the gear fully usable. */
.cat-card.dimmed .cat-ring,
.cat-card.dimmed .cat-meta { opacity: 0.4; }

.cat-ring {
  width: 56px; height: 56px;
  --ring: var(--cat);
  position: relative;
}
.cat-ring::before {
  content: "";
  width: 42px; height: 42px;
  border-radius: 50%;
  background: var(--card);
}
.cat-ring span {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 0.72rem;
  font-weight: 700;
}

.cat-meta { min-width: 0; flex: 1; }
.cat-name {
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.cat-dot {
  width: 0.7rem; height: 0.7rem;
  border-radius: 50%;
  background: var(--cat);
  flex: none;
}
.cat-count { color: var(--muted); font-size: 0.88rem; margin-top: 0.15rem; }
.cat-done {
  margin-left: 0.3rem;
  font-size: 0.8rem;
  color: var(--accent);
}

/* Per-card ⚙ config button + collapsible config panel (colour + include-in-stats). */
.cat-config-btn {
  flex: none;
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0.3rem;
  border-radius: 7px;
  display: flex;
  align-items: center;
}
.cat-config-btn:hover, .cat-config-btn.on { color: var(--cat); background: var(--bg); }
.cat-config {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0 1rem 0.9rem;
  /* sits below the card header; a hairline separates it */
  border-top: 1px solid var(--border);
  margin-top: -1px;
  padding-top: 0.7rem;
}
.cat-config[hidden] { display: none; }
.cat-config-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
}
.cat-config-label { color: var(--muted); }
.cat-config input[type="color"] {
  flex: none;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.cat-config input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.cat-config input[type="color"]::-webkit-color-swatch { border: none; border-radius: 50%; }
.cat-config input[type="color"]::-moz-color-swatch { border: none; border-radius: 50%; }
.cat-color-reset {
  margin-left: auto;
  padding: 0.3rem 0.7rem;
  font-size: 0.82rem;
  font-weight: 600;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--bg);
  color: var(--muted);
  cursor: pointer;
}
.cat-color-reset:hover { border-color: var(--accent); color: var(--accent); }
.cat-config-check { cursor: pointer; }
.cat-config-check input { flex: none; width: 1rem; height: 1rem; }

.data-note {
  margin: 1.2rem 0 0.5rem;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.5;
}
.data-note a { color: var(--accent); }

/* =================== List =================== */
.list-controls {
  /* Sticky just below the frozen .topbar (its height is measured into
     --topbar-h by app.js; the fallback covers the first paint). */
  position: sticky;
  top: var(--topbar-h, 6.5rem);
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.6rem 0.7rem;
  margin-bottom: 0.8rem;
}

#search {
  width: 100%;
  padding: 0.5rem 0.7rem;
  font-size: 16px; /* avoid iOS focus auto-zoom */
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
}

.filter-row { display: flex; gap: 0.5rem; }
.filter-row select {
  flex: 1;
  min-width: 0;
  padding: 0.45rem 0.5rem;
  font-size: 16px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
}

.cat-group-head {
  margin: 1rem 0 0.4rem;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.place-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.8rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 0.5rem;
}

/* round visited checkbox: hollow ring → filled dot when visited */
.visit-toggle {
  flex: none;
  width: 1.5rem; height: 1.5rem;
  border-radius: 50%;
  border: 3px solid var(--cat);
  background: transparent;
  cursor: pointer;
  position: relative;
  transition: background 0.12s ease;
}
.visit-toggle.on { background: var(--cat); }
.visit-toggle.on::after {
  content: "✓";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #fff;
  font-size: 0.85rem;
  font-weight: 700;
}

.place-main {
  flex: 1;
  min-width: 0;
  cursor: pointer;
}
.place-name {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.place-sub {
  color: var(--muted);
  font-size: 0.82rem;
  margin-top: 0.1rem;
}

/* Review indicators on a list row: the user's star rating + a note glyph, shown
   only when present so a reviewed place reads as reviewed at a glance. */
.place-badges {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.2rem;
}
.row-stars {
  color: var(--gold);
  font-size: 0.8rem;
  line-height: 1;
  letter-spacing: 0.04em;
}
.row-note {
  display: inline-flex;
  align-items: center;
  color: var(--muted);
}

.fav-btn {
  flex: none;
  border: none;
  background: transparent;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  color: var(--border);
  padding: 0.2rem;
}
.fav-btn.on { color: var(--gold); }

/* Clear-filters button: a subtle text button in the list controls (shown only when
   a filter/search is active) and a matching one inside the empty state. */
.clear-filters {
  align-self: flex-start;
  padding: 0.3rem 0.7rem;
  font-size: 0.82rem;
  font-weight: 600;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--muted);
  cursor: pointer;
}
.clear-filters:hover { border-color: var(--accent); color: var(--accent); }
.clear-filters[hidden] { display: none; }

.empty {
  text-align: center;
  color: var(--muted);
  padding: 2rem 1rem;
}
.empty p { margin: 0 0 0.8rem; }
.clear-filters-inline {
  padding: 0.4rem 0.9rem;
  font-size: 0.88rem;
  font-weight: 600;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--accent);
  cursor: pointer;
}
.clear-filters-inline:hover { border-color: var(--accent); }

/* =================== Map =================== */
#map {
  height: calc(100vh - 8rem);
  min-height: 420px;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}

/* Map view: lock the whole page to the viewport so the map fills the space below
   the frozen topbar exactly — nothing scrolls or zooms at the page level
   (panning/zooming happens inside Leaflet). `map-active` is toggled on <body> by
   switchView(). Uses dvh so mobile browser chrome is accounted for. */
body.map-active {
  height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;
  display: flex;
  flex-direction: column;
}
body.map-active .topbar { position: static; }   /* frozen by flex now, not sticky */
body.map-active .content {
  flex: 1 1 auto;
  min-height: 0;       /* let the flex child shrink so #map can fill exactly */
  display: flex;
}
body.map-active #view-map {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  margin-bottom: 0;
}
body.map-active #map {
  flex: 1 1 auto;
  height: auto;        /* override the calc() height; flex drives the size */
  min-height: 0;
}

/* legend / layer control */
.map-legend {
  position: relative;
  background: var(--card);
  padding: 0.5rem 0.6rem;
  border-radius: 10px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
  font-size: 0.82rem;
  line-height: 1.7;
}
/* Collapsible header ("Layers"); collapsed by default. */
.map-legend .legend-toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  padding: 0.05rem 0.1rem;
}
.map-legend .legend-toggle svg { flex: none; color: var(--accent); }
.map-legend .legend-toggle .legend-caret { margin-left: auto; transition: transform 0.15s ease; font-size: 1.4rem; line-height: 1; }
.map-legend.open .legend-toggle .legend-caret { transform: rotate(180deg); }
.map-legend .legend-body {
  margin-top: 0.4rem;
  /* 10 categories + status toggles can get tall — cap it and scroll inside. */
  max-height: min(62vh, 24rem);
  overflow-y: auto;
}
.map-legend .legend-body[hidden] { display: none; }
.map-legend .legend-title { font-weight: 700; margin: 0.35rem 0 0.15rem; }
.map-legend .legend-title:first-child { margin-top: 0; }
/* Stairways group: a master row (checkbox = show/hide all tiers) plus a disclosure
   triangle that collapses the per-tier submenu; the tiers sit indented beneath it. */
.map-legend .legend-stair-row { display: flex; align-items: center; }
.map-legend .legend-stair-master { flex: 1; min-width: 0; }
.map-legend .stair-disclose {
  flex: none;
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0 0.15rem;
  display: flex;
  align-items: center;
}
.map-legend .stair-disclose .legend-caret {
  font-size: 1.2rem;
  line-height: 1;
  transition: transform 0.15s ease;
}
.map-legend .stair-disclose.open .legend-caret { transform: rotate(180deg); }
.map-legend .stair-submenu[hidden] { display: none; }
/* Master off: the tier selection is paused (not applied to the map). Dim it to say
   so, but keep it editable so the user can adjust the selection while it's off. */
.map-legend .stair-submenu.paused { opacity: 0.45; }
.map-legend .legend-stair-item { padding-left: 0.95rem; }
.map-legend label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
}
.map-legend .legend-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.map-legend .legend-count {
  flex: none;
  color: var(--muted);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
}
.map-legend .swatch {
  width: 0.8rem; height: 0.8rem;
  border-radius: 50%;
  flex: none;
}
/* Category / stair swatches echo the map's teardrop pin so the legend and the map
   read as one system: a rounded square with one pointed corner, rotated to point
   down. (The Show/Favorites swatches stay round — they denote state, not category.) */
.map-legend .swatch-pin {
  border-radius: 50% 50% 50% 0;
  transform: rotate(45deg);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.6);
}
/* status-filter swatches mirror the map dots: solid = explored, faded = unexplored
   (kept in step with markerStyle's darker/thicker unexplored dots). */
.map-legend .swatch-solid { background: var(--muted); }
.map-legend .swatch-muted {
  background: var(--muted);
  opacity: 0.5;
  border: 2px solid var(--muted);
}
/* Favorites-only filter: a gold star instead of a colour dot. */
.map-legend .swatch-fav {
  background: none;
  color: var(--gold);
  font-size: 0.85rem;
  line-height: 0.8rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.map-legend .locate-btn {
  margin-top: 0.4rem;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  padding: 0.3rem 0.4rem;
  font-size: 0.8rem;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
}
.map-legend .locate-icon { flex: none; }
.map-legend .locate-btn:hover { border-color: var(--accent); color: var(--accent); }
.map-legend .locate-btn.on { background: var(--accent); color: #fff; border-color: var(--accent); }

/* ---- Teardrop pin markers ----
   Google-Maps-style pins: an SVG in an L.divIcon, coloured per category via the
   inline `--pin` custom property. The wrapper must shed Leaflet's default white
   div-icon chrome. The SVG scales from its tip (transform-origin) so the point
   stays glued to the coordinate as applyMarkerScale() grows/shrinks it on zoom. */
.leaflet-div-icon.pin-wrap {
  background: transparent;
  border: none;
}
.pin-wrap .pin {
  display: block;
  overflow: visible;                 /* let the pin grow past its 24×32 box when scaled up */
  transform-origin: 12px 30px;       /* the tip — scale about the anchored point */
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));
}
.pin-wrap .pin-body {
  fill: var(--pin, #888);
  stroke: #fff;
  stroke-width: 1.5;
}
.pin-wrap .pin-hole { fill: #fff; }
/* Unexplored: same hue, faded (mirrors the old muted-dot semantics). */
.pin-wrap .pin--muted { opacity: 0.5; }
/* Selected (its detail sheet is open): lift it with a stronger shadow + ring, and
   fill the hole so it reads as the current pin. Doesn't touch transform (that's the
   zoom scale) so the two never fight. */
.pin-wrap .pin--selected {
  opacity: 1;
  filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 0.5));
}
.pin-wrap .pin--selected .pin-body { stroke-width: 2.5; }
.pin-wrap .pin--selected .pin-hole { fill: var(--pin, #888); }

/* the "you are here" marker */
.me-marker {
  width: 18px; height: 18px;
  position: relative;
}
.me-dot {
  position: absolute;
  left: 50%; top: 50%;
  width: 14px; height: 14px;
  transform: translate(-50%, -50%);
  background: #1a73e8;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.3);
}

/* compact popup buttons inside leaflet popups */
.leaflet-popup-content { margin: 0.6rem 0.7rem; min-width: 180px; }
.popup-name { font-weight: 700; margin-bottom: 0.1rem; }
.popup-sub { color: var(--muted); font-size: 0.8rem; margin-bottom: 0.4rem; }
.popup-actions { display: flex; gap: 0.3rem; }

/* =================== Detail sheet =================== */
.sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 900;
  background: rgba(20, 20, 20, 0.4);
}
.sheet-backdrop[hidden] { display: none; }

.sheet {
  position: fixed;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  z-index: 1000;
  width: 100%;
  max-width: 520px;
  max-height: 88vh;
  overflow-y: auto;
  overscroll-behavior: contain;   /* keep sheet scrolling from chaining to the page */
  background: var(--card);
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.22);
  padding: 0.5rem 1.15rem 1.5rem;
  animation: sheet-up 0.2s ease;
}
.sheet[hidden] { display: none; }

@keyframes sheet-up {
  from { transform: translate(-50%, 100%); }
  to { transform: translate(-50%, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .sheet { animation: none; }
}

.sheet-grip {
  width: 38px; height: 4px;
  border-radius: 999px;
  background: var(--border);
  margin: 0.2rem auto 0.7rem;
}

.sheet-head { display: flex; align-items: flex-start; gap: 0.6rem; }
.sheet-title { flex: 1; min-width: 0; }
.sheet-title h2 { margin: 0; font-size: 1.2rem; }
.sheet-title .sheet-sub {
  color: var(--muted);
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.2rem;
}
.sheet-title .dot {
  width: 0.6rem; height: 0.6rem;
  border-radius: 50%;
  background: var(--cat);
  flex: none;
}
.sheet-close {
  flex: none;
  border: none;
  background: var(--bg);
  border-radius: 50%;
  width: 2rem; height: 2rem;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  color: var(--muted);
}
.sheet-close:hover { color: var(--text); }

.sheet-photo {
  margin: 0.85rem 0 0;
}
.sheet-photo img {
  display: block;
  width: 100%;
  height: 190px;
  object-fit: cover;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--bg);
}
.sheet-photo figcaption {
  font-size: 0.7rem;
  color: var(--muted);
  margin: 0.3rem 0.1rem 0;
  line-height: 1.3;
}
.sheet-photo figcaption a { color: var(--muted); }

/* Tappable stairway thumbnail → opens the fullscreen lightbox. The ⤢ badge sits
   over the top-right of the image as a zoom affordance. */
.sheet-photo-zoom { position: relative; cursor: zoom-in; }
.sheet-photo-zoom::after {
  content: "⤢";
  position: absolute;
  top: 1.2rem; right: 0.6rem;
  width: 1.7rem; height: 1.7rem;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: rgba(20, 20, 20, 0.55);
  color: #fff;
  font-size: 1rem;
  pointer-events: none;
}

/* Multi-photo gallery: a horizontal, swipeable strip of high-confidence photos
   (generate-images-commons.mjs). Each card keeps the single-photo look but is
   sized to show ~1.2 photos so it's clearly scrollable. */
.sheet-gallery {
  display: flex;
  gap: 0.6rem;
  margin: 0.8rem 0 0;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 0.2rem;
}
.sheet-gallery .sheet-photo {
  margin: 0;
  flex: 0 0 84%;
  scroll-snap-align: start;
}

/* =================== Fullscreen photo lightbox =================== */
/* Layers above the detail sheet (z 1000). Opened by tapping a stairway thumbnail. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1100;
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  padding: 1rem;
}
.lightbox[hidden] { display: none; }
.lightbox-img {
  max-width: 100%;
  max-height: 84vh;
  object-fit: contain;
  border-radius: 6px;
}
.lightbox-credit {
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.8rem;
  line-height: 1.4;
  text-align: center;
  max-width: 520px;
}
.lightbox-credit a { color: #fff; }
.lightbox-close {
  position: absolute;
  top: calc(0.6rem + env(safe-area-inset-top, 0px));
  right: 0.8rem;
  z-index: 1110;
  width: 44px; height: 44px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}
.lightbox-close:hover { background: rgba(255, 255, 255, 0.28); }

.sheet-mini-map {
  height: 150px;
  border-radius: 12px;
  overflow: hidden;
  margin: 0.85rem 0 0;
  border: 1px solid var(--border);
}

.sheet-visit {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.85rem 0 0;
}
.btn-visit {
  flex: 1;
  padding: 0.55rem 0.8rem;
  font-size: 0.95rem;
  font-weight: 600;
  border: 1px solid var(--cat);
  border-radius: 10px;
  background: transparent;
  color: var(--cat);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.btn-visit.on { background: var(--cat); color: #fff; }

.btn-fav {
  flex: none;
  width: 2.6rem;
  padding: 0.55rem 0;
  font-size: 1.2rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  color: var(--border);
  cursor: pointer;
}
.btn-fav.on { color: var(--gold); border-color: var(--gold); }

.rating { display: flex; gap: 0.2rem; margin: 0.5rem 0; }
.rating button {
  border: none;
  background: transparent;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: var(--border);
  padding: 0;
}
.rating button.on { color: var(--gold); }

.sheet label.field-label {
  display: block;
  font-size: 0.8rem;
  color: var(--muted);
  margin: 0.6rem 0 0.25rem;
}
.sheet textarea {
  width: 100%;
  min-height: 70px;
  padding: 0.5rem 0.6rem;
  font-size: 16px;
  font-family: inherit;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
  resize: vertical;
}

.sheet-links { display: flex; gap: 0.5rem; margin-top: 0.8rem; }
.sheet-links a {
  flex: 1;
  text-align: center;
  padding: 0.55rem 0.5rem;
  font-size: 0.88rem;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  color: var(--text);
}
.sheet-links a:hover { border-color: var(--accent); color: var(--accent); }

.visited-at {
  margin-top: 0.6rem;
  font-size: 0.78rem;
  color: var(--muted);
  text-align: center;
}

/* ---- Stairway rating on a stairway's detail sheet (read-only, collapsible) ---- */
.uh-rating {
  margin: 0.85rem 0 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}
/* The always-visible verdict row doubles as the disclosure control. */
.uh-toggle {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: none;
  background: transparent;
  cursor: pointer;
  text-align: left;
  color: var(--text);
  font: inherit;
}
.uh-word {
  font-weight: 700;
  font-size: 1rem;
  color: var(--cat); /* the sheet's accent is the stairway bucket's colour */
}
.uh-src-tag {
  font-size: 0.68rem;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.05rem 0.45rem;
  white-space: nowrap;
}
.uh-chevron {
  margin-left: auto;
  flex: none;
  color: var(--muted);
  transition: transform 0.18s ease;
}
.uh-toggle[aria-expanded="true"] .uh-chevron { transform: rotate(180deg); }

.uh-detail {
  padding: 0 0.75rem 0.7rem;
}
.uh-detail[hidden] { display: none; }
.uh-rating-text {
  margin: 0 0 0.5rem;
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--muted);
}
.uh-rating-link {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
}
.uh-rating-link:hover { text-decoration: underline; }

/* Hairline separating the read-only "about this place" block from the user's own
   review controls below, so the sheet reads as two clear sections. */
.sheet-divider {
  height: 1px;
  background: var(--border);
  margin: 1rem 0 0.2rem;
}

/* Sources tab — rendered from SOURCES.md */
.sources-doc { padding: 1rem 1.1rem; line-height: 1.55; }
.sources-doc h1 { font-size: 1.25rem; margin: 0 0 0.6rem; }
.sources-doc h2 {
  font-size: 1rem;
  margin: 1.1rem 0 0.3rem;
  color: var(--accent);
}
.sources-doc h3 { font-size: 0.92rem; margin: 0.8rem 0 0.2rem; }
.sources-doc p { margin: 0.3rem 0; font-size: 0.9rem; }
.sources-doc ul { margin: 0.3rem 0 0.3rem 1.1rem; padding: 0; }
.sources-doc li { margin: 0.2rem 0; font-size: 0.9rem; }
.sources-doc a { color: var(--accent); }
.sources-doc code {
  background: var(--track);
  padding: 0.05rem 0.3rem;
  border-radius: 5px;
  font-size: 0.85em;
}
.sources-doc hr { border: 0; border-top: 1px solid var(--border); margin: 1rem 0; }
