/* Map surface. Owned by the map builder.
   The map is the canvas; magenta belongs to our pins and the time instrument.
   Labels on magenta fills follow the theme pair (docs/brand.md).

   THE BASEMAP IS DARK IN BOTH MODES. style.json is a single static file that
   MapLibre consumes once at init — it cannot read CSS custom properties and
   cannot be swapped without map.js's cooperation. A half-converted basemap is
   worse than a dark one on a light page, so in light mode the tiles stay
   night and the CHROME themes: controls, hint, attribution, cards, panel and
   the time instrument follow the tokens, while everything anchored to the
   tiles themselves (pins, stems, tooltips, the AR fold) re-pins the dark
   palette below so it keeps reading on the tiles it actually sits on. */

.mapwrap {
  position: absolute; inset: 0;
  overflow: hidden;
  /* Literal, not var(--canvas): this is the colour behind the tiles while
     they load, and the tiles are dark in both modes. */
  background: #0D0D0F;
}

/* The re-pin: everything that sits ON the tiles keeps the dark tokens, in
   both modes, because its background is the unthemed basemap. Values are
   app.css's dark :root, verbatim. */
.mapwrap .pin, .ar {
  --surface: #1C1C1F;
  --raised: #232326;
  --line: #2E2E33;
  --text: #FFFFFF;
  --muted: #8E8E93;
  --accent: #E0308A;
  --accent-on: #0D0D0F;
  --accent-text: #EC4A9C;
  --accent-tint: rgba(224, 48, 138, .12);
  --accent-line: rgba(224, 48, 138, .5);
  --accent-line-soft: rgba(224, 48, 138, .35);
  --accent-glow: rgba(224, 48, 138, .5);
  --shadow-1: 0 1px 2px rgba(0,0,0,.5), 0 6px 24px rgba(0,0,0,.35);
  --shadow-2: 0 2px 6px rgba(0,0,0,.55), 0 16px 48px rgba(0,0,0,.45);
}
.mapfold {
  position: absolute; inset: 0;
  transition: transform 400ms cubic-bezier(.3, .7, .2, 1), opacity 400ms ease;
  transform-origin: 50% 100%;
}
.mapwrap.folded .mapfold {
  transform: perspective(1400px) rotateX(62deg) scale(.86) translateY(-6%);
  opacity: 0;
  pointer-events: none;
}
#lm-map { position: absolute; inset: 0; }
#lm-map canvas { outline: none; }

/* MapLibre chrome, re-dressed. Attribution is compact and collapsed by
   default (map.js strips the open state MapLibre adds at init); collapsed it
   is a small dark round button, expanded it is the same dark pill as the
   map hint. */
.mapwrap .maplibregl-ctrl-attrib {
  background: var(--glass-veil) !important;
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  color: var(--muted) !important;
  font: 400 10px/1.4 var(--body);
  border-radius: var(--r-pill);
}
/* The vendored maplibre css loads after this file, so these are scoped under
   .mapwrap to outrank its same-specificity rules. */
.mapwrap .maplibregl-ctrl-attrib a { color: var(--muted); }
.mapwrap .maplibregl-ctrl-attrib.maplibregl-compact { margin: 0 10px 0 0; min-height: 22px; }
.mapwrap .maplibregl-ctrl-attrib.maplibregl-compact:not(.maplibregl-compact-show) {
  width: 22px; height: 22px; padding: 0;
}
.mapwrap .maplibregl-ctrl-attrib .maplibregl-ctrl-attrib-button {
  background-color: transparent;
  width: 22px; height: 22px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='%238E8E93' fill-rule='evenodd' viewBox='0 0 20 20'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E");
}
.mapwrap .maplibregl-ctrl-attrib-button:focus {
  box-shadow: 0 0 0 2px var(--accent-line);
}
.mapwrap .maplibregl-ctrl-attrib.maplibregl-compact-show {
  padding: 3px 26px 3px 10px;
}
.mapwrap .maplibregl-ctrl-bottom-right { bottom: 118px; z-index: 10; transition: opacity 150ms ease; }
@media (max-width: 760px) {
  .mapwrap .maplibregl-ctrl-bottom-right { bottom: 152px; }
  /* The open sheet and the attribution control share the bottom-right corner
     on the phone; the control yields while a card is open. */
  .mapwrap.card-open .maplibregl-ctrl-bottom-right { opacity: 0; pointer-events: none; }
}

/* ------------------------------------------------------------- controls */

