/* ============================================================
   Howff — Scotland bothy map
   Visual language: weathered enamel signage meets OS map paper.
   Restrained palette, single accent (heather purple), serif display
   pair against a tight humanist sans for body. Texture and weight
   do the differentiating; no shadows-and-gradients filler.
   ============================================================ */

:root {
  color-scheme: light;
  /* Palette — drawn from weathered OS-map / enamel-sign references */
  --ink:        #1a221f;
  --ink-soft:   #3a443f;
  --muted:      #6b7770;
  --line:       rgba(26, 34, 31, 0.12);
  --line-soft:  rgba(26, 34, 31, 0.06);
  --paper:      #f3efe5;
  --paper-warm: #ebe6d7;
  --panel:      rgba(252, 250, 244, 0.94);
  --panel-deep: #fcfaf4;
  --accent:     #6b4f8a; /* heather */
  --accent-ink: #f3efe5;

  /* Source-type colours — saturated enough to read on the map at small
     pin sizes, but muted enough to live next to OS-map cartography. */
  --mba:       #1e5a8a;
  --estate:    #2f7a4a;
  --informal:  #c97a1f;
  --emergency: #b2533f;

  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 22px;

  --shadow-1: 0 1px 2px rgba(26,34,31,0.06), 0 4px 16px rgba(26,34,31,0.08);
  --shadow-2: 0 4px 10px rgba(26,34,31,0.08), 0 18px 36px rgba(26,34,31,0.12);

  --t-fast: 140ms cubic-bezier(0.2, 0.7, 0.2, 1);
  --t-med:  240ms cubic-bezier(0.2, 0.7, 0.2, 1);
  --t-slow: 360ms cubic-bezier(0.19, 1, 0.22, 1);
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
[hidden] { display: none !important; }

body {
  color: var(--ink);
  background: var(--paper);
  font-family: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden; /* the map owns the viewport */
}
body:not(.is-ready) .topbar,
body:not(.is-ready) .locate-fab,
body:not(.is-ready) .admin-fab {
  opacity: 0;
  transform: translate3d(0, 8px, 0);
}
body.is-ready .topbar,
body.is-ready .locate-fab,
body.is-ready .admin-fab {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* Numbers and grid refs read as map data, not body copy. */
.mono {
  font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  font-feature-settings: "ss02", "zero";
  letter-spacing: -0.01em;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Section labels: small caps, tracked, like an old map legend. */
.legend-label {
  font: 700 0.66rem/1 "IBM Plex Sans", sans-serif;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Paper grain — opt-in via .has-grain on chrome panels only. The previous
   version applied it across the whole viewport with mix-blend-mode: multiply,
   which made the map tiles look mangled and patchy. */
.has-grain { position: relative; isolation: isolate; }
.has-grain::before {
  content: "";
  position: absolute; inset: 0;
  z-index: -1;
  pointer-events: none;
  border-radius: inherit;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.1  0 0 0 0 0.13  0 0 0 0 0.12  0 0 0 0.04 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  mix-blend-mode: multiply;
  opacity: 0.5;
}

/* ============================================================
   Loading veil
   ============================================================ */
#loading-veil {
  position: fixed; inset: 0;
  z-index: 9999;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 14px;
  background: var(--paper);
  color: var(--ink);
  transition: opacity var(--t-slow), visibility var(--t-slow);
}
#loading-veil.is-hidden {
  opacity: 0; visibility: hidden;
}
.loading-contours {
  width: 240px; height: auto;
  color: var(--accent);
}
.loading-contours path {
  stroke-dasharray: 320;
  stroke-dashoffset: 320;
  animation: contour-draw 2.4s cubic-bezier(0.16, 0.84, 0.22, 1) forwards;
}
.loading-contours path:nth-child(1) { animation-delay: 0.00s; }
.loading-contours path:nth-child(2) { animation-delay: 0.18s; }
.loading-contours path:nth-child(3) { animation-delay: 0.36s; }
.loading-contours path:nth-child(4) { animation-delay: 0.54s; }
.loading-contours path:nth-child(5) { animation-delay: 0.72s; }
.loading-contours circle {
  opacity: 0;
  animation: contour-summit 0.5s ease-out 1.1s forwards;
}
@keyframes contour-draw {
  to { stroke-dashoffset: 0; }
}
@keyframes contour-summit {
  from { opacity: 0; transform: scale(0.4); transform-origin: 100px 32px; }
  to   { opacity: 1; transform: scale(1);   transform-origin: 100px 32px; }
}
#loading-veil .loading-text {
  margin: 4px 0 0;
  font-family: "Fraunces", Georgia, serif;
  font-size: 1.8rem;
  font-weight: 500;
  letter-spacing: 0.02em;
}
#loading-veil .loading-sub {
  margin: 0;
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
@keyframes pulse {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(0.92); opacity: 0.6; }
}

