/* ------------------------------------------------------------------
   map.css - the viewer: index pane, hotspots, name tag, info box.
   Colours and fonts come from base.css.

   Layout: the index pane sits top left, the info box top right, and the
   zoom buttons bottom left. On a phone the index is a drop-down and the
   info box is a sheet along the bottom.
   ------------------------------------------------------------------ */


/* ---- Index pane (top left) ----------------------------------------
   The title plate, with the list of places under it. js/nav.js adds the
   class "is-open" while the list is showing.
   ------------------------------------------------------------------- */

#nav {
  position: fixed;
  top: 14px;
  left: 20px;
  z-index: 1000;            /* above the map panes */
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  max-height: calc(100vh - 14px - 110px);   /* stops short of the zoom buttons */
  color: var(--text);
  background: var(--surface);
  border: 2.5px solid var(--line);
  border-radius: 6px;
  box-shadow: var(--cast), var(--bloom);
}
#nav.is-open { width: 250px; }

#plate {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 12px;
  padding: 7px 10px 8px 16px;
}

#title {
  flex: 1;
  margin: 0;
  font: 800 24px/1.15 var(--serif);
}

/* On a sub-map: a line above the title that leads back up. */
#back {
  flex-basis: 100%;
  margin-bottom: 1px;
  font: italic 500 16px/1.3 var(--serif);
  color: var(--accent);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}
#back[hidden] { display: none; }

/* The arrow that opens and closes the list. Drawn from two borders. */
#nav-toggle {
  flex: none;
  width: 30px;
  height: 30px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
}
#nav-toggle::before {
  content: "";
  display: block;
  width: 8px;
  height: 8px;
  margin: 0 auto 4px;
  border-right: 2.5px solid var(--text);
  border-bottom: 2.5px solid var(--text);
  transform: rotate(45deg);               /* points down: "there's more" */
  transition: transform 0.15s ease-out;
}
#nav.is-open #nav-toggle::before {
  margin: 4px auto 0;
  transform: rotate(-135deg);             /* points up: "put it away" */
}
#nav-toggle:hover { background: var(--surface-deep); }
#nav-toggle[hidden] { display: none; }

#nav-body {
  display: none;
  overflow-y: auto;
  padding: 6px 0 8px;
  border-top: 2px solid var(--line);
}
#nav.is-open #nav-body { display: block; }

#places,
#other-maps ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* One place in the list. The dot on the left is the torch: it lights when
   the pointer is on this entry, or on the place itself on the map. */
#places button {
  position: relative;
  display: block;
  width: 100%;
  padding: 4px 14px 5px 34px;
  font: 500 18px/1.25 var(--serif);
  color: var(--text);
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
}
#places button::before {
  content: "";
  position: absolute;
  left: 17px;
  top: 0.62em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--text-soft);
  opacity: 0.35;
  transition: opacity 0.12s, background 0.12s, box-shadow 0.12s;
}
#places button:hover,
#places button:focus-visible,
#places button.is-hot {
  color: var(--accent);
  outline: none;
}
#places button:hover::before,
#places button:focus-visible::before,
#places button.is-hot::before {
  background: var(--torch);
  opacity: 1;
  box-shadow: 0 0 0 3px rgba(240, 127, 31, 0.28);
}
/* The place whose info box is open. */
#places button.is-current {
  font-weight: 800;
  background: var(--surface-deep);
}
#places button.is-current::before {
  background: var(--text);
  opacity: 1;
}

#other-maps {
  margin-top: 8px;
  padding: 8px 16px 0;
  border-top: 1.5px solid color-mix(in srgb, var(--line) 30%, transparent);
}
#other-maps h2 {
  margin: 0 0 2px;
  font: italic 500 15px/1.3 var(--serif);
  color: var(--text-soft);
}
#other-maps a {
  display: block;
  padding: 2px 0;
  font: 600 17px/1.3 var(--serif);
  color: var(--accent);
  text-underline-offset: 3px;
}

/* Opened from the editor's Preview button: say so, since these shapes
   may not be saved yet. */
.is-preview #title::after {
  content: "preview";
  margin-left: 10px;
  padding: 1px 8px 2px;
  font: italic 500 14px/1.3 var(--serif);
  color: var(--on-accent);
  background: var(--accent);
  border-radius: 3px;
  vertical-align: 3px;
}


/* ---- Zoom buttons (bottom left) ------------------------------------
   Leaflet's own, restyled to match the boxes.
   ------------------------------------------------------------------- */

