/* ============================================================================
   installations.css - the "Våra installationer" map.

   Loaded by BOTH the landing page and /admin/cms/installationer, which render
   the same .inst-* markup. Same arrangement as before-after.css: the backoffice
   shows the real component, so what the operator checks is what the visitor
   gets. admin.css adds the editing chrome around it and must never restyle
   .inst-*.

   MapLibre's own stylesheet is NOT imported here - installations-map.js injects
   it alongside the library, so neither page pays for it until a map is built.
   ========================================================================== */

/* ── The map ────────────────────────────────────────────────────────────────
   The section used to open with a totals row above the panel; it was removed at
   the owner's request, so the map now sits directly under the section intro and
   is the only thing in here. */

/* The panel is dark because the map inside it is. The basemap is OpenFreeMap's
   dark style, which is what lets the brand mark read as a marker at all - so the
   frame and the credit strip are dark too, and the whole thing lands on the page
   as one deliberate block rather than a black rectangle inside a pale box. The
   site already uses ink-900 surfaces for the nav and the footer, so this is the
   existing vocabulary rather than a new one. */
.inst-panel {
  border: 1px solid var(--ink-900);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--ink-900);
}

.inst-map {
  position: relative;
  /* An explicit height, not an aspect ratio. MapLibre sizes its canvas from the
     container, and a container with no height at all renders a 0px map that
     reports no errors - the single most common way this component ships
     "broken" while every line of script has run correctly. */
  height: 460px;
  width: 100%;
  background: #0c0c0c;
}

/* Before the library arrives (and forever, with JavaScript off) the box is a
   quiet placeholder rather than a grey hole. It never says "loading": on a page
   where the map may legitimately never load, a permanent "Loading map…" is
   exactly the failure the reference site shipped. */
/* Matched to the dark basemap, not to the page. A pale placeholder under a
   near-black map is a visible flash from light to dark the moment the tiles
   arrive, on every visit. */
.inst-map::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 30% 35%, #1b2836, transparent 62%),
    radial-gradient(circle at 70% 65%, #131c26, transparent 58%);
}

.inst-map[data-inst-state='ready']::before {
  display: none;
}

.inst-map-error {
  position: absolute;
  inset: auto var(--sp-4) var(--sp-4) var(--sp-4);
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm);
  background: var(--paper-0);
  border: 1px solid var(--border-card);
  font: var(--body-sm);
  color: var(--text-body);
}

/* The cooperative-gesture hint. MapLibre 5 blocks the gesture and fires an
   event but no longer draws its own overlay, so this is ours. */
.inst-map-hint {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(16, 24, 32, 0.42);
  color: #fff;
  font: 600 16px/1.3 var(--font-body);
  text-align: center;
  padding: var(--sp-5);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--speed) var(--ease);
  z-index: 2;
}

.inst-map-hint.is-visible {
  opacity: 1;
}

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

/* Attribution is required by OpenFreeMap, OpenStreetMap and the style's
   licence, and it is rendered in the markup rather than by a MapLibre control:
   a control only exists once the library has loaded, and the credit must be
   there whether or not it ever does. */
.inst-credit {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0;
  padding: var(--sp-2) var(--sp-4);
  border-top: 1px solid rgb(255 255 255 / 10%);
  background: var(--ink-900);
  font: 400 12px/1.5 var(--font-body);
  color: var(--ink-300);
}

.inst-credit a {
  color: var(--blue-300);
  text-decoration: underline;
}

.inst-credit a:hover {
  color: #fff;
}

/* ── The street list ────────────────────────────────────────────────────────

   The visible "Visa alla gator" disclosure was removed at the owner's request.
   The list stays, off-screen: it is the map's text equivalent, and the only form
   in which this section says anything to a screen reader or to a visitor with no
   JavaScript. A canvas full of circles conveys neither street nor count.

   The clip-path recipe rather than display:none, and that distinction is the
   whole point - a display:none element is removed from the accessibility tree,
   so hiding it that way would have turned "remove the button" into "remove the
   content". Nothing here is focusable, so no skip-link problem follows. */
.inst-streets-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  list-style: none;
}

/* ── Popups ─────────────────────────────────────────────────────────────── */

.inst-popup .maplibregl-popup-content {
  border-radius: var(--radius-sm);
  padding: var(--sp-3) var(--sp-4);
  box-shadow: var(--shadow-card);
  font: var(--body-sm);
  color: var(--text-body);
}

.inst-popup-street {
  display: block;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: var(--display-tracking);
  text-transform: uppercase;
  color: var(--text-heading);
}

.inst-popup-area {
  display: block;
  color: var(--text-muted);
}

.inst-popup-count {
  display: block;
  margin-top: 2px;
  font-weight: 600;
  color: var(--blue-600);
}

@media (max-width: 640px) {
  .inst-map {
    height: 380px;
  }
}