/* ============================================================
   Map layer
   ============================================================ */
.app {
  position: fixed; inset: 0;
}
#map {
  position: absolute; inset: 0;
  z-index: 1;
  background: #dee5d8;
}

/* Critical Leaflet layout rules, kept locally so the map still renders
   correctly if the CDN stylesheet is slow, stale, or blocked. Without these
   absolute positioning rules the tile grid collapses into the visible
   "jumbled map" failure mode. */
.leaflet-container {
  position: relative;
  overflow: hidden;
  background: #dee5d8;
  outline: 0;
  touch-action: pan-x pan-y;
  font-family: inherit;
}
.leaflet-pane,
.leaflet-map-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
  position: absolute;
  left: 0;
  top: 0;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
  user-select: none;
  -webkit-user-drag: none;
}
.leaflet-tile {
  border: 0;
  max-width: none !important;
  max-height: none !important;
  visibility: hidden;
}
.leaflet-tile-loaded {
  visibility: inherit;
}
.leaflet-container img {
  max-width: none !important;
  max-height: none !important;
}
.leaflet-container a {
  color: var(--ink-soft);
}
.leaflet-control {
  position: relative;
  z-index: 800;
  pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
  position: absolute;
  z-index: 700;
  pointer-events: none;
}
.leaflet-top { top: 0; }
.leaflet-right { right: 0; }
.leaflet-bottom { bottom: 0; }
.leaflet-left { left: 0; }
.leaflet-zoom-animated {
  transform-origin: 0 0;
}
.leaflet-tile-pane { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane { z-index: 500; }
.leaflet-marker-pane { z-index: 600; }
.leaflet-tooltip-pane { z-index: 650; }
.leaflet-popup-pane { z-index: 700; }
.leaflet-map-pane,
.leaflet-tile-pane,
.leaflet-marker-pane,
.leaflet-shadow-pane,
.leaflet-overlay-pane,
.leaflet-tooltip-pane,
.leaflet-popup-pane {
  filter: saturate(0.9) contrast(0.96) brightness(1.04);
}
.leaflet-marker-pane,
.leaflet-shadow-pane,
.leaflet-tooltip-pane,
.leaflet-popup-pane {
  filter: none;
}
.leaflet-tile {
  opacity: 0;
  transition: opacity 180ms ease-out;
}
.leaflet-tile-loaded {
  opacity: 1;
}

/* Push the top-right corner controls (layer switcher) below the topbar so
   it doesn't collide with the list-toggle button. */
.leaflet-top.leaflet-right { top: 72px; right: 12px; }
.leaflet-control-layers {
  background: var(--panel) !important;
  border: 1px solid var(--line) !important;
  border-radius: var(--radius-md) !important;
  box-shadow: var(--shadow-1) !important;
  color: var(--ink);
  font: 600 0.78rem/1 "IBM Plex Sans", sans-serif;
  backdrop-filter: blur(18px) saturate(1.05);
  transition: opacity var(--t-med), transform var(--t-med), box-shadow var(--t-fast);
}
.leaflet-control-layers:not(.leaflet-control-layers-expanded) { opacity: 0.86; }
.leaflet-control-layers-toggle { width: 36px !important; height: 36px !important; }
.leaflet-control-layers-list { padding: 8px 12px; }
.leaflet-control-layers label { padding: 4px 0; cursor: pointer; }
.leaflet-control-layers input[type="radio"] { accent-color: var(--accent); margin-right: 6px; }
.leaflet-control-attribution {
  background: rgba(252, 250, 244, 0.78);
  color: var(--muted);
  font-size: 10px;
  padding: 2px 8px;
}
.leaflet-control-attribution a { color: var(--ink-soft); }
.leaflet-control-zoom {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: visible;
  box-shadow: var(--shadow-1);
  display: flex;
  gap: 6px;
  background: transparent;
}
.leaflet-control-zoom a {
  display: grid !important;
  place-items: center;
  background: var(--panel);
  color: var(--ink);
  border: 1px solid var(--line-soft) !important;
  border-radius: var(--radius-sm) !important;
  font: 700 20px/1 "IBM Plex Sans", sans-serif;
  width: 40px;
  height: 40px;
  box-shadow: var(--shadow-1);
  backdrop-filter: blur(16px);
}

/* ============================================================
   Pins — concentric contour rings, evoking an OS-map summit symbol.
   Source colour drives the rings; status modifies the composition.
   ============================================================ */
.pin-wrap {
  position: absolute;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  cursor: pointer;
  --pin-c: var(--mba);
  opacity: 1;
  transition: opacity 160ms ease-out;
}
.pin-wrap:hover .pin { transform: translateY(-3px) scale(1.06); }
.pin-wrap.is-active {
  z-index: 2;
}
.pin-wrap.is-active .pin { transform: translateY(-5px) scale(1.16); }

.pin {
  position: relative;
  width: 26px; height: 26px;
  transition: transform var(--t-med), filter var(--t-fast);
  filter: drop-shadow(0 3px 6px rgba(26,34,31,0.18));
}
/* Three rings + centre dot. Outer ring is the source colour at full strength,
   middle is mixed with paper, inner ring is a thin shadow of the same.
   Centre dot is white with a coloured pip to read at distance. */
.pin::before,
.pin::after,
.pin > .pin-ring {
  content: "";
  position: absolute; left: 50%; top: 50%;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.pin::before {
  width: 26px; height: 26px;
  border: 2px solid var(--pin-c);
  background: color-mix(in srgb, var(--pin-c) 12%, var(--paper));
  box-shadow: 0 2px 5px rgba(26,34,31,0.22);
}
.pin > .pin-ring {
  width: 18px; height: 18px;
  border: 1.5px solid var(--pin-c);
  background: color-mix(in srgb, var(--pin-c) 22%, var(--paper));
}
.pin::after {
  width: 8px; height: 8px;
  background: var(--pin-c);
  border: 1.5px solid var(--paper);
}

/* Source colours */
.pin-source-mba       { --pin-c: var(--mba); }
.pin-source-estate    { --pin-c: var(--estate); }
.pin-source-informal  { --pin-c: var(--informal); }
.pin-source-emergency {
  --pin-c: var(--emergency);
}
/* Emergency: solid square waypoint, not a summit symbol. */
.pin-source-emergency .pin::before,
.pin-source-emergency .pin > .pin-ring,
.pin-source-emergency .pin::after {
  border-radius: 2px;
}
.pin-source-emergency .pin::before { transform: translate(-50%,-50%) rotate(45deg); }
.pin-source-emergency .pin > .pin-ring { transform: translate(-50%,-50%) rotate(45deg); }

/* Status modifiers */
.pin-status-coming_soon .pin::before { border-style: dashed; }
.pin-status-under_construction .pin > .pin-ring {
  border-style: dashed;
}
.pin-status-permanently_closed { --pin-c: var(--muted); opacity: 0.7; }
.pin-status-permanently_closed .pin::after {
  background: transparent;
  border: 0;
  width: 16px; height: 2px;
  border-radius: 1px;
  transform: translate(-50%,-50%) rotate(-45deg);
  background: var(--muted);
}
.pin-status-temp_closed { --pin-c: var(--muted); }
.pin-status-temp_closed .pin::before { border-style: dotted; }

/* Cluster restyle to match contour-ring aesthetic */
.marker-cluster-small,
.marker-cluster-medium,
.marker-cluster-large {
  display: grid;
  place-items: center;
  width: 34px !important;
  height: 34px !important;
  margin-left: -17px !important;
  margin-top: -17px !important;
  border-radius: 50%;
  background: rgba(107, 79, 138, 0.18) !important;
}
.marker-cluster-small div,
.marker-cluster-medium div,
.marker-cluster-large div {
  display: block;
  width: 28px;
  height: 28px;
  margin: 0;
  border: 2px solid #fff;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font: 700 12px/24px "IBM Plex Sans", sans-serif;
  text-align: center;
  box-shadow: 0 3px 9px rgba(26,34,31,0.18);
}
body.is-rendering-markers .leaflet-marker-pane {
  opacity: 0.72;
  transition: opacity 120ms ease-out;
}

/* User location pin */
.you-pin {
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--accent);
  border: 3px solid #fff;
  box-shadow: 0 0 0 6px rgba(107, 79, 138, 0.18), 0 4px 12px rgba(26,34,31,0.32);
  animation: pulse 2s ease-in-out infinite;
}

/* ============================================================
   Topbar
   ============================================================ */
.topbar {
  position: absolute;
  top: 12px; left: 12px; right: 12px;
  z-index: 500;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 12px;
  pointer-events: none;
  transition: opacity 420ms ease-out, transform 420ms var(--t-slow);
}
.topbar > * { pointer-events: auto; }

.brand {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 8px 14px 8px 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-1);
  backdrop-filter: blur(18px) saturate(1.05);
}
.brand svg { width: 30px; height: 30px; color: var(--accent); flex: 0 0 auto; }
.brand-text { display: flex; flex-direction: column; line-height: 1; }
.brand-eyebrow {
  color: var(--muted);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.brand-wordmark {
  margin-top: 2px;
  font-family: "Fraunces", "Source Serif 4", Georgia, serif;
  font-size: 1.55rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.filter-bar {
  display: flex; flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow-1);
  backdrop-filter: blur(18px) saturate(1.05);
}
.filter-divider {
  width: 1px; height: 18px;
  background: var(--line);
  margin: 0 2px;
}
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 12px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  font: 600 0.78rem/1 "IBM Plex Sans", sans-serif;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast), opacity var(--t-fast);
}
.chip:hover { background: rgba(26,34,31,0.04); }
.chip.is-active {
  background: var(--ink);
  color: var(--paper);
}
.chip.is-active .dot { box-shadow: 0 0 0 2px var(--ink); }
.chip-source:not(.is-active) { opacity: 0.55; }
.chip-toggle[aria-pressed="true"] {
  background: var(--accent);
  color: var(--accent-ink);
}

.dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  transition: box-shadow var(--t-fast);
}
.dot-mba       { background: var(--mba); }
.dot-estate    { background: var(--estate); }
.dot-informal  { background: var(--informal); }
.dot-emergency { background: var(--emergency); }

.list-toggle {
  display: inline-flex; align-items: center; gap: 8px;
  height: 44px; padding: 0 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-1);
  color: var(--ink);
  font: 600 0.85rem/1 "IBM Plex Sans", sans-serif;
  cursor: pointer;
  backdrop-filter: blur(18px) saturate(1.05);
  transition: opacity 420ms ease-out 60ms, transform var(--t-fast), box-shadow var(--t-fast);
}
.list-toggle:hover { transform: translateY(-1px); box-shadow: var(--shadow-2); }
.list-toggle svg { width: 18px; height: 18px; color: var(--ink-soft); }
.list-toggle strong { color: var(--accent); font-weight: 700; }

/* ============================================================
   Locate FAB
   ============================================================ */
.locate-fab {
  position: absolute;
  left: 16px;
  bottom: calc(env(safe-area-inset-bottom, 0) + 80px);
  z-index: 500;
  width: 48px; height: 48px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--panel-deep);
  color: var(--ink);
  cursor: pointer;
  box-shadow: var(--shadow-1);
  display: grid; place-items: center;
  transition: opacity 420ms ease-out 90ms, transform var(--t-fast), box-shadow var(--t-fast);
}
.locate-fab:hover { transform: scale(1.05); box-shadow: var(--shadow-2); }
.locate-fab.is-active { color: var(--accent); }
.locate-fab svg { width: 22px; height: 22px; }