.leaflet-bottom.leaflet-left .leaflet-control-zoom {
  margin: 0 0 22px 20px;
  border: 2.5px solid var(--line);
  border-radius: 6px;
  box-shadow: var(--cast), var(--bloom);
}
.leaflet-touch .leaflet-control-zoom a,
.leaflet-control-zoom a {
  width: 34px;
  height: 34px;
  font: 700 22px/32px var(--serif);
  color: var(--text);
  background: var(--surface);
  border-bottom: 1.5px solid var(--line);
}
.leaflet-control-zoom a:first-child { border-radius: 3px 3px 0 0; }
.leaflet-control-zoom a:last-child  { border-radius: 0 0 3px 3px; border-bottom: 0; }
.leaflet-control-zoom a:hover { color: var(--text); background: var(--surface-deep); }
.leaflet-control-zoom a.leaflet-disabled { color: color-mix(in srgb, var(--text) 30%, transparent); background: var(--surface); }


/* ---- Hotspots ------------------------------------------------------
   Each hotspot is a group (.spot) holding two pictures, both made in
   js/hotspots.js:

     .halo  the glow around the shape
     .lift  a cut-out copy of the painting inside the shape

   js/hotspots.js sets two numbers on the group:
     --near   0 to 1, how close the pointer is
     --grow   how much to enlarge when it pops up
   and adds the class "is-up" while the shape is hovered or selected.
   ------------------------------------------------------------------- */

.spot {
  pointer-events: none;

  /* Scale from the centre of the shape, not the corner of the map. */
  transform-box: fill-box;
  transform-origin: center;

  /* Settling back down: quick and plain. */
  transition: transform 0.2s ease-out;
}

.spot .halo {
  opacity: var(--near, 0);
  transition: opacity 0.2s linear;
}

.spot .lift {
  opacity: 0;
  transition: opacity 0.1s ease-out;
}

.spot.is-up {
  transform: scale(var(--grow, 1.35));

  /* Popping up: overshoot, dip back, settle. A plain overshoot for
     browsers that don't know linear(), a proper bounce for the rest. */
  transition: transform 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.4);
}
@supports (transition-timing-function: linear(0, 1)) {
  .spot.is-up {
    transition: transform 0.6s linear(
      0, 0.22 5%, 0.68 12%, 1.02 19%, 1.2 26%, 1.25 31%, 1.2 37%,
      1.03 48%, 0.955 56%, 0.94 61%, 0.965 69%, 1.01 80%, 1.015 87%, 1
    );
  }
}

.spot.is-up .halo,
.spot.is-up .lift {
  opacity: 1;
}

/* The pointer turns into a hand over a hotspot. */
.leaflet-container.on-spot,
.leaflet-container.on-spot .leaflet-interactive {
  cursor: pointer;
}

/* Name tag above a hovered place: a slip with no outline, wiped in from
   the left each time it appears. */
.leaflet-tooltip.spot-label {
  padding: 2px 12px 3px;
  font: 700 17px/1.3 var(--serif);
  color: var(--tag-text);
  background: var(--tag);
  border: 0;
  border-radius: 3px;
  box-shadow: -3px 3px 0 rgba(28, 16, 22, 0.5);
  white-space: nowrap;
  animation: wipe-in 0.24s cubic-bezier(0.3, 0.7, 0.2, 1) both;
}
.leaflet-tooltip.spot-label::before { display: none; }   /* no arrow */

/* clip-path hides everything outside a rectangle. Start with the right
   edge of that rectangle pulled all the way to the left (nothing shows),
   and slide it out. The -6px values leave room for the shadow. */
@keyframes wipe-in {
  from { clip-path: inset(-6px 100% -6px -6px); }
  to   { clip-path: inset(-6px -6px -6px -6px); }
}

/* People who ask their OS for less motion get the glow without the bounce. */
@media (prefers-reduced-motion: reduce) {
  .spot,
  .spot.is-up { transition: none; }
  #panel { transition: none !important; }
  .leaflet-tooltip.spot-label { animation: none; }
}


/* ---- Torchlight (dark themes) ---------------------------------------
   js/theme.js lays one element over the map, under the places. On a dark
   theme it is filled with darkness (--shade) that thins out to nothing
   around the pointer, so the map is lit where you're looking. Places that
   glow or pop up are drawn above it, so they shine through. On the Paper
   theme --shade is transparent and none of this shows.
   -------------------------------------------------------------------- */