.map-controls {
  position: absolute; top: 16px; right: 16px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 20;
}
.mapbtn {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--glass-btn);
  backdrop-filter: blur(12px);
  color: var(--text);
  cursor: pointer;
  transition: background var(--t), color var(--t), transform var(--t);
  padding: 0;
}
.mapbtn:hover { background: var(--raised); }
.mapbtn:active { transform: scale(.94); }
.mapbtn svg { width: 18px; height: 18px; }
.mapbtn[aria-pressed="true"] { background: var(--accent-tint); color: var(--accent-text); border-color: var(--accent-line-soft); }
.mapbtn--wide {
  display: flex; align-items: center;
  width: auto; padding: 0 12px; gap: 7px;
  font: 500 12.5px var(--body);
}
.mapbtn--wide svg { flex: none; }

/* --------------------------------------------------------------- pins */
/* Pins sit directly on the tiles, and the tiles are dark in both modes, so
   every literal in this section is deliberately mode-independent: the
   rgba(13,13,15,…) ink washes, the white-based quiet-pin strokes, the black
   drop shadows and the magenta glows are all colours against the night
   basemap, not against the app canvas. The var() references resolve through
   the .mapwrap .pin re-pin above for the same reason. */

.pin { cursor: pointer; }
/* Stacking: events ride above places, places above moment dots, so a scattered
   moment can never intercept a click meant for a quest pin. */
.mapwrap .maplibregl-marker.pin--moment { z-index: 1; }
.mapwrap .maplibregl-marker.pin--place { z-index: 2; }
.mapwrap .maplibregl-marker.pin--event { z-index: 3; }
.mapwrap .maplibregl-marker.selected { z-index: 4; }
.pin-q {
  position: relative;
  width: 32px; height: 32px;
  border-radius: 50%;
  display: grid; place-items: center;
  border: 2px solid var(--accent);
  background: rgba(13, 13, 15, .82);
  color: var(--accent-text);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .5);
  transition: transform 150ms cubic-bezier(.2, .7, .3, 1), opacity 150ms ease,
              background 150ms ease, border-color 150ms ease, color 150ms ease;
}
.pin:hover .pin-q { transform: scale(1.12); }
.pin-q .rung { width: 13px; height: 13px; }

/* in progress: filled magenta, near-black glyph */
.pin--doing .pin-q { background: var(--accent); border-color: var(--accent); color: var(--accent-on); }
/* complete: ghost */
.pin--done .pin-q { border-color: var(--line); background: rgba(28, 28, 31, .82); color: var(--muted); }
.pin--done .pin-q .rung { display: none; }
.pin--done .pin-q::after {
  content: ''; width: 12px; height: 7px;
  border-left: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(-45deg) translate(1px, -1px);
}
.pin-n {
  position: absolute; top: -5px; right: -7px;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--accent);
  color: var(--accent-on);
  font: 500 10px/16px var(--mono);
  text-align: center;
}
.pin--done .pin-n { background: var(--raised); color: var(--muted); }

/* Selected: unmistakable at a glance — a bright double ring, a glow, and a
   slight lift. map.js also glides the pin toward the open card. */
.pin.selected .pin-q {
  transform: scale(1.16);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(13, 13, 15, .9), 0 0 0 5px var(--accent),
              0 0 24px rgba(224, 48, 138, .65), 0 2px 10px rgba(0, 0, 0, .5);
}
.pin--event.selected .pin-e {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 20px rgba(224, 48, 138, .55), 0 2px 10px rgba(0, 0, 0, .5);
}
.pin--moment.selected .pin-m {
  transform: scale(1.5);
  box-shadow: 0 0 0 3px rgba(13, 13, 15, .9), 0 0 0 4.5px var(--accent), 0 0 18px rgba(224, 48, 138, .7);
}

/* quiet: a seeded venue with no quests yet. Still one of ours — the rung
   glyph in muted grey — and it names itself on hover/focus, so it reads as a
   venue rather than tile noise. */