.map-mode-switch {
  position: absolute;
  left: 16px;
  bottom: calc(env(safe-area-inset-bottom, 0) + 16px);
  z-index: 520;
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  box-shadow: var(--shadow-1);
  backdrop-filter: blur(18px) saturate(1.05);
}
.map-mode-switch button {
  height: 34px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  font: 700 0.74rem/1 "IBM Plex Sans", sans-serif;
  cursor: pointer;
}
.map-mode-switch button.is-active {
  background: var(--ink);
  color: var(--paper);
}

/* ============================================================
   Sync pill
   ============================================================ */
.sync-pill {
  position: absolute;
  right: 16px;
  bottom: calc(env(safe-area-inset-bottom, 0) + 16px);
  z-index: 500;
  padding: 6px 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow-1);
  color: var(--muted);
  font: 600 0.72rem/1 "IBM Plex Sans", sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  backdrop-filter: blur(14px);
  opacity: 0;
  transition: opacity var(--t-med);
}
.sync-pill.is-visible { opacity: 1; }
.sync-pill.is-error { color: var(--emergency); }

/* ============================================================
   List panel — slide-up sheet on mobile, side panel on desktop
   ============================================================ */
.list-panel {
  position: absolute;
  z-index: 800;
  background: var(--panel-deep);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-2);
  display: flex; flex-direction: column;
  transform: translate3d(0, 110%, 0);
  transition: transform var(--t-slow), opacity var(--t-slow);
  opacity: 0;
  will-change: transform, opacity;
  contain: layout paint style;
  backface-visibility: hidden;
}
.list-panel:not([hidden]) {
  display: flex;
}
.list-panel.is-open {
  transform: translate3d(0, 0, 0);
  opacity: 1;
}

