/* ==========================================================================
   Explore the Delta

   Loaded only on the map experience template. Everything is fixed-position
   chrome over a full-viewport canvas, so this sheet does not participate in
   the page flow that pages.css and templates.css describe.
   ========================================================================== */

html.wo-delta,
html.wo-delta body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

html.wo-delta body {
  /* Never seen: the stage covers the viewport. Here so a failed load is dark
     rather than white. */
  background-color: #04090c;
  margin: 0;
}

/*
 * The map is the viewport. The labels layer is given the identical box, so a
 * projected screen position means the same thing in both.
 */
.xp-stage,
.xp-pins {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  min-width: 100vw;
  min-height: 100vh;
}

.xp-stage {
  overflow: hidden;
  background-color: #050d12;
}

.xp-stage canvas {
  display: block;
  cursor: grab;
  /* Without this the browser claims the gesture and the map fights the page's
     own pan and zoom. */
  touch-action: none;
}

.xp-stage canvas:active { cursor: grabbing; }

/*
 * Atmospheric fall-off at the frame edge. The camera is near enough to
 * vertical that scene fog has almost no depth to work with, so the haze is
 * done in screen space, where it can be tuned against the artwork.
 */
.xp-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background:
    radial-gradient(120% 100% at 50% 50%, rgba(6, 15, 20, 0) 55%, rgba(6, 15, 20, 0.5) 100%),
    linear-gradient(to bottom, rgba(6, 15, 20, 0.35), rgba(6, 15, 20, 0) 22%);
}

/* ---------- Intro overlay ---------- */
.xp-intro {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  text-align: center;
  padding: var(--space-8);
  background-color: rgba(3, 12, 10, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: opacity 700ms ease, visibility 700ms;
}

.xp-intro.is-hidden { opacity: 0; visibility: hidden; }

.xp-intro__eyebrow {
  font-size: var(--fs-badge);
  font-weight: var(--fw-bold);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--color-gold-light);
}

.xp-intro__title {
  max-width: 22ch;
  margin: var(--space-6) auto 0;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.3rem + 2.6vw, 3.9rem);
  font-weight: var(--fw-regular);
  line-height: 1.12;
  text-wrap: balance;
  color: var(--color-cream);
}

.xp-intro__title em { font-style: normal; color: var(--color-accent); }

.xp-intro__lead {
  max-width: 46ch;
  margin: var(--space-6) auto 0;
  font-size: var(--fs-lead);
  line-height: 1.65;
  color: var(--color-muted);
}

.xp-intro__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: center;
  margin-top: var(--space-10);
}

.xp-intro__progress {
  margin-top: var(--space-8);
  font-size: var(--fs-small);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: rgba(248, 243, 237, 0.4);
}

/* ---------- Side panel ---------- */
.xp-panel {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 50;
  width: min(468px, 100vw);
  height: 100%;
  display: flex;
  flex-direction: column;
  background-color: rgba(8, 22, 18, 0.86);
  backdrop-filter: blur(26px) saturate(130%);
  -webkit-backdrop-filter: blur(26px) saturate(130%);
  border-left: 1px solid rgba(174, 124, 53, 0.42);
  transform: translateX(100%);
  visibility: hidden;
  transition: transform 520ms cubic-bezier(0.22, 1, 0.36, 1), visibility 520ms;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .xp-panel { background-color: rgb(7, 20, 16); }
}

.xp-panel.is-open { transform: none; visibility: visible; }

.xp-panel__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-8) var(--space-8) var(--space-6);
  border-bottom: 1px solid var(--border-hairline);
}

.xp-panel__type {
  font-size: var(--fs-badge);
  font-weight: var(--fw-bold);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-gold-light);
}

.xp-panel__title {
  margin-top: var(--space-3);
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.4rem + 1vw, 2.5rem);
  font-weight: var(--fw-regular);
  line-height: 1.1;
  color: var(--color-cream);
}