.pin--place { position: relative; }
.pin--quiet .pin-q {
  width: 24px; height: 24px;
  border: 1.5px solid rgba(255, 255, 255, .38);
  background: rgba(13, 13, 15, .72);
  color: rgba(255, 255, 255, .55);
  box-shadow: 0 1px 6px rgba(0, 0, 0, .45);
}
.pin--quiet .pin-q .rung { width: 9px; height: 9px; }
.pin--quiet:hover .pin-q, .pin--quiet:focus-visible .pin-q {
  border-color: rgba(255, 255, 255, .6);
  color: rgba(255, 255, 255, .8);
}
.pin .qname {
  position: absolute; left: 50%; bottom: calc(100% + 6px);
  transform: translateX(-50%) translateY(3px);
  padding: 3px 9px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: rgba(13, 13, 15, .9);
  color: var(--text);
  font: 500 11px/1.3 var(--body);
  white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity 120ms ease, transform 120ms ease;
}
.pin--quiet:hover .qname, .pin--quiet:focus-visible .qname, .pin--quiet.selected .qname {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* moment: a small ember from the viewer's own record */
.pin-m {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid rgba(13, 13, 15, .9);
  box-shadow: 0 0 8px rgba(224, 48, 138, .55);
  transition: transform 150ms cubic-bezier(.2, .7, .3, 1), opacity 150ms ease;
}
.pin:hover .pin-m { transform: scale(1.35); }

/* event: a tag anchored above the place on a hairline stem — the stem says
   which venue hosts it. map.js places the chip each frame (left/top on
   .pin-e), trying candidates that dodge sibling pins, other chips, rendered
   city labels, and the bezel. The CSS default is the home position so the
   first paint is sane before the layout pass runs. */
.pin--event { position: relative; width: 0; height: 0; }
.pin--event .pin-e { position: absolute; left: -85px; top: -54px; }
.pin--event .stem {
  position: absolute; left: -0.5px; width: 1px;
  top: -42px; height: 28px;
  background: linear-gradient(180deg, rgba(224, 48, 138, .12), rgba(224, 48, 138, .6));
  pointer-events: none;
}
.pin--event.pin--past .stem { background: linear-gradient(180deg, transparent, rgba(142, 142, 147, .45)); }
.pin-e {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 10px 4px 8px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(224, 48, 138, .45);
  background: rgba(13, 13, 15, .88);
  color: var(--accent-text);
  font: 500 11px/1.2 var(--body);
  white-space: nowrap;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .5);
  transition: transform 150ms cubic-bezier(.2, .7, .3, 1), opacity 150ms ease;
}
.pin-e .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; }
.pin--upcoming .pin-e .dot { animation: pulse 1.6s ease-in-out infinite; }
.pin--past .pin-e { color: var(--muted); border-color: var(--line); }
.pin--past .pin-e .dot { background: var(--muted); box-shadow: none; }
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(224, 48, 138, .55); }
  55% { box-shadow: 0 0 0 7px rgba(224, 48, 138, 0); }
}

/* pins entering/leaving with the time cursor. MapLibre stamps inline
   opacity/transform on the marker element itself every frame, so hiding must
   happen on the inner ember, which it never touches. */
.pin.t-hide { pointer-events: none; }
.pin.t-hide .pin-m { opacity: 0; transform: scale(.6); box-shadow: none; }
.pin { transition: opacity 150ms ease, transform 150ms cubic-bezier(.2, .7, .3, 1); }

/* --------------------------------------------------------------- hint */

.map-hint {
  position: absolute; top: 16px; left: 16px;
  z-index: 20;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: var(--glass-veil);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  color: var(--muted);
  font-size: 11.5px;
  max-width: 46ch;
}

/* ---------------------------------------------------------- pin card */