/* Desktop: docked left, full height */
@media (min-width: 880px) {
  .list-panel {
    top: 76px; left: 12px; bottom: 12px;
    width: 380px;
    border-radius: var(--radius-md);
    transform: translate3d(-110%, 0, 0);
  }
  .list-panel.is-open { transform: translate3d(0, 0, 0); }
}

/* Mobile: bottom sheet, ~75svh */
@media (max-width: 879px) {
  .list-panel {
    left: 0; right: 0; bottom: 0;
    height: 78svh;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-bottom: 0;
  }
}

.list-panel-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 12px 10px;
  border-bottom: 1px solid var(--line-soft);
}
.search {
  flex: 1;
  display: inline-flex; align-items: center; gap: 8px;
  height: 40px; padding: 0 12px;
  background: var(--paper-warm);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  color: var(--muted);
  transition: border-color var(--t-fast), background var(--t-fast);
}
.search:focus-within { border-color: var(--accent); background: var(--paper); }
.search svg { width: 16px; height: 16px; flex: 0 0 auto; }
.search input {
  flex: 1; min-width: 0;
  border: 0; outline: 0;
  background: transparent;
  color: var(--ink);
  font: 500 0.95rem/1 "IBM Plex Sans", sans-serif;
}
.search input::placeholder { color: var(--muted); }

