/* The map is a fixed-size stage in poster pixels. One transform on .map-stage
   drives all zoom and pan; the labels are children, so they scale with it for
   free and every number from sections.json drops in unchanged. */

.map-view {
  position: relative;
  width: 100%;
  overflow: hidden;
  height: 100dvh;
  background: #1b1d21;
  cursor: grab;
  touch-action: none;
  overscroll-behavior: contain;
}
.map-view.is-dragging { cursor: grabbing; }

.map-stage {
  position: absolute;
  top: 0; left: 0;
  transform-origin: 0 0;
  /* Every label on the map is real text now, so without this a drag across
     the poster selects words instead of panning. The text stays in the DOM
     for search engines and screen readers either way; being able to sweep-
     select it is worth much less than being able to drag the map. */
  user-select: none;
  -webkit-user-select: none;
}

/* Safari honours this rather than the draggable attribute. */
.mlabel, .map-art {
  -webkit-user-drag: none;
}

.map-art {
  display: block;
  width: 100%;
  height: 100%;
  /* Deliberately no will-change here. Promoting a 2987x4203 image to its own
     compositor layer asks for a ~50MB texture; the allocation fails and the
     image silently paints nothing at all. Blurring during a gesture is handled
     by .is-interacting instead, which costs nothing when idle. */
}

.map-labels,
.map-annotations {
  position: absolute;
  inset: 0;
}

.mlabel,
.manno {
  position: absolute;
  display: block;
  text-decoration: none;
  color: #000;
}

.mlabel {
  transform-origin: 50% 50%;
  transition: transform .14s cubic-bezier(.2, .8, .2, 1), filter .14s ease;
}

.mplate {
  position: absolute;
  inset: 0;
  display: block;
  overflow: visible;
}

/* .mline lives in site.css: the topic and subtopic pages draw poster text too,
   and they do not load this stylesheet. */

.mlabel:hover,
.mlabel:focus-visible {
  transform: scale(1.07);
  z-index: 5;
  filter: drop-shadow(0 6px 16px rgb(0 0 0 / .32));
  outline: none;
}

.mlabel:focus-visible { outline: 3px solid #1b6dff; outline-offset: 3px; }

/* While a gesture is in flight, suppress the pop so labels don't animate
   under the cursor mid-pan. Removed shortly after the gesture settles. */
.is-interacting .mlabel {
  transition: none;
}
.is-interacting .mlabel:hover {
  transform: none;
  filter: none;
}

/* The poster's own heading. It has no plate, so its shadow goes on the
   letterforms rather than on a box -- a shadow cast by the shape of the words
   themselves, which is why the blur is much tighter than the plated labels use.

   The `filter: none` is doing real work: .mlabel--bare is still a .mlabel, so
   without it the shared .mlabel:hover shadow would apply to the link box as
   well and the title would carry two shadows at different radii. */
.mlabel--bare:hover,
.mlabel--bare:focus-visible {
  filter: none;
}
.mlabel--bare .mline {
  transition: filter .14s ease;
}
.mlabel--bare:hover .mline,
.mlabel--bare:focus-visible .mline {
  filter: drop-shadow(0 5px 4px rgb(0 0 0 / .3));
}

.zoom {
  position: absolute;
  right: 1rem;
  bottom: 1rem;
  display: flex;
  flex-direction: column;
  gap: 1px;
  border-radius: .6rem;
  overflow: hidden;
  background: rgb(255 255 255 / .14);   /* shows through as the divider */
  box-shadow: 0 2px 12px rgb(0 0 0 / .4);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.zoom-btn {
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  padding: 0;
  color: #eef1f5;
  background: rgb(22 24 28 / .82);
  border: 0;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.zoom-btn:hover { background: rgb(44 48 55 / .92); }
.zoom-btn:focus-visible {
  outline: 3px solid #7cc7ff;
  outline-offset: -3px;
}
.zoom-btn[disabled] {
  color: #71777f;
  cursor: default;
  background: rgb(22 24 28 / .62);
}

.map-hint {
  position: absolute;
  left: 50%;
  bottom: 1rem;
  transform: translateX(-50%);
  margin: 0;
  padding: .45rem .9rem;
  font-size: .8rem;
  color: #cfd5de;
  background: rgb(0 0 0 / .55);
  border-radius: 999px;
  pointer-events: none;
  transition: opacity .4s ease;
}
.map-hint.is-gone { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .mlabel { transition: none; }
}