.pin-card {
  position: absolute; left: 16px; bottom: 128px;
  z-index: 30;
  width: 340px; max-width: calc(100% - 32px);
  background: var(--glass-panel);
  backdrop-filter: blur(14px);
  border: 1px solid var(--line);
  border-radius: var(--r-l);
  box-shadow: var(--shadow-2);
  overflow: hidden;
  transform-origin: 0 100%;
  animation: cardin 150ms cubic-bezier(.2, .7, .3, 1);
}
@keyframes cardin { from { opacity: 0; transform: translateY(8px) scale(.98); } }
.pin-card .lotus-edge { border-radius: 0; }
.pin-card .inner {
  padding: 16px 18px 18px;
  max-height: 52vh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.pin-card .inner::-webkit-scrollbar { width: 8px; }
.pin-card .inner::-webkit-scrollbar-thumb {
  background: var(--line); border-radius: 4px;
  border: 2px solid transparent; background-clip: content-box;
}
/* More below the fold: a bottom fade says so, and lifts at the end so the
   last row is never veiled. map.js toggles the classes on scroll. */
.pin-card .fadecue {
  position: absolute; left: 1px; right: 1px; bottom: 1px;
  height: 44px;
  border-radius: 0 0 var(--r-l) var(--r-l);
  background: linear-gradient(180deg, transparent, var(--glass-panel));
  opacity: 0; pointer-events: none;
  transition: opacity 150ms ease;
}
.pin-card.can-scroll:not(.at-end) .fadecue { opacity: 1; }
.pin-card .close {
  position: absolute; top: 10px; right: 10px;
  width: 28px; height: 28px;
  border: 0; border-radius: 50%;
  background: var(--raised); color: var(--muted);
  cursor: pointer; font-size: 14px; line-height: 1;
}
.pin-card .close:hover { color: var(--text); }
.pin-card .close:active { transform: scale(.92); }
.pin-card h3 { padding-right: 28px; }
.pin-card .whenline { margin-top: 4px; }

.qrow { padding: 12px 0; border-top: 1px solid var(--line); }
.qrow:first-of-type { border-top: 0; }
.qrow .meta { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 10px; }
/* The pending glyph must occupy the same footprint as the label — map.js
   also locks the measured width before busy(). */
.qrow .btn { min-width: 88px; }

@media (max-width: 760px) {
  .pin-card {
    left: 8px; right: 8px; width: auto;
    bottom: calc(var(--nav-h) + 92px);
  }
  .pin-card .inner { max-height: 38vh; }
}

/* ------------------------------------------------------- detail panel */

/* Opens over the map when a place pin is tapped; the map stays visible
   beside it. Desktop: a modal-weight dialog anchored right, clear of the
   time instrument. Phone: a bottom sheet, map visible above. */
.map-panel {
  position: absolute; top: 16px; right: 16px; bottom: 128px;
  z-index: 35;
  width: min(440px, calc(100% - 32px));
  display: flex; flex-direction: column;
  background: var(--glass-panel);
  backdrop-filter: blur(14px);
  border: 1px solid var(--line);
  border-radius: var(--r-l);
  box-shadow: var(--shadow-2);
  overflow: hidden;
  outline: none;
  animation: panelin 200ms cubic-bezier(.2, .7, .3, 1);
}
@keyframes panelin { from { opacity: 0; transform: translateX(14px); } }
@media (prefers-reduced-motion: reduce) { .map-panel { animation: none; } }
.map-panel .lotus-edge { border-radius: 0; flex: none; }
.map-panel .mp-head { position: relative; flex: none; padding: 16px 20px 10px; }
.map-panel .mp-head h3 { padding-right: 32px; }
.map-panel .close {
  position: absolute; top: 12px; right: 12px;
  width: 28px; height: 28px;
  border: 0; border-radius: 50%;
  background: var(--raised); color: var(--muted);
  cursor: pointer; font-size: 14px; line-height: 1;
}
.map-panel .close:hover { color: var(--text); }
.map-panel .close:active { transform: scale(.92); }
.map-panel .mp-scroll {
  flex: 1; overflow-y: auto;
  padding: 0 20px 18px;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.map-panel .mp-scroll::-webkit-scrollbar { width: 8px; }
.map-panel .mp-scroll::-webkit-scrollbar-thumb {
  background: var(--line); border-radius: 4px;
  border: 2px solid transparent; background-clip: content-box;
}
.mp-quest { padding: 14px 0; border-top: 1px solid var(--line); }
.mp-quest:first-of-type { border-top: 0; }
.mp-quest h4 { font: 600 15px/1.35 var(--body); color: var(--text); }
.mp-quest .meta { display: flex; flex-wrap: wrap; gap: 6px; margin: 7px 0 9px; }
.mp-qbody { color: var(--muted); margin-bottom: 10px; }
.mp-state .btn { min-width: 88px; }
/* The ladder's task slot: nothing renders in it until the stages migration
   is applied, and an empty slot takes no room. */
.mp-tasks:empty { display: none; }

@media (max-width: 760px) {
  .map-panel {
    top: auto; left: 8px; right: 8px;
    bottom: calc(var(--nav-h) + 8px);
    width: auto;
    max-height: 56vh;
    animation: sheetin 200ms cubic-bezier(.2, .7, .3, 1);
  }
  @keyframes sheetin { from { opacity: 0; transform: translateY(14px); } }
  /* The sheet and the attribution control share the bottom-right corner on
     the phone; the control yields while the panel is open, same as the card. */
  .mapwrap.panel-open .maplibregl-ctrl-bottom-right { opacity: 0; pointer-events: none; }
}

/* ------------------------------------------------------ time instrument */

.timebar {
  position: absolute; left: 16px; right: 16px; bottom: 16px;
  z-index: 40;
  display: flex; align-items: stretch; gap: 14px;
  padding: 12px 18px 10px 14px;
  border-radius: var(--r-l);
  border: 1px solid var(--line);
  background: var(--glass-bar);
  backdrop-filter: blur(16px);
  box-shadow: var(--shadow-1);
}
.timebar .lhs { display: flex; align-items: center; gap: 12px; flex: none; }
.tplay {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--raised);
  color: var(--text);
  cursor: pointer; padding: 0;
  transition: background var(--t), color var(--t), transform var(--t);
}
.tplay:hover { background: var(--surface); }
.tplay:active { transform: scale(.92); }
.tplay[aria-pressed="true"] { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.tplay svg { width: 15px; height: 15px; }

.treadout { font-family: var(--mono); min-width: 118px; }
.treadout .d { font-size: 17px; font-weight: 500; letter-spacing: .02em; color: var(--text); white-space: nowrap; }
.treadout .s { font-size: 10.5px; color: var(--muted); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; }
.treadout .s .live { color: var(--accent-text); }

.ttrack {
  position: relative; flex: 1;
  min-width: 0;
  cursor: pointer;
  touch-action: none;
  border-radius: var(--r-s);
}
.ttrack:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; }
.ttrack .rail-line {
  position: absolute; left: 0; right: 0; top: 26px;
  height: 2px; border-radius: 1px;
  background: var(--line);
}
.ttrack .fill {
  position: absolute; left: 0; top: 25px;
  height: 4px; border-radius: 2px;
  background: linear-gradient(90deg, var(--plum), var(--accent));
  box-shadow: 0 0 10px var(--accent-glow-dim);
}
.ttrack .notch {
  position: absolute; top: 20px; width: 1px; height: 8px;
  background: var(--line);
}
.ttrack .notch b {
  position: absolute; top: 12px; left: 3px;
  font: 500 9px var(--mono); letter-spacing: .1em;
  color: var(--muted); font-weight: 400;
}
.ttrack .tick {
  position: absolute; top: 23px; width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--accent-line);
  margin-left: -2px;
}
.ttrack .tick--event { background: transparent; border: 1px solid var(--accent-line); width: 5px; height: 5px; }
.ttrack .nowmark {
  position: absolute; top: 16px; width: 1px; height: 16px;
  background: var(--faint-mid);
  margin-left: -.5px;
}
.ttrack .nowmark b {
  position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
  font: 400 8.5px var(--mono); letter-spacing: .14em;
  color: var(--faint-mid);
}
.ttrack .handle {
  position: absolute; top: 27px;
  width: 18px; height: 18px;
  margin-left: -9px;
  transform: translateY(-50%);
  color: var(--accent);
  filter: drop-shadow(0 0 6px var(--accent-glow));
  pointer-events: none;
  transition: transform 80ms ease;
}
.ttrack.dragging .handle { transform: translateY(-50%) scale(1.2); }
.ttrack .handle .rung { width: 18px; height: 18px; }