.icon-btn {
  display: grid; place-items: center;
  width: 40px; height: 40px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.icon-btn:hover { background: rgba(26,34,31,0.06); color: var(--ink); }
.icon-btn svg { width: 18px; height: 18px; }

.list-panel-meta {
  padding: 8px 16px 6px;
  display: flex; justify-content: space-between;
  font-size: 0.72rem; color: var(--muted);
  font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
}

.bothy-list {
  flex: 1; overflow-y: auto;
  margin: 0; padding: 4px 0 12px;
  list-style: none;
  scroll-behavior: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  contain: content;
}
.bothy-list-item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 12px;
  padding: 10px 14px;
  cursor: pointer;
  border-left: 3px solid transparent;
  opacity: 0;
  transform: translate3d(0, 4px, 0);
  animation: row-in 220ms ease-out forwards;
  animation-delay: calc(var(--row-i, 0) * 14ms);
  transition: background var(--t-fast), border-color var(--t-fast), transform var(--t-fast);
}
.bothy-list-item:hover {
  background: rgba(107, 79, 138, 0.06);
  transform: translate3d(2px, 0, 0);
}
.bothy-list-item.is-active {
  background: rgba(107, 79, 138, 0.10);
  border-left-color: var(--accent);
}
.bothy-thumb {
  width: 56px; height: 56px;
  border-radius: var(--radius-sm);
  background: var(--paper-warm) center/cover no-repeat;
  border: 1px solid var(--line-soft);
  flex: 0 0 auto;
  position: relative;
  overflow: hidden;
}
.bothy-thumb.no-photo::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(135deg, var(--paper-warm), var(--paper));
}
.bothy-thumb.no-photo::after {
  content: "";
  position: absolute; left: 50%; top: 50%;
  width: 18px; height: 18px;
  margin: -9px 0 0 -9px;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  border: 2px solid var(--muted);
}
.bothy-row-body { min-width: 0; }
.bothy-row-name {
  margin: 0;
  font: 600 0.95rem/1.2 "IBM Plex Sans", sans-serif;
  color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bothy-row-sub {
  margin: 2px 0 6px;
  font-size: 0.78rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bothy-row-tags {
  display: flex; flex-wrap: wrap; gap: 4px;
}
.tag {
  display: inline-flex; align-items: center;
  height: 18px; padding: 0 6px;
  border-radius: 4px;
  font: 700 0.62rem/1 "IBM Plex Sans", sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.tag-source-mba       { background: rgba(30, 90, 138, 0.14);  color: var(--mba); }
.tag-source-estate    { background: rgba(47, 122, 74, 0.14);  color: var(--estate); }
.tag-source-informal  { background: rgba(201, 122, 31, 0.16); color: var(--informal); }
.tag-source-emergency { background: rgba(178, 83, 63, 0.16);  color: var(--emergency); }
.tag-status-coming_soon         { background: rgba(107, 79, 138, 0.14); color: var(--accent); }
.tag-status-under_construction  { background: rgba(201, 122, 31, 0.16); color: var(--informal); }
.tag-status-permanently_closed  { background: rgba(107, 119, 112, 0.20); color: var(--muted); }
.tag-status-temp_closed         { background: rgba(178, 83, 63, 0.14); color: var(--emergency); }

.bothy-row-aside {
  display: flex; flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex: 0 0 auto;
}
.bothy-row-dist {
  font: 700 0.78rem/1 "IBM Plex Sans", sans-serif;
  color: var(--accent);
}
.bothy-row-aside .check {
  width: 16px; height: 16px;
  display: grid; place-items: center;
  font-size: 11px;
  border-radius: 50%;
  background: rgba(47, 122, 74, 0.18);
  color: var(--estate);
}

/* ============================================================
   Detail drawer
   ============================================================ */
.detail-drawer {
  position: absolute;
  z-index: 850;
  background: var(--panel-deep);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-2);
  display: flex; flex-direction: column;
  transform: translate3d(110%, 0, 0);
  opacity: 0;
  transition: transform var(--t-slow), opacity var(--t-slow);
  overflow: hidden;
  will-change: transform, opacity;
  contain: layout paint style;
  backface-visibility: hidden;
}
.detail-drawer:not([hidden]) { display: flex; }
.detail-drawer.is-open { transform: translate3d(0, 0, 0); opacity: 1; }

@media (min-width: 880px) {
  .detail-drawer {
    top: 76px; right: 12px; bottom: 12px;
    width: 420px;
    border-radius: var(--radius-md);
  }
}
@media (max-width: 879px) {
  .detail-drawer {
    left: 0; right: 0; bottom: 0;
    height: 82svh;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    transform: translate3d(0, 110%, 0);
    border-bottom: 0;
  }
  .detail-drawer.is-open { transform: translate3d(0, 0, 0); }
}

.detail-close {
  position: absolute;
  top: 14px; right: 14px;
  z-index: 5;
  background: rgba(252, 250, 244, 0.92);
  border-color: var(--line);
  backdrop-filter: blur(8px);
}

#detail-body {
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  contain: content;
}

.detail-hero {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--paper-warm) center/cover no-repeat;
  border-bottom: 1px solid var(--line-soft);
}
.detail-hero.no-photo {
  display: grid; place-items: center;
  background: linear-gradient(135deg, var(--paper-warm), var(--paper));
}
.detail-hero.no-photo::after {
  content: "No photo yet";
  font: 600 0.78rem/1 "IBM Plex Sans", sans-serif;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted);
}
.detail-hero-gradient {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 70%;
  background: linear-gradient(to top, rgba(26,34,31,0.62), transparent);
}
.detail-hero-credit {
  position: absolute;
  left: 12px; bottom: 10px;
  font-size: 0.66rem; color: rgba(255,255,255,0.84);
  font-weight: 500;
  text-shadow: 0 1px 2px rgba(0,0,0,0.4);
}
.detail-hero-credit a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

.detail-body {
  padding: 18px 20px 28px;
}
.detail-tags {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-bottom: 10px;
}
.detail-tags .tag { height: 22px; padding: 0 8px; font-size: 0.68rem; }

.detail-title {
  margin: 6px 0 4px;
  font-family: "Fraunces", "Source Serif 4", Georgia, serif;
  font-size: 1.85rem;
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.01em;
}
.detail-place {
  margin: 0 0 16px;
  color: var(--muted);
  font-size: 0.92rem;
}