.xp-panel__close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: 1px solid rgba(174, 124, 53, 0.45);
  color: var(--color-cream);
  transition: border-color var(--transition), background-color var(--transition);
}

.xp-panel__close:hover,
.xp-panel__close:focus-visible {
  border-color: var(--color-gold);
  background-color: rgba(174, 124, 53, 0.2);
}

.xp-panel__body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-8);
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.xp-panel__lead { font-size: var(--fs-lead); line-height: 1.55; color: var(--color-cream); }
.xp-panel__lead:empty { display: none; }

.xp-panel__text { margin-top: var(--space-4); font-size: var(--fs-body); line-height: 1.75; color: var(--color-muted); }
.xp-panel__text:empty { display: none; }

.xp-panel__facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6);
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--border-hairline);
}

.xp-panel__facts:empty { display: none; }
.xp-panel__facts dt { font-size: var(--fs-badge); letter-spacing: 0.14em; text-transform: uppercase; color: rgba(248, 243, 237, 0.45); }
.xp-panel__facts dd { margin: 4px 0 0; font-family: var(--font-display); font-size: 1.05rem; color: var(--color-cream); }

.xp-panel__actions {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-6) var(--space-8) calc(var(--space-8) + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border-hairline);
}

/* ---------- Controls ---------- */
/* Bottom right, because the compass has the bottom left and the explore
   control has the middle — the same three corners the artwork used. */
.xp-controls {
  position: fixed;
  right: clamp(1rem, 3vw, 2.6rem);
  bottom: calc(clamp(1rem, 3vw, 2.2rem) + env(safe-area-inset-bottom));
  z-index: 30;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
}

.xp-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 46px;
  padding: 0 var(--space-6);
  background-color: rgba(3, 14, 11, 0.6);
  border: 1px solid rgba(174, 124, 53, 0.45);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-soft);
  transition: border-color var(--transition), background-color var(--transition), color var(--transition);
}

.xp-btn:hover,
.xp-btn:focus-visible { border-color: var(--color-gold); color: var(--color-white); }

.xp-btn[aria-pressed="true"] {
  background-color: rgba(174, 124, 53, 0.28);
  border-color: var(--color-gold);
  color: var(--color-white);
}

.xp-btn svg.lucide { width: 1.05rem; height: 1.05rem; color: var(--color-gold-light); }

.xp-phase {
  display: flex;
  border: 1px solid rgba(174, 124, 53, 0.45);
  background-color: rgba(3, 14, 11, 0.6);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.xp-phase button {
  min-height: 46px;
  padding: 0 var(--space-4);
  font-size: var(--fs-small);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  transition: background-color var(--transition), color var(--transition);
}

.xp-phase button:hover,
.xp-phase button:focus-visible { color: var(--color-white); }
.xp-phase button[aria-pressed="true"] { background-color: rgba(174, 124, 53, 0.3); color: var(--color-white); }

/* ---------- Fallback ---------- */
.xp-fallback {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: none;
  place-items: center;
  padding: var(--space-8);
  background-color: #030c0a;
  text-align: center;
}

.xp-fallback.is-visible { display: grid; }

.xp-fallback__map {
  display: block;
  width: min(520px, 100%);
  margin: 0 auto var(--space-8);
  opacity: 0.55;
}

/* ---------- UI scrim ----------
   The supplied artwork had a dark gradient burned across its top and bottom so
   the title and the pill would read. That belongs here, on the screen, rather
   than in the texture: prep divided it back out of the pixels, and this puts
   it back where it stays still while the terrain moves under it. */
.xp-scrim {
  position: fixed;
  inset: 0;
  z-index: 15;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(3, 12, 10, 0.55) 0, rgba(3, 12, 10, 0) 22%),
    linear-gradient(to top, rgba(3, 12, 10, 0.5) 0, rgba(3, 12, 10, 0) 20%);
}

/* ---------- Top chrome ---------- */
.xp-top {
  position: fixed;
  inset: 0 0 auto;
  z-index: 40;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: var(--space-4);
  padding: clamp(0.9rem, 2.2vw, 1.6rem) clamp(1rem, 3vw, 2.6rem);
  pointer-events: none;
}