.timebar.skel-mode .ttrack, .timebar.skel-mode .treadout { visibility: hidden; }
.timebar .tskel {
  position: absolute; left: 76px; right: 18px; top: 14px; bottom: 12px;
  border-radius: var(--r-s);
}

@media (max-width: 760px) {
  .timebar {
    left: 8px; right: 8px; bottom: calc(var(--nav-h) + 8px);
    padding: 8px 12px 6px 8px; gap: 8px;
  }
  .tplay { width: 32px; height: 32px; }
  .treadout { min-width: 84px; }
  .treadout .d { font-size: 13px; }
  .treadout .s { font-size: 9px; }
  .pin-e { max-width: 46vw; }
  .pin-e .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ttrack .notch b { display: none; }
  .ttrack .notch:nth-child(odd) b { display: block; }
  .map-hint { top: 8px; left: 8px; font-size: 10.5px; max-width: 60vw; }
  .map-controls { top: 8px; right: 8px; }
  .mapbtn--ar { display: none; }

  /* Shell workaround, requested in docs/notes/map-shell-requests.md: on the
     phone tab bar the active rung renders below the label and clips at the
     bottom viewport edge. Lift it out of the column flow to a small tick at
     the top of the tab, fully inside --nav-h. Belongs in app.css. */
  .nav a.item { position: relative; }
  .nav a.item .rung {
    position: absolute; top: 3px; left: 50%;
    width: 9px; height: 8px; margin-left: -4.5px;
  }
}

/* ------------------------------------------------------------ AR fold */
/* A stylised night scene in both modes — it depicts an evening skyline, not
   an app surface — so its literals stay and its tokens come from the .ar
   re-pin at the top of this file. */

