/* The tour viewer. Deliberately close to the look Drew is replacing: the
   panorama is the whole page, and everything else is a translucent slab
   floating over it. Nothing here is a framework -- it is one page. */

:root {
  --panel: rgba(38, 40, 44, 0.82);
  --panel-solid: #26282c;
  --ink: #fff;
  --accent: #ff3b30;          /* the you-are-here dot and its view cone */
  --dot: #2f9ae0;             /* every other station */
  --radius: 14px;
  --shadow: 0 6px 28px rgba(0, 0, 0, 0.42);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #111;
  font: 400 14px/1.4 Roboto, system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

#stage {
  position: fixed;
  inset: 0;
  touch-action: none;
  cursor: grab;
}
#stage.dragging { cursor: grabbing; }
#stage.overhotspot { cursor: pointer; }
#stage canvas { display: block; }

.pill {
  position: fixed;
  padding: 9px 20px;
  border-radius: 999px;
  background: var(--panel);
  backdrop-filter: blur(6px);
  box-shadow: var(--shadow);
  font-size: 14px;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

#address {
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  max-width: min(560px, calc(100vw - 32px));
  overflow: hidden;
  text-overflow: ellipsis;
}

#loading {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transition: opacity 0.25s;
}
#loading[hidden] { display: block; opacity: 0; pointer-events: none; }

.panel {
  background: var(--panel);
  backdrop-filter: blur(6px);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

#failed {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 18px 22px;
  max-width: 460px;
  line-height: 1.5;
}
#failed code {
  display: block;
  margin-top: 8px;
  opacity: 0.7;
  font-size: 12px;
  word-break: break-all;
}

/* ---------------------------------------------------------------- minimap */

#map {
  position: fixed;
  left: 16px;
  bottom: 16px;
  width: 280px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
#map[hidden] { display: none; }

#map header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}
#map h1 {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.15;
  opacity: 0.92;
}

#collapse, #expand {
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: var(--ink);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s;
}
#collapse:hover, #expand:hover { background: rgba(255, 255, 255, 0.26); }

#expand {
  position: fixed;
  left: 16px;
  bottom: 16px;
  width: 44px;
  height: 44px;
  background: var(--panel);
  backdrop-filter: blur(6px);
  box-shadow: var(--shadow);
  border-radius: var(--radius);
}
#expand[hidden] { display: none; }

/* The rendered plan and the live overlay share one box and one viewBox, so a
   station dot drawn at plan-mm-through-`frame` lands exactly on its room. */
/* The plan DRAWING sets the height and the overlay is stretched over whatever
   that turns out to be. Anything else drifts: give the box its own height and
   the two layers letterbox their shared viewBox by different amounts, so the
   station dots sit lower than the rooms they mark -- by a distance that changes
   with the height of the window, which is a strange bug to look at.

   A floor plan can be any shape (this house's 2nd floor is twice as tall as it
   is wide) so the height still has to be capped, but the cap is applied to the
   WIDTH -- max-width = the tallest map we want, times the drawing's own aspect.
   Height then follows from the drawing and lands exactly on the cap, with no
   second constraint to disagree with it. --ar comes from the published frame. */
:root { --map-max-h: 40vh; }

#stagemap {
  position: relative;
  width: 100%;
  max-width: calc(var(--map-max-h) * var(--ar, 1.6));
  margin: 0 auto;
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
}
#mapsvg svg {
  display: block;
  width: 100%;
  height: auto;
}
/* inset alone: the overlay takes the box the drawing just defined, so the two
   share one geometry by construction rather than by both being told a size. */
#overlay { position: absolute; inset: 0; }

/* Hovering is driven by a class, not by :hover, so that pointing at a ring out
   in the panorama lights the matching dot on the plan as well -- which is the
   half that actually answers "where am I about to go?". */
/* Scaled about its own bounding box, so the whole mark grows in place. Putting
   the transform on the outer group avoids fighting the translate/scale that
   positions the mark -- in SVG those are the same property, and a CSS transform
   on that element would throw the placement away. */
.station {
  cursor: pointer;
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 0.16s ease-out;
}
.station.hovered { transform: scale(1.16); }

/* Invisible until hovered, but still hittable: on a small map the mark is only
   a few pixels across, and this quietly makes it a comfortable target. */
.station .halo {
  opacity: 0;
  transition: opacity 0.16s ease-out;
}
.station.hovered .halo { opacity: 0.34; }

#floorpick { display: block; }
#floors {
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.14) no-repeat right 10px center/12px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23fff' stroke-width='1.8'/%3E%3C/svg%3E");
  color: var(--ink);
  font: inherit;
  cursor: pointer;
  appearance: none;
}
#floors:focus-visible { outline: 2px solid var(--accent); }
#floorpick:has(#floors option:only-child) { display: none; }
#floors option { background: var(--panel-solid); }

@media (max-width: 560px) {
  #map { width: 190px; left: 12px; bottom: 12px; }
  #address { font-size: 13px; padding: 8px 14px; }
}

/* A short window is where the map crowds the tour most, so give it less. */
@media (max-height: 620px) {
  :root { --map-max-h: 32vh; }
}