.xp-top > * { pointer-events: auto; }
.xp-top__left { display: flex; flex-direction: column; align-items: flex-start; }
.xp-top__right { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-6); }

.xp-top__btn {
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(248, 243, 237, 0.78);
  background: none;
  border: 0;
  padding: 6px 2px;
  transition: color var(--transition);
}

.xp-top__btn:hover,
.xp-top__btn:focus-visible { color: var(--color-white); }

.xp-back {
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  color: rgba(248, 243, 237, 0.7);
  transition: color var(--transition);
}

.xp-back:hover,
.xp-back:focus-visible { color: var(--color-accent); }
.xp-back svg.lucide { width: 1.05rem; height: 1.05rem; }

.xp-title { text-align: center; }

.xp-title h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.4vw, 1.85rem);
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-white);
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.5);
}

.xp-title p {
  margin: 5px 0 0;
  font-size: clamp(0.6rem, 1vw, 0.72rem);
  letter-spacing: 0.08em;
  color: rgba(248, 243, 237, 0.62);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.55);
}

/* ---------- Legend ----------
   Part of the top-left block rather than a floating panel, as the design has
   it: brand, then the legend under it, open by default. */
.xp-legend {
  margin-top: var(--space-4);
  max-width: 260px;
}

.xp-legend__toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  background: none;
  border: 0;
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(248, 243, 237, 0.72);
  transition: color var(--transition);
}

.xp-legend__toggle:hover,
.xp-legend__toggle:focus-visible { color: var(--color-white); }

.xp-legend__toggle svg.lucide {
  width: 0.85rem;
  height: 0.85rem;
  transform: rotate(180deg);
  transition: transform var(--transition);
}

.xp-legend__toggle[aria-expanded="false"] svg.lucide { transform: none; }

.xp-legend__body {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height var(--transition), opacity var(--transition), margin var(--transition);
}

.xp-legend.is-open .xp-legend__body {
  max-height: 420px;
  opacity: 1;
  margin-top: var(--space-3);
}

.xp-legend__keys { margin: 0; padding: 0; list-style: none; display: grid; gap: 7px; }

.xp-legend__keys li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.64rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 243, 237, 0.8);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.6);
}

.xp-legend__key {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: #f4f1ea;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4);
}