.ar {
  position: absolute; inset: 0;
  z-index: 25;
  overflow: hidden;
  opacity: 0; pointer-events: none;
  transition: opacity 400ms ease;
  background:
    radial-gradient(120% 55% at 50% 76%, rgba(142, 44, 110, .30), transparent 60%),
    linear-gradient(180deg, #0D0D0F 0%, #121016 46%, #1C1220 68%, #0B0B0D 72%, #0D0D0F 100%);
  cursor: grab;
}
.ar:active { cursor: grabbing; }
.mapwrap.folded .ar { opacity: 1; pointer-events: auto; }
.ar .horizon {
  position: absolute; left: 0; right: 0; top: 72%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(236, 74, 156, .5), transparent);
}
.ar .skyline { position: absolute; left: -10%; right: -10%; width: 120%; bottom: 27.5%; height: 18%; opacity: .9; }
.ar .skyline--far { bottom: 28%; height: 12%; opacity: .5; }
.ar .ground {
  position: absolute; left: 0; right: 0; top: 72%; bottom: 0;
  background: linear-gradient(180deg, rgba(28, 28, 31, .5), #0D0D0F 70%);
}
.ar .ground::before {
  content: '';
  position: absolute; inset: 0;
  background-image:
    repeating-linear-gradient(90deg, rgba(46, 46, 51, .35) 0 1px, transparent 1px 120px),
    repeating-linear-gradient(0deg, rgba(46, 46, 51, .3) 0 1px, transparent 1px 34px);
  transform: perspective(420px) rotateX(62deg);
  transform-origin: 50% 0;
}
.arpoi {
  position: absolute;
  transform: translate(-50%, -100%);
  min-width: 190px; max-width: 250px;
  padding: 13px 16px;
  border-radius: var(--r-m);
  border: 1px solid var(--line);
  background: rgba(28, 28, 31, .92);
  backdrop-filter: blur(8px);
  box-shadow: var(--shadow-1);
  cursor: pointer;
  transition: border-color var(--t);
}
.arpoi:hover { border-color: rgba(224, 48, 138, .4); }
/* Each card stands on a stem that reaches the horizon it belongs to (length
   set per-card by map.js as --stem), with a glowing base dot on the skyline. */
.arpoi::after {
  content: '';
  position: absolute; left: 50%; bottom: calc(-1 * var(--stem, 26px));
  width: 1px; height: var(--stem, 26px);
  background: linear-gradient(180deg, rgba(224, 48, 138, .55), rgba(224, 48, 138, .1));
}
.arpoi::before {
  content: '';
  position: absolute; left: 50%; bottom: calc(-1 * var(--stem, 26px) - 3px);
  width: 7px; height: 7px; margin-left: -3px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px rgba(224, 48, 138, .8), 0 0 22px rgba(224, 48, 138, .4);
}
.arpoi .nm { font: 600 15px/1.25 var(--body); color: var(--text); }
.arpoi .dist { font: 500 13px var(--mono); color: var(--accent-text); margin-top: 3px; letter-spacing: .04em; }
.arpoi .what { font-size: 12px; color: var(--muted); margin-top: 3px; }
.arpoi--quiet { min-width: 150px; padding: 10px 13px; }
.arpoi--quiet .nm { font-size: 13px; color: var(--muted); }
.arpoi--quiet .dist { font-size: 11.5px; color: var(--muted); }
.arpoi--quiet::before { background: rgba(142, 142, 147, .8); box-shadow: 0 0 8px rgba(142, 142, 147, .5); }
.arpoi--quiet::after { background: linear-gradient(180deg, rgba(142, 142, 147, .4), transparent); }
.ar .ar-back {
  position: absolute; top: 16px; left: 16px;
  z-index: 30;
}
.ar .ar-compass {
  position: absolute; left: 50%; top: 20px; transform: translateX(-50%);
  font: 500 11px var(--mono); letter-spacing: .3em;
  color: var(--muted);
}
.ar .ar-note {
  position: absolute; left: 50%; bottom: 118px; transform: translateX(-50%);
  font-size: 10.5px; color: var(--muted); white-space: nowrap;
  padding: 4px 12px; border-radius: var(--r-pill);
  background: rgba(13, 13, 15, .6);
}

/* The second line in the hint pill: why the map is full of other people's
   work. Separate element rather than one longer sentence, so the first claim —
   people are never shown here — keeps its own line and its own weight. */
.map-hint__why { margin-top: 5px; }