.banner {
  display: flex; gap: 10px;
  padding: 10px 12px;
  margin-bottom: 14px;
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  line-height: 1.4;
}
.banner-stalking { background: rgba(178, 83, 63, 0.10); border: 1px solid rgba(178, 83, 63, 0.22); color: var(--emergency); }
.banner-verify   { background: rgba(201, 122, 31, 0.10); border: 1px solid rgba(201, 122, 31, 0.22); color: var(--informal); }
.banner-closed   { background: rgba(107, 119, 112, 0.16); border: 1px solid rgba(107, 119, 112, 0.30); color: var(--ink-soft); }
.banner svg { width: 16px; height: 16px; flex: 0 0 auto; margin-top: 2px; }

.detail-notes {
  margin: 0 0 16px;
  color: var(--ink-soft);
  font-size: 0.94rem; line-height: 1.55;
}

.meta-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 10px 14px;
  margin: 0 0 18px;
  padding: 12px 14px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
}
.meta-grid > div { min-width: 0; }
.meta-grid dt {
  font: 700 0.62rem/1 "IBM Plex Sans", sans-serif;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 3px;
}
.meta-grid dd {
  margin: 0;
  font-size: 0.92rem; font-weight: 600;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.section-title {
  margin: 0 0 8px;
  font: 700 0.66rem/1 "IBM Plex Sans", sans-serif;
  letter-spacing: 0.10em; text-transform: uppercase;
  color: var(--muted);
}

.amenity-list {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px 10px;
}
.amenity {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px;
  border-radius: var(--radius-xs);
  background: var(--paper);
  font-size: 0.86rem;
  border: 1px solid var(--line-soft);
}
.amenity .amenity-mark {
  flex: 0 0 auto;
  width: 16px; height: 16px;
  display: grid; place-items: center;
  font-size: 10px;
  border-radius: 50%;
}
.amenity-yes .amenity-mark      { background: rgba(47, 122, 74, 0.20);  color: var(--estate); }
.amenity-no .amenity-mark       { background: rgba(178, 83, 63, 0.18);  color: var(--emergency); }
.amenity-unknown                { color: var(--muted); }
.amenity-unknown .amenity-mark  { background: rgba(107, 119, 112, 0.16); color: var(--muted); }
.amenity-detail { color: var(--muted); font-size: 0.78rem; margin-left: 4px; }

.munro-line {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  margin-bottom: 14px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  font-size: 0.88rem; color: var(--ink-soft);
}
.munro-line strong { color: var(--ink); }
.munro-line svg { width: 18px; height: 18px; color: var(--accent); flex: 0 0 auto; }

.verify-row {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-bottom: 18px;
}
.verify-badge {
  display: inline-flex; align-items: center; gap: 5px;
  height: 22px; padding: 0 8px;
  border-radius: 4px;
  font: 700 0.66rem/1 "IBM Plex Sans", sans-serif;
  letter-spacing: 0.04em; text-transform: uppercase;
}
.verify-badge.ok  { background: rgba(47, 122, 74, 0.14);  color: var(--estate); }
.verify-badge.no  { background: rgba(107, 119, 112, 0.14); color: var(--muted); }
.verify-badge::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: currentColor;
}