.xp-legend__key--wildlife { background-color: #d8b46a; }
.xp-legend__key--expedition { background-color: #8fbfa0; }
.xp-legend__key--viewpoint { background-color: #9ec8dd; }
.xp-legend__key--village { background-color: #e0d3bb; }

.xp-legend__tools {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(248, 243, 237, 0.14);
  display: grid;
  gap: 8px;
  justify-items: start;
}

.xp-legend__icons { display: flex; gap: 6px; }

.xp-legend__note {
  margin: var(--space-3) 0 0;
  font-size: 0.56rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(248, 243, 237, 0.34);
}

/* ---------- Markers ----------
   The button *is* the disc, so the tap target is the thing you aim at, and the
   name floats beside it without moving the anchor point. JavaScript writes a
   transform and nothing else. */
.xp-pins { position: fixed; inset: 0; z-index: 20; pointer-events: none; }

.xp-pin {
  position: absolute;
  left: 0;
  top: 0;
  width: 30px;
  height: 30px;
  margin: -15px 0 0 -15px;
  padding: 0;
  border: 0;
  background: none;
  pointer-events: auto;
  opacity: 0;
  transition: opacity 320ms ease;
}

.xp-pin.is-visible { opacity: 1; }

.xp-pin__dot {
  position: absolute;
  inset: 4px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background-color: #f6f4ee;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.45);
  transition: transform 260ms cubic-bezier(0.2, 0.8, 0.3, 1), background-color var(--transition);
}

.xp-pin__icon { width: 12px; height: 12px; fill: #16221a; }

/* the ring that grows on hover, drawn without a second element */
.xp-pin::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid rgba(246, 244, 238, 0.75);
  opacity: 0;
  transform: scale(0.72);
  transition: opacity 300ms ease, transform 300ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

.xp-pin:hover::before,
.xp-pin:focus-visible::before,
.xp-pin.is-active::before { opacity: 1; transform: scale(1.28); }

.xp-pin:hover .xp-pin__dot,
.xp-pin:focus-visible .xp-pin__dot { transform: scale(1.16); }

.xp-pin.is-active .xp-pin__dot { background-color: var(--color-gold); }
.xp-pin.is-active .xp-pin__icon { fill: #10190f; }

.xp-pin__name {
  position: absolute;
  left: 42px;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.75), 0 0 22px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 260ms ease;
  pointer-events: none;
}

/* Names flip to the left near the right edge, or they run off screen. */
.xp-pin.is-flip .xp-pin__name { left: auto; right: 42px; }

.xp-pin:hover .xp-pin__name,
.xp-pin:focus-visible .xp-pin__name,
.xp-pin.is-active .xp-pin__name { opacity: 1; }

.xp-pin--wildlife .xp-pin__dot { background-color: #efe4c8; }
.xp-pin--expedition .xp-pin__dot { background-color: #e2efe4; }

/* ---------- Compass ---------- */
.xp-compass {
  position: fixed;
  left: clamp(1rem, 3vw, 2.6rem);
  bottom: calc(clamp(1rem, 3vw, 2.2rem) + env(safe-area-inset-bottom));
  z-index: 30;
  width: 62px;
  height: 62px;
  opacity: 0.62;
  pointer-events: none;
}

.xp-compass svg { width: 100%; height: 100%; overflow: visible; }
.xp-compass circle { fill: none; stroke: rgba(255, 255, 255, 0.5); stroke-width: 1; }
.xp-compass__tick { stroke: rgba(255, 255, 255, 0.45); stroke-width: 1; }
.xp-compass__needle { fill: rgba(255, 255, 255, 0.95); }
.xp-compass__tail { fill: rgba(255, 255, 255, 0.32); }
.xp-compass text {
  fill: rgba(255, 255, 255, 0.75);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-anchor: middle;
}

/* ---------- Explore control ---------- */
.xp-explore {
  position: fixed;
  left: 50%;
  bottom: calc(clamp(1rem, 3vw, 2.2rem) + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 45;
  display: grid;
  justify-items: center;
  gap: var(--space-4);
}

.xp-explore__btn {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 52px;
  padding: 0 var(--space-6) 0 0;
  /* Same ground as the legend panel, so the two read as one system. */
  background-color: rgba(6, 18, 14, 0.52);
  border: 1px solid rgba(248, 243, 237, 0.10);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--color-white);
  transition: background-color var(--transition), border-color var(--transition);
}

.xp-explore__btn:hover,
.xp-explore__btn:focus-visible {
  background-color: rgba(6, 18, 14, 0.68);
  border-color: rgba(248, 243, 237, 0.26);
}

.xp-explore__mark {
  display: grid;
  place-items: center;
  width: 52px;
  align-self: stretch;
  background-color: rgba(0, 0, 0, 0.18);
  border-right: 1px solid rgba(248, 243, 237, 0.08);
}

/* The compass is a fine line drawing, so it is given most of the square. */
.xp-explore__mark img {
  width: 26px;
  height: auto;
  display: block;
}

.xp-explore__label {
  font-size: 0.74rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
}

.xp-explore__chev { display: grid; place-items: center; margin-left: var(--space-4); }
.xp-explore__chev svg.lucide { width: 1rem; height: 1rem; transition: transform var(--transition); }
.xp-explore__btn[aria-expanded="true"] .xp-explore__chev svg.lucide { transform: rotate(180deg); }

.xp-explore__menu {
  order: -1;
  /* 80% of the viewport, but capped: five columns of place names need about
     900px, and past that the panel only grows its own empty space. On a wide
     screen an uncapped 80vw was most of the desk. */
  width: min(80vw, 900px);
  max-height: min(52vh, 460px);
  overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-6);
  padding: var(--space-6);
  /* Same ground as the legend panel, but a much deeper blur: this one covers
     most of the map, and small type at 0.52 alpha over lit canopy is only
     readable if what is behind it has been taken right down to soft colour. */
  background-color: rgba(6, 18, 14, 0.52);
  border: 1px solid rgba(248, 243, 237, 0.10);
  backdrop-filter: blur(26px) saturate(115%);
  -webkit-backdrop-filter: blur(26px) saturate(115%);
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: opacity var(--transition), transform var(--transition), visibility var(--transition);
}

.xp-explore__menu.is-open { opacity: 1; visibility: visible; transform: none; }

/* The close button sits over the grid rather than in it, so the panel gets a
   strip of its own at the top; otherwise it lands on the last column's heading. */
.xp-explore__menu { padding-top: calc(var(--space-6) + 16px); }

.xp-explore__close {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  background: none;
  border: 1px solid rgba(248, 243, 237, 0.14);
  color: rgba(248, 243, 237, 0.6);
  transition: color var(--transition), border-color var(--transition), background-color var(--transition);
}

.xp-explore__close:hover,
.xp-explore__close:focus-visible {
  color: var(--color-white);
  border-color: rgba(248, 243, 237, 0.4);
  background-color: rgba(248, 243, 237, 0.06);
}

.xp-explore__close svg.lucide { width: 0.9rem; height: 0.9rem; }

.xp-explore__heading {
  margin: 0 0 var(--space-3);
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(248, 243, 237, 0.42);
}

.xp-explore__group button {
  display: block;
  width: 100%;
  padding: 6px 0;
  text-align: left;
  font-size: 0.84rem;
  color: rgba(248, 243, 237, 0.86);
  background: none;
  border: 0;
  transition: color var(--transition), padding-left var(--transition);
}

.xp-explore__group button:hover,
.xp-explore__group button:focus-visible {
  color: var(--color-accent);
  padding-left: 6px;
}

/* ---------- Cursor ---------- */
.xp-cursor { display: none; }

body.has-xp-cursor .xp-cursor {
  display: block;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 90;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 50%;
  pointer-events: none;
  transition: width 220ms ease, height 220ms ease, margin 220ms ease,
              background-color 220ms ease, border-color 220ms ease;
}

body.has-xp-cursor .xp-cursor.is-over {
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  border-color: rgba(255, 255, 255, 0.95);
  background-color: rgba(255, 255, 255, 0.12);
}

body.has-xp-cursor .xp-cursor.is-grab {
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  background-color: rgba(255, 255, 255, 0.75);
}

body.has-xp-cursor .xp-stage canvas { cursor: none; }
body.has-xp-cursor .xp-pin { cursor: none; }

/* ---------- Responsive ---------- */
@media (max-width: 1180px) {
  .xp-legend {
    max-width: none;
    left: clamp(1rem, 3vw, 3rem);
    right: clamp(1rem, 3vw, 3rem);
    bottom: calc(6px + env(safe-area-inset-bottom));
    text-align: center;
    font-size: 0.62rem;
  }
  .xp-legend br { display: none; }
  .xp-legend p { display: inline; }
  .xp-legend p + p::before { content: " · "; }
}

@media (max-width: 900px) {
  .xp-panel {
    width: 100vw;
    top: auto;
    bottom: 0;
    height: min(76vh, 620px);
    border-left: 0;
    border-top: 1px solid rgba(174, 124, 53, 0.42);
    transform: translateY(100%);
  }
  .xp-panel.is-open { transform: none; }
  .xp-panel__head { padding: var(--space-6) var(--space-6) var(--space-4); }
  .xp-panel__body { padding: var(--space-6); }
  .xp-panel__actions { padding: var(--space-4) var(--space-6) calc(var(--space-6) + env(safe-area-inset-bottom)); }

  /*
   * Two deliberate rows rather than whatever flex-wrap produces: the light-of-
   * day switch is the widest control and gets a line of its own, with the two
   * icon buttons under it. Left to wrap on its own it made a three-row stack
   * a third of the screen tall.
   */
  .xp-controls {
    left: 0;
    right: 0;
    transform: none;
    justify-content: center;
    padding-inline: var(--space-4);
    gap: var(--space-2);
    bottom: calc(2.6rem + env(safe-area-inset-bottom));
  }

  .xp-phase {
    order: -1;
    flex-basis: 100%;
    justify-content: center;
  }

  .xp-phase button {
    flex: 1;
    min-width: 0;
    padding: 0 var(--space-3);
    font-size: 0.68rem;
    letter-spacing: 0.06em;
  }

  /* The label on the button is what makes these wide; the icon carries the
     meaning and the title attribute carries the rest. */
  .xp-btn span { display: none; }
  .xp-btn { padding: 0 var(--space-4); }

  .xp-pin__name { font-size: 0.66rem; }

  /*
   * The bottom sheet covers the controls completely on a phone. Leaving them
   * underneath means a tap aimed at Reset view lands on whatever the panel has
   * in that spot — which, on this layout, is the link out to the encyclopedia.
   */
  .wo-point-open .xp-controls {
    opacity: 0;
    visibility: hidden;
    transition: opacity 200ms ease, visibility 200ms;
  }
}

/* A phone held sideways has almost no vertical room; the bottom sheet has to
   stop being a sheet or it covers the map entirely. */
@media (max-width: 900px) and (orientation: landscape) {
  .xp-panel {
    width: min(400px, 62vw);
    height: 100%;
    top: 0;
    bottom: auto;
    border-top: 0;
    border-left: 1px solid rgba(174, 124, 53, 0.42);
    transform: translateX(100%);
  }
  .xp-panel.is-open { transform: none; }
  .xp-controls { bottom: calc(0.75rem + env(safe-area-inset-bottom)); }
  .xp-top { min-height: 58px; }
}

@media (prefers-reduced-motion: reduce) {
  .xp-intro,
  .xp-panel,
  .xp-pin,
  .xp-legend,
  .xp-explore__menu { transition-duration: 1ms; }
}

/* ---------- Responsive: the new chrome ---------- */
@media (max-width: 1180px) {
  .xp-title h1 { letter-spacing: 0.16em; }
}

@media (max-width: 900px) {
  .xp-top { grid-template-columns: auto 1fr auto; padding: 0.75rem 1rem; }
  .xp-title h1 { font-size: 1.05rem; letter-spacing: 0.12em; }
  .xp-title p { display: none; }
  .xp-top__btn { font-size: 0.6rem; letter-spacing: 0.14em; }

  .xp-compass { width: 44px; height: 44px; opacity: 0.5; }

  .xp-explore { bottom: calc(0.75rem + env(safe-area-inset-bottom)); }
  .xp-explore__btn { min-height: 46px; }
  .xp-explore__mark { width: 46px; }
  .xp-explore__label { font-size: 0.66rem; letter-spacing: 0.12em; }
  .xp-explore__menu {
    /* the pill is nearly the full width here, so the panel matches it */
    width: calc(100vw - 1.2rem);
    grid-template-columns: repeat(2, 1fr);
    padding: var(--space-4);
  }

  /*
   * The explore pill owns the bottom of a phone, so the utilities move up
   * under the header. One row, not three: the earlier rule gave the light-of-
   * day switch a line of its own, which made sense when it sat along the
   * bottom and does not now.
   */
  .xp-controls {
    left: auto;
    right: 0.6rem;
    bottom: auto;
    top: calc(0.6rem + 44px);
    justify-content: flex-end;
    flex-wrap: nowrap;
    padding-inline: 0;
    gap: 5px;
  }

  .xp-phase { order: 0; flex-basis: auto; }

  .xp-phase button {
    min-height: 34px;
    padding: 0 7px;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
  }

  .xp-btn { min-height: 34px; padding: 0 9px; }
  .xp-btn svg.lucide { width: 0.9rem; height: 0.9rem; }

  .xp-legend { top: 58px; }
}

@media (max-width: 560px) {
  .xp-pin__name { display: none; }
  .xp-pin.is-active .xp-pin__name { display: block; }
}

/* the brand lockup, sized for the map rather than the site header */
.xp-top .brand { display: flex; align-items: center; gap: 10px; }
.xp-top .brand__mark { width: 30px; height: auto; }
.xp-top .brand__name { font-size: 0.82rem; letter-spacing: 0.14em; }

/* Five groups, five columns. The old three-across-two-beneath layout left
   Village and Viewpoint stranded on a second row under headings they had
   nothing to do with, which is what made the panel read as lopsided. At 80vw
   there is room to give each category its own column and let the row of
   headings line up. */
.xp-explore__menu { grid-template-columns: repeat(5, minmax(0, 1fr)); }

@media (max-width: 900px) {
  /* the utilities now live in the legend, so the old corner cluster is gone */
  .xp-controls { display: none; }

  .xp-top .brand__text { display: none; }
  .xp-legend { max-width: none; }
  .xp-explore__menu { grid-template-columns: repeat(2, 1fr); }
}

/* Five columns need roughly 130px each plus the gaps. Now that the panel is
   capped at 900px it stops shrinking with the viewport, so five stay
   comfortable much further down than when it was a straight 80vw. */
@media (max-width: 1000px) and (min-width: 901px) {
  .xp-explore__menu { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------- Legend block: fit and legibility ---------- */
.xp-top__left { max-width: min(300px, 34vw); }

/* The site header's brand rule is drawn to run the width of a header; here it
   would push the lockup past the legend under it. */
.xp-top .brand__rule { display: none; }
.xp-top .brand__name { white-space: nowrap; }

/* A quiet panel behind the legend, or small type over bright canopy is
   unreadable — and there is bright canopy everywhere on this map. */
.xp-legend.is-open .xp-legend__body {
  padding: var(--space-4);
  margin-left: -2px;
  background-color: rgba(6, 18, 14, 0.52);
  border: 1px solid rgba(248, 243, 237, 0.10);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* The light-of-day switch is sized for a footer bar by default; inside the
   legend it has a column to fit into. */
.xp-legend__tools { justify-items: stretch; }
.xp-legend__tools .xp-phase { width: 100%; }
.xp-legend__tools .xp-phase button {
  flex: 1;
  min-width: 0;
  min-height: 30px;
  padding: 0 4px;
  font-size: 0.53rem;
  letter-spacing: 0.06em;
}
.xp-legend__icons .xp-btn { min-height: 30px; padding: 0 10px; }
.xp-legend__icons .xp-btn svg.lucide { width: 0.85rem; height: 0.85rem; }
.xp-legend__icons .xp-btn span:not(.screen-reader-text) { display: none; }

/* ---------- Pointer plumbing ----------
   A transparent wrapper still catches the pointer. Two of them were sitting
   over the map with the browser's default `auto` — the explore container,
   inflated to the height of its own closed menu because `visibility: hidden`
   still occupies grid space, and the top-left column, made tall by the legend.
   Between them they ate every drag and wheel over the middle and the top left
   of the map, and the map simply stopped responding.

   The rule from here on: wrappers never take the pointer, only the things you
   can actually press. */
.xp-explore,
.xp-top__left,
.xp-top__right,
.xp-title,
.xp-legend { pointer-events: none; }

.xp-explore > *,
.xp-top a,
.xp-top button,
.xp-legend__body { pointer-events: auto; }

/* And the menu is taken out of the flow, so a closed menu cannot make its
   container tall in the first place. */
.xp-explore { position: fixed; }

.xp-explore__menu {
  position: absolute;
  left: 50%;
  bottom: calc(100% + var(--space-4));
  transform: translate(-50%, 12px);
}

.xp-explore__menu.is-open { transform: translate(-50%, 0); }