.shade {
  /* No pointer (a phone, or the mouse is over a pane): light mid-screen. */
  background: radial-gradient(circle at 50% 45%, transparent 0, var(--shade) 78%);
}
.shade.has-torch {
  background:
    radial-gradient(circle at var(--x) var(--y), rgba(240, 127, 31, 0.1) 0, transparent 240px),
    radial-gradient(circle at var(--x) var(--y), transparent 0, transparent 70px, var(--shade) 360px);
}
/* The warm tint only belongs with the darkness. */
:root:not([data-theme]) .shade.has-torch,
[data-theme=""] .shade.has-torch { background: none; }


/* ---- Theme switch (bottom left, beside the zoom buttons) ------------ */

#themes {
  position: fixed;
  left: 76px;
  bottom: 28px;
  z-index: 1000;
  display: flex;
  gap: 9px;
}
#themes button {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 2.5px solid var(--line);
  border-radius: 50%;
  box-shadow: -2px 2px 0 rgba(0, 0, 0, 0.45);
  cursor: pointer;
}
/* Each dot shows its own theme's surface colour, whatever theme is on. */
#themes button[data-theme-choice=""]     { background: #f3ecdb; }
#themes button[data-theme-choice="pine"] { background: #14342a; }
#themes button[data-theme-choice="plum"] { background: #351b27; }
#themes button[aria-pressed="true"] {
  outline: 2.5px solid var(--torch);
  outline-offset: 2px;
}
#themes button:focus-visible {
  outline: 3px solid var(--torch);
  outline-offset: 3px;
}


/* ---- Info box (top right) ------------------------------------------ */

#panel {
  position: fixed;
  top: 14px;
  right: 22px;
  z-index: 1001;
  box-sizing: border-box;
  width: min(390px, calc(100vw - 40px));
  max-height: calc(100vh - 14px - 28px);
  overflow-y: auto;
  padding: 22px 26px 24px;
  color: var(--text);
  background: var(--surface);
  border: 3px solid var(--line);
  border-radius: 6px;
  box-shadow: var(--cast), var(--bloom);

  /* Closed: invisible and nudged toward the edge it slides in from. */
  opacity: 0;
  visibility: hidden;
  transform: translateX(14px);
  transition: opacity 0.16s ease-out, transform 0.16s ease-out, visibility 0s 0.16s;
}

#panel.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.2s ease-out, transform 0.24s cubic-bezier(0.2, 0.9, 0.3, 1.15);
}

.panel-title {
  margin: 0 34px 0 0;                     /* leaves room for the close button */
  font: 800 31px/1.08 var(--serif);
  letter-spacing: -0.005em;
  text-wrap: balance;
  outline: none;
}

.panel-subtitle {
  margin: 7px 0 0;
  font: italic 500 19px/1.3 var(--serif);
  color: var(--accent);
}

.panel-body {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 2px solid var(--line);
  font: 400 18px/1.5 var(--serif);
}
.panel-body p {
  margin: 0 0 0.75em;
  white-space: pre-line;                  /* single line breaks in "info" are kept */
}
.panel-body p:last-child { margin-bottom: 0; }

.panel-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  padding: 0 0 3px;
  font: 400 26px/1 var(--serif);
  color: var(--surface);
  background: var(--text);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}
.panel-close:hover { background: var(--accent); }

.panel-enter {
  display: inline-block;
  margin-top: 18px;
  padding: 7px 16px 8px;
  font: 700 18px/1.2 var(--serif);
  color: var(--on-accent);
  background: var(--accent);
  border: 2.5px solid var(--line);
  border-radius: 5px;
  text-decoration: none;
}
.panel-enter:hover { color: var(--surface); background: var(--text); }
.panel-enter[hidden] { display: none; }

.panel-close:focus-visible,
.panel-enter:focus-visible,
#nav-toggle:focus-visible,
#back:focus-visible,
#other-maps a:focus-visible {
  outline: 3px solid var(--torch);
  outline-offset: 2px;
}


/* ---- Phones --------------------------------------------------------
   The index becomes a drop-down from the title; the info box becomes a
   sheet along the bottom.
   ------------------------------------------------------------------- */

@media (max-width: 640px) {
  #nav {
    top: 10px;
    left: 14px;
    max-width: calc(100vw - 28px);
    max-height: 60vh;
  }
  #nav.is-open { width: min(250px, calc(100vw - 28px)); }
  #title { font-size: 20px; }

  #panel {
    top: auto;
    left: 14px;
    right: 10px;
    bottom: 14px;
    width: auto;
    max-height: 52vh;
    padding: 18px 20px 20px;
    transform: translateY(14px);
  }
  #panel.is-open { transform: none; }
  .panel-title { font-size: 26px; }

  .leaflet-bottom.leaflet-left .leaflet-control-zoom { margin: 0 0 18px 14px; }
  #themes { left: 68px; bottom: 24px; }
}