.detail-actions {
  display: flex; flex-direction: column; gap: 8px;
}
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 42px; padding: 0 16px;
  border-radius: var(--radius-sm);
  font: 600 0.88rem/1 "IBM Plex Sans", sans-serif;
  cursor: pointer; text-decoration: none;
  transition: transform var(--t-fast), background var(--t-fast), box-shadow var(--t-fast);
  border: 1px solid var(--line);
}
.btn:hover { transform: translateY(-1px); }
.btn-primary {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.btn-primary:hover { background: var(--accent); border-color: var(--accent); }
.btn-secondary {
  background: transparent;
  color: var(--ink);
}
.btn-secondary:hover { background: rgba(26,34,31,0.04); }
.btn svg { width: 16px; height: 16px; }

/* ============================================================
   Small-screen adjustments
   ============================================================ */
@media (max-width: 879px) {
  .topbar {
    grid-template-columns: auto auto;
    gap: 8px;
  }
  .filter-bar {
    grid-column: 1 / -1;
    order: 3;
    justify-content: flex-start;
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none;
    border-radius: var(--radius-md);
  }
  .filter-bar::-webkit-scrollbar { display: none; }
  .brand { padding: 6px 12px 6px 8px; }
  .brand svg { width: 26px; height: 26px; }
  .brand-wordmark { font-size: 1.35rem; }
  .brand-eyebrow { font-size: 0.58rem; }
  .list-toggle { height: 40px; padding: 0 12px; font-size: 0.78rem; }
  .leaflet-top.leaflet-right {
    display: none;
  }
  .leaflet-bottom.leaflet-right {
    right: 14px;
    bottom: calc(env(safe-area-inset-bottom, 0) + 14px);
  }
  .leaflet-control-zoom a {
    width: 42px;
    height: 42px;
    font-size: 21px;
    line-height: 1;
  }
  .locate-fab {
    bottom: calc(env(safe-area-inset-bottom, 0) + 70px);
  }
  .meta-grid { grid-template-columns: 1fr 1fr; }
  .amenity-list { grid-template-columns: 1fr; }
}

/* ============================================================
   Admin mode
   ============================================================ */

/* Lock FAB — bottom-left, mirrors the locate FAB style */
.admin-fab {
  position: fixed;
  left: 16px;
  bottom: calc(env(safe-area-inset-bottom, 0) + 144px);
  z-index: 900;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: var(--panel);
  box-shadow: var(--shadow-1);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  transition: color var(--t-fast), background var(--t-fast), box-shadow var(--t-fast);
}
.admin-fab svg { width: 18px; height: 18px; }
.admin-fab:hover { color: var(--ink); box-shadow: var(--shadow-2); }

@media (max-width: 879px) {
  .admin-fab {
    bottom: calc(env(safe-area-inset-bottom, 0) + 136px);
  }
}

/* Mode banner — thin bar below topbar */
.admin-banner {
  position: fixed;
  top: 60px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 900;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px 6px 10px;
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: var(--radius-lg);
  font-size: 0.78rem;
  font-weight: 600;
  box-shadow: var(--shadow-2);
  white-space: nowrap;
}
.admin-banner svg { width: 14px; height: 14px; flex-shrink: 0; }
.admin-banner-exit {
  margin-left: 6px;
  padding: 2px 10px;
  border-radius: var(--radius-sm);
  border: 1.5px solid rgba(255,255,255,0.45);
  background: transparent;
  color: var(--accent-ink);
  font-size: 0.72rem;
  font-weight: 700;
  cursor: pointer;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  transition: background var(--t-fast);
}
.admin-banner-exit:hover { background: rgba(255,255,255,0.2); }

/* Pin confirm bar — floats above the map, below the banner */
.pin-confirm {
  position: fixed;
  top: 110px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 900;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  background: var(--panel-deep);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  font-size: 0.82rem;
  white-space: nowrap;
}
.pin-confirm-name { font-weight: 600; color: var(--ink); }
.pin-confirm-actions { display: flex; gap: 8px; }

/* Small button variants */
.btn-sm { padding: 5px 12px; font-size: 0.78rem; }
.btn-ghost {
  background: transparent;
  border: 1.5px solid var(--line);
  color: var(--ink-soft);
  border-radius: var(--radius-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--t-fast);
}
.btn-ghost:hover { background: var(--paper-warm); }

/* Draggable marker cursor */
.leaflet-marker-draggable { cursor: grab !important; }
.leaflet-marker-draggable:active { cursor: grabbing !important; }

/* Login dialog — <dialog> renders in the browser top layer */
.admin-dialog {
  position: fixed; /* fallback layout hint */
  border: none;
  border-radius: var(--radius-md);
  padding: 32px 28px 28px;
  width: min(340px, calc(100vw - 32px));
  background: var(--panel-deep);
  box-shadow: var(--shadow-2);
  color: var(--ink);
}
.admin-dialog::backdrop {
  background: rgba(26, 34, 31, 0.5);
  backdrop-filter: blur(3px);
}
.admin-modal-title {
  font-family: "Fraunces", serif;
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0 0 20px;
  color: var(--ink);
}
.admin-pw-input {
  width: 100%;
  padding: 10px 12px;
  margin-bottom: 12px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  font-family: inherit;
  background: var(--paper);
  color: var(--ink);
  outline: none;
  transition: border-color var(--t-fast);
}
.admin-pw-input:focus { border-color: var(--accent); }
.admin-modal-err {
  margin: 10px 0 0;
  color: var(--emergency);
  font-size: 0.82rem;
  font-weight: 600;
}
.admin-modal-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  border-radius: var(--radius-xs);
}
.admin-modal-close svg { width: 16px; height: 16px; }
.admin-modal-close:hover { color: var(--ink); background: var(--paper-warm); }

@keyframes row-in {
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}
