/* ==========================================================================
   The district map - `c-map.tpl`.

   Loaded only by the two page types that draw it (properties, home), because
   167 inlined paths and their states are not something every page should pay
   for.

   One map serves the whole site and it is the HOME PAGE's export (client
   decision, 25 Aug 2026). The Search frame draws a different vector version of
   the same city - same painted extent to the pixel, different district
   boundaries - and it is not used.

   The box and the states below are measured on the Search frame (1006:1231),
   the only frame in the file that draws the map on the flat page ground rather
   than over a photograph. The landing page's copy sits on a frosted, blurred
   base over the hero picture; that base is NOT here, because on Field Grey
   there is nothing behind it to frost and the frame draws none.

   THE STATES ARE NOT IN THE ARTWORK. The export carries geometry and a stroke
   and nothing else; every fill below is a class that page-search.js sets from
   data, which is what lets the same file serve whatever the admin eventually
   binds to it.
   ========================================================================== */

.c-map{
  position:relative;
  /* Painted extent 337..1093 x 133..796 on the frame - 757x664 against a
     733.031x671 viewBox, i.e. 3.3% wider and 1% shorter than the artwork's own
     aspect. That is what `preserveAspectRatio="none"` is on the root element
     for, and the landing frame stretches the same file its own way (732x670).
     The map is hand-placed art in a flat Figma file, not a projection.

     Fluid below its own width, keeping the frame's stretched aspect rather
     than the artwork's: the 757x664 IS the design, and shrinking it changes
     the box, not the projection. NEITHER mobile frame draws the map - the
     Search frame's mobile panel puts a «Карта» control where it would be and
     the mobile landing frame omits the «Избрани квартали» band entirely - so
     what happens to it at 393 is a page-composition decision (a disclosure,
     not a deletion) and lives in the two page stylesheets that draw one. */
  width:min(757px, 100%);
  aspect-ratio:757 / 664;
  height:auto;
}

.c-map__svg{
  display:block;
  width:100%;
  height:100%;
}

/* A district's states. Colour is the whole vocabulary here - no stroke change,
   no lift, nothing that would need a second reading: mapped and not chosen is
   Map Peach, unmapped is the page ground, hovered is Warm Cream and chosen is
   the deep orange. */
.district{
  fill:var(--c-map-base);
  /* the export writes stroke="#1C1C1C" on 161 paths; the Search frame paints
     them Hairline Gold, sampled at #c2a170 on 8356 pixels inside the map */
  stroke:var(--c-gold);
  stroke-width:1;
  transition:fill var(--c-ease-map);
}

/* Parks are scenery. They are never selectable, never bound, never hovered. */
.district.is-park{
  fill:var(--c-green);
  pointer-events:none;
}

.district.is-hovered { fill:var(--c-map-hover); }

/* AN UNMAPPED DISTRICT IS NOT PART OF THE CONTROL, AND IT SAYS SO.

   `is-bound` is added by the script for every path the binding table names -
   i.e. every district an operator has mapped in the admin. A path without it
   is scenery: it drops to the page ground so it reads as an empty shape held
   by its gold hairline, the same not-here the landing page gets from
   `fill:transparent` over its frosted base, and it takes itself out of the
   hit test so there is no pointer, no tooltip and no click that could not go
   anywhere. The two states must be told apart at a glance - a map where every
   shape looks alike but only 34 of 167 do something is a map that lies.

   The fill is the ground COLOUR rather than `transparent` on purpose: the
   Search page draws a drop shadow off this artwork's silhouette, and a hole
   in the silhouette is a hole in the shadow. On flat Field Grey the two read
   identically. */
.district:not(.is-bound):not(.is-park){
  fill:var(--c-field);
  pointer-events:none;
}

/* Only a district that resolves to a real one should feel clickable - the
   script adds `is-bound`, and with an empty binding table nothing gets it. */
.district.is-bound{ cursor:pointer; }

/* THE FOCUS RING, and it is neither an outline nor this path's own stroke.

   `base.css` declares one `:focus-visible` for the whole system - a 2px green
   outline at a 3px offset. On an SVG <path> that outline is drawn round the
   shape's BOUNDING BOX, so a focused district in the middle of the city rings
   a rectangle over four of its neighbours and says nothing about which shape
   has focus. The city is 167 interlocking outlines; the only ring that can
   follow one of them is its own contour.

   Widening the focused path's OWN stroke does not work either, and it looks
   as though it does until you tab onto a district near the start of the
   artwork: SVG has no z-index, paint order is document order, and every path
   after it in the file paints over the outer half of that stroke. So the ring
   is a separate copy of the shape, appended last by `c-map.js` and therefore
   painted over the whole city. The fill change is the second half of the
   signal and stays on the path itself.                       audit, 27 Aug */
.district.is-bound:focus{ outline:none; }
.district.is-bound:focus-visible{
  outline:none;
  fill:var(--c-map-hover);
}
.district.is-bound.is-selected:focus-visible{ fill:var(--c-map-selected); }

/* The ring itself - a shallow clone of the focused path, carrying its `d` and
   nothing else. It is deliberately NOT `.district`, so none of the state
   vocabulary above reaches it, and it is inert: the shape underneath is the
   control and a second hit area over it would only steal the click. */
.c-map__ring{
  fill:none;
  stroke:var(--c-green);
  stroke-width:3;
  stroke-linejoin:round;
  pointer-events:none;
}
.district.is-bound:hover{ fill:var(--c-map-hover); }

/* CHOSEN, and it stays chosen under the cursor. The map is a multi-select
   filter control: the visitor's own selection is the one piece of state on it
   that a hover must not paint over, because hovering is how you reach the
   second click that removes it. Declared after the hover rule so it wins at
   equal specificity. */
.district.is-selected,
.district.is-bound.is-selected:hover{ fill:var(--c-map-selected); }

/* --- the tooltip -------------------------------------------------------- */
/* 140x88 white card at map-relative x324 y283, 12px of padding, a 10px radius
   and a downward pointer at its bottom centre. The name is the panel's 16px
   (ink 63 against a 64.5 canvas ink box), the count is bold beneath it and the
   link is Estate Green. */

.c-map__tip{
  position:absolute;
  z-index:2;
  min-width:140px;
  padding:12px;
  /* the script sets left/top to the district's centre; this lifts the card
     clear of the cursor and centres it, which is where the frame draws it */
  transform:translate(-50%, calc(-100% - 14px));
  background:var(--c-white);
  border-radius:var(--c-r-control);
  box-shadow:var(--c-sh-photo);
  pointer-events:auto;
}
.c-map__tip[hidden]{ display:none; }

/* the pointer - a 14px square rotated onto its corner, clipped by the card's
   own background so only the triangle shows */
.c-map__tip::after{
  content:"";
  position:absolute;
  left:50%;
  bottom:-6px;
  width:14px; height:14px;
  margin-left:-7px;
  background:var(--c-white);
  transform:rotate(45deg);
}

.c-map__tip-name{
  display:block;
  font:400 var(--c-fs-body)/var(--c-lh-body) var(--c-sans);
  color:var(--c-ink);
}
.c-map__tip-count{
  display:block;
  margin-top:8px;
  font:700 var(--c-fs-label)/var(--c-lh-sans) var(--c-sans);
  color:var(--c-ink);
}
.c-map__tip-link{
  display:block;
  margin-top:2px;
  font:400 var(--c-fs-label)/var(--c-lh-sans) var(--c-sans);
  color:var(--c-green);
  transition:color var(--c-ease);
}
.c-map__tip-link:hover{ color:var(--c-ink); }
