/* The real street map.
   Full OpenStreetMap detail -- every street, every label -- as VECTOR tiles through MapLibre,
   repainted to the page's own palette in src/mapstyle.js. Vector so it stays sharp at any
   zoom and on any screen, and so the whole thing can be restyled from one place. It fades up
   over the white the flight dissolves into.

   The id selector matters: maplibre-gl.css is injected after this stylesheet and its own
   .maplibregl-map sets position:relative, which at equal specificity would win and collapse
   the container to zero height.

   The move into the right half is a CLIP plus a TRANSFORM, never a resize. Resizing the map
   element itself means MapLibre re-lays-out on every frame of the slide, which it cannot keep
   up with: the map goes blank for the length of the animation. So the clip narrows, the map
   slides inside it at a fixed size, and it is handed the half properly in one step once it
   has arrived -- by which point the picture is already identical, so nothing moves. */
.ws-mapclip{ position:absolute; top:0; right:0; bottom:0; left:0; overflow:hidden;
  pointer-events:none;
  transition:left var(--t-slide) var(--ease), top var(--t-slide) var(--ease); }
body.split .ws-mapclip{ left:var(--panel-w); }

#cityMap.ws-map{ position:absolute; top:0; left:0; opacity:0;   /* size set in JS */
  pointer-events:none;                 /* invisible, so it must not swallow the menu's clicks */
  transition:opacity var(--t-slow) ease, transform var(--t-slide) var(--ease); }
#cityMap.ws-map.on{ opacity:1; pointer-events:auto; }
/* Changing the city from the bar: out, jump, back in. Three classes so it beats .on, which is
   two -- and the map keeps taking clicks throughout, because it is going nowhere. */
#cityMap.ws-map.on.swap{ opacity:0; transition:opacity var(--t-out) ease; }
/* HALF THE PANEL, and it has to be derived rather than written. The map is still at full box
   width while the clip narrows, so to keep the same ground under the shrinking window it slides
   by half the width the clip lost. A percentage in a transform resolves against the element's
   own width, and the element is the full box -- the same thing --panel-w is a percentage of --
   so half of that token is exactly the right distance at any split. It was -25%, which is what
   this evaluates to at the 50% the panel used to take. */
body.split:not(.settled) #cityMap.ws-map{ transform:translateX(calc(var(--panel-w) / -2)); }
body.settled #cityMap.ws-map{ width:100%; height:100%; transform:none;
  transition:opacity var(--t-slow) ease; }
@media (max-width:860px){
  body.split .ws-mapclip{ left:0; top:var(--panel-h); }
  body.split:not(.settled) #cityMap.ws-map{ transform:translateY(calc(var(--panel-h) / -2)); }
}

/* the layers are repainted to real greys in src/mapstyle.js, so this changes nothing today --
   it is a guarantee that the map stays monochrome if the upstream style ever adds a layer we
   have not named */
.ws-map .maplibregl-canvas{ filter:grayscale(1); }
/* ---- the map's own chrome ----
   MapLibre builds these itself, so they are the one part of the page whose markup we do not
   write. They are still SURFACES: src/streetmap.js puts class="surface" on each control group as
   it adds it and hands them to src/surface.js to be drawn, exactly like the capsule in the bar.
   Before that they were the only bordered boxes on the page with a plain CSS border and a 2px
   radius, which is why they read as sharp against everything else.
   They take --radius-xs, because they are narrower than anything else here: see tokens.css.
   No border, no radius and no background declared, for the same reason no other surface does. */
/* MapLibre's own 4px radius has to be turned off explicitly: the surface's is at :where()
   specificity, which is zero, so their class rule wins over it. The clip hides the difference,
   but two shapes declared on one box is how they come apart later. */
.ws-map .maplibregl-ctrl-group{ box-shadow:none; border-radius:0; }
.ws-map .maplibregl-ctrl-group button{ width:32px; height:30px; border-radius:0;
  color:var(--ink); }
/* .divide-t rather than a border, for the reason in surface.css: this is the line that made
   the artifact visible, poking a device pixel past the control's outline at both ends. */
.ws-map .maplibregl-ctrl-group button + button{ position:relative; border-top:0; }
.ws-map .maplibregl-ctrl-group button + button::before{ content:''; position:absolute; top:0;
  left:var(--rule); right:var(--rule); height:var(--rule); background:var(--ink);
  z-index:var(--z-outline); pointer-events:none; }
.ws-map .maplibregl-ctrl-group button:hover{ background:var(--surface-hover); }
.ws-map .maplibregl-ctrl-group button:active{ background:var(--surface-press); }
/* MapLibre's own focus ring is a 2px blue glow, which is the only colour on an otherwise
   monochrome page. The page's own ring is ink, inset so the surface's clip cannot eat it. */
.ws-map .maplibregl-ctrl-group button:focus{ box-shadow:none; }
.ws-map .maplibregl-ctrl-group button:focus-visible{ outline:var(--rule) solid var(--ink);
  outline-offset:-4px; }
/* three classes: maplibre's own .maplibregl-ctrl.maplibregl-ctrl-attrib is two, and at a
   tie the later stylesheet -- theirs -- wins */
.ws-map .maplibregl-ctrl.maplibregl-ctrl-attrib{ background:var(--wash);
  padding:1px 8px; font:400 var(--fs-9-5)/var(--lh-read) var(--font-mono);
  color:var(--text-muted); }
.ws-map .maplibregl-ctrl-attrib a{ color:var(--text-soft); text-decoration:none; }
.ws-map .maplibregl-ctrl-bottom-left,
.ws-map .maplibregl-ctrl-bottom-right{ margin:0 5px 5px; }

/* Back to the view the flight landed on. It appears only once the visitor has actually moved
   off it, and it is added AFTER the zoom buttons so it hangs under them -- coming and going
   above them would shove the zoom controls up and down the corner. */
.ws-map .ws-recentre{ opacity:0; pointer-events:none;
  transition:opacity var(--t-out) ease; }
/* it keeps its space while hidden: the zoom buttons sit under it and must not jump */
.ws-map .ws-recentre.on{ opacity:1; pointer-events:auto; }
.ws-map .ws-recentre button{ display:flex; align-items:center; justify-content:center;
  color:var(--ink); background:none; border:0; cursor:pointer; }
.ws-map .ws-recentre svg{ width:16px; height:16px; display:block; }

/* the city's name, on hover over its dot in the flight */
/* A SURFACE with no outline (data-edge="none" in index.html): its ground is ink, so a line of
   ink around it would be invisible, but it still takes the same smoothed corner as every other
   box -- it used to be the one sharp-cornered thing that moved. */
.tag{ position:fixed; z-index:var(--z-over); transform:translate(-50%,-100%);
  background:var(--ink); color:var(--on-ink); padding:5px 10px;
  white-space:nowrap; pointer-events:none;
  font:600 var(--fs-11) var(--font-mono); letter-spacing:var(--ls-tag);
  text-transform:uppercase; opacity:0; transition:opacity var(--t-quick) ease; }
.tag.on{ opacity:1; }
