/* ------------------------------------------------------------------
   The constituency map. Loaded after systems.css.
   ------------------------------------------------------------------ */

.map-block { display: flex; flex-direction: column; gap: 12px; }

.map-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.map-modes { gap: 6px; }

/*
 * The frame, and the zoom controls that used to float over it.
 *
 * They were the way back from a board that could be dragged and pinched out
 * of position. The board is fixed now, so there is nothing to get back from.
 *
 * What the frame does carry is the touch behaviour, for the padding around
 * the board as well as the board itself: `pan-y` means a finger that lands
 * anywhere in here scrolls the page and does nothing else. No pinch, no
 * sideways drag, no double-tap zoom. Page zoom is untouched — somebody who
 * needs the whole page bigger is not who the fixed board was for.
 */

.map-frame {
  position: relative;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background:
    radial-gradient(700px 460px at 50% 0%, var(--wash-blue), transparent 65%),
    var(--ink-2);
  overflow: hidden;
  height: min(62vh, 620px);
  touch-action: pan-y;
  overscroll-behavior: contain;
}

/*
 * A fixed board, not a map you handle.
 *
 * `pan-y` is the whole of the mobile behaviour: a finger that lands on Punjab
 * scrolls the page down to the standings, exactly as it would anywhere else
 * on the page, and does nothing else. Pinch does not zoom it, a drag does not
 * move it sideways, and a double tap is not a zoom gesture — the browser is
 * told none of those belong to this element.
 *
 * It used to be `touch-action: none` with a drag, a pinch and a double-tap
 * zoom of its own, which meant every one of those competed with the page: a
 * player trying to tap a district kept moving the board instead, and a finger
 * that started on the map could not scroll at all.
 */
.punjab-map {
  width: 100%;
  height: 100%;
  display: block;
  cursor: pointer;
  touch-action: pan-y;
}

.map-outline {
  fill: var(--paper-3);
  stroke: var(--rule);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

/*
 * The district is the unit; the constituencies inside it are a subdivision.
 *
 * The board used to say the opposite. Every seat carried a full-strength ink
 * outline and the district boundaries were a third of that, so 117 cells all
 * shouted and the 23 shapes that are actually campaigned for had to be looked
 * for. The seat lines are still there — a district is made of seats and
 * hiding that would be drawing a different country — but they are quiet
 * enough now that a district reads as one piece of ground.
 */
.map-cell {
  stroke: rgba(18, 32, 54, 0.14);
  stroke-width: 0.5;
  vector-effect: non-scaling-stroke;
  cursor: pointer;
  transition: fill 0.35s ease, fill-opacity 0.35s ease;
}
/*
 * Hovering lights the district, because clicking selects the district.
 *
 * It used to be `.map-cell:hover`, one constituency outlined in cream — which
 * promised a selection the click does not make. The class is put on every
 * seat of the district instead, and it is styled only where a real pointer
 * exists so a tap that leaves it behind on a touchscreen draws nothing.
 */
@media (hover: hover) and (pointer: fine) {
  .map-cell.is-hovered { stroke: var(--cream); stroke-width: 1.2; }
}

/*
 * Kept, unused: one constituency picked out on its own.
 *
 * The record of what the board used to do, in the same way paintCellsBySeat
 * is kept in the script beside it. Nothing draws either now — a district is
 * what gets selected, and it is washed rather than outlined.
 */
.map-cell.is-selected { stroke: var(--cream); stroke-width: 2; }

.map-district-line {
  fill: none;
  stroke: rgba(18, 32, 54, 0.55);
  stroke-width: 1.6;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

/* Kept, unused: the outline the old painter drew round the tapped seat. */
.map-selection {
  fill: none;
  stroke: var(--wheat);
  stroke-width: 2.6;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

.map-labels { --map-k: 1; pointer-events: none; }
.map-seat-num {
  fill: var(--paper-2);
  font-family: var(--font);
  font-size: calc(11px / var(--map-k));
  font-weight: 700;
  paint-order: stroke;
  stroke: rgba(18, 32, 54, 0.8);
  stroke-width: calc(2.6px / var(--map-k));
  opacity: 0;
  transition: opacity 0.2s ease;
}
.map-labels.show-nums .map-seat-num { opacity: 1; }

/* ---------------------------------------------------------- readout */

/*
 * What you just tapped, and it has to be readable at a glance on a phone.
 *
 * This used to be one wrapping line at 0.86rem with the constituency name
 * only a shade larger than the AC number beside it, the party badge, the
 * band and the district — five things of nearly the same weight, none of
 * them the answer to "which seat is this".
 *
 * The name leads now: its own line, display face, nearly twice the size of
 * anything else, at full contrast. Everything else is secondary and looks it.
 */
.map-readout:empty { display: none; }
.map-readout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: 'district district' 'name badge' 'meta meta';
  align-items: center;
  gap: 3px 10px;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-soft);
  background: var(--ink-2);
  font-size: 0.8rem;
}
.readout-name {
  grid-area: name;
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: var(--cream);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.readout-ac {
  grid-area: meta;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
}
.readout-leading {
  grid-area: badge;
  justify-self: end;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--party);
  color: var(--party-ink, #fff);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.readout-band {
  grid-area: meta;
  justify-self: end;
  font-weight: 700;
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.readout-mla { color: var(--muted-2); margin-left: auto; }

/* ---------------------------------------------------------- legend */

.map-legend {
  display: flex;
  align-items: center;
  gap: 6px 16px;
  flex-wrap: wrap;
  font-size: 0.82rem;
}
.legend-item { display: inline-flex; align-items: center; gap: 6px; }
.legend-item.is-you .legend-label { color: var(--cream); font-weight: 700; }
.legend-swatch { width: 11px; height: 11px; border-radius: 3px; }
.legend-label { color: var(--muted); }
.legend-count { font-weight: 700; font-variant-numeric: tabular-nums; }
.legend-majority { margin-left: auto; color: var(--muted-2); }

.map-note { margin: 0; font-size: 0.76rem; color: var(--muted-2); line-height: 1.55; }

@media (max-width: 720px) {
  .map-frame { height: min(52vh, 440px); }
  .readout-mla { margin-left: 0; width: 100%; }
  .legend-majority { margin-left: 0; }
}

/* ------------------------------------------------ one region, not a crop */

/*
 * Choosing Majha used to frame Majha and leave Malwa and Doaba drawn just
 * outside the frame, where a pinch would find them again. Now the camera is
 * the viewBox and everything outside the chosen region is not drawn at all,
 * so the region genuinely replaces the board rather than being a view of it.
 */
.map-cell.is-outside,
.map-district-line.is-outside,
.map-seat-num.is-outside,
.map-outline.is-outside {
  display: none;
}

/*
 * With one region on screen the seats are much larger, so the strokes that
 * separate them can afford to be finer without the map turning to mush.
 */
.punjab-map.is-region .map-district-line { stroke-width: 2; }

/* ------------------------------------------------- how this part stands */

/*
 * A line above the board saying who holds what, for whatever is on screen.
 * It changes with the region, because that is the point of choosing one.
 */
.map-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 7px 2px 0;
  font-size: 0.66rem;
}
.map-summary-name {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.map-summary-rows {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  min-width: 0;
}
.map-summary-row {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-variant-numeric: tabular-nums;
}
.map-summary-row.is-you .map-summary-short { color: var(--cream); }
.map-summary-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--party);
  flex: none;
}
.map-summary-short {
  font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.map-summary-n { font-weight: 700; color: var(--cream); }
.map-summary-won {
  font-size: 0.58rem;
  font-weight: 700;
  color: var(--good);
}
.map-summary-none { color: var(--muted-2); }

/*
 * The instruction that stands where the key goes on an untouched board.
 *
 * Set in the accent rather than the muted grey the key uses: it is the only
 * thing on this screen telling a new player what the map is for, and the key
 * it replaces is a footnote. It takes the whole width so it reads as a line
 * addressed to the player and not as one more label in the strip.
 */
.map-summary-hint {
  flex: 1 0 100%;
  color: var(--gold-deep, var(--wheat));
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.map-summary-seats {
  margin-left: auto;
  font-size: 0.6rem;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
}

.legend-title {
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-2);
}

/*
 * A selected district is one shape.
 *
 * Every seat in it takes the same wash and none of them is stroked, so
 * neighbouring fills meet with nothing drawn between them and the district
 * reads as one piece of ground. What marks its edge is its own boundary,
 * below.
 *
 * It used to outline every constituency instead, which said "you have
 * selected these eleven areas" when the player had tapped one district — and
 * on a phone turned the district into a lattice of bright lines.
 */
.map-district-wash {
  fill: var(--wheat);
  fill-opacity: 0.28;
  stroke: none;
  pointer-events: none;
}

/*
 * Kept, unused: the old per-seat outline.
 *
 * The rule is left as the record of what the board used to say, in the same
 * way paintCellsBySeat is kept in the script beside it.
 */
.map-district-sel {
  fill: none;
  stroke: var(--wheat);
  stroke-width: 2.2;
  stroke-opacity: 0.9;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
  filter: drop-shadow(0 0 4px rgba(154, 116, 32, 0.5));
}

@media (max-width: 430px) {
  /* The seat count is the first thing to go: the map says it better. */
  .map-summary-seats { display: none; }
  .map-summary { gap: 6px; }
  .map-summary-rows { gap: 7px; }
}

/* -------------------------------------------- who is ahead in a district */

/*
 * A district is a group of seats, and colouring the whole thing in one colour
 * would hide the seats — which are the truth of the board. So the border
 * carries it: tinted where somebody is ahead, solid where every seat in it
 * has been won and it is theirs for good.
 */
.map-district-line.has-leader {
  stroke: var(--party);
  stroke-opacity: 0.5;
}
.map-district-line.is-controlled {
  stroke-opacity: 0.95;
  stroke-width: 2.4;
}

/*
 * And the selected district's own boundary, last so that it wins.
 *
 * This is what marks the edge of the shape the wash fills. It has to be
 * declared after the leader rules above: they are `.map-district-line` plus
 * one class as well, so at equal specificity the later rule takes the stroke
 * — and with this one above them, a selected district that anybody was
 * leading kept the leader's colour at half opacity and the selection did not
 * show at all. Which was most of the board.
 */
.map-district-line.is-selected {
  stroke: var(--wheat);
  stroke-width: 2.6;
  stroke-opacity: 1;
  filter: drop-shadow(0 0 4px rgba(154, 116, 32, 0.45));
}

/* The district the seat sits in, above the seat's own name. */
.readout-district {
  grid-area: district;
  display: flex;
  align-items: baseline;
  gap: 7px;
  flex-wrap: wrap;
  padding-bottom: 6px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--line);
}
.readout-district-name {
  font-weight: 700;
  font-size: 0.78rem;
  color: var(--cream);
}
.readout-district-seats {
  font-size: 0.6rem;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
}
.readout-district-lead {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--party, var(--muted));
}
.readout-district-lead.is-controlled::after { content: ' ✓'; }
.readout-district-lead.is-open { color: var(--muted-2); }

@media (max-width: 379px) {
  .readout-name { font-size: 1.22rem; }
}

/* ------------------------------------------------- a seat that is finished */

/*
 * The tick is always drawn and only ever shown on a district that has been
 * taken, so the map never rebuilds 117 glyphs to change one. One tick a
 * district, at its middle — ticking every constituency inside it would put
 * fourteen of them on Ludhiana.
 *
 * Unlike the seat numbers it does not wait for a zoom: taking a district
 * outright is the one thing on this board that cannot be undone, and it
 * should read at any scale.
 */
.map-seat-tick {
  fill: #fff;
  font-family: var(--font);
  font-size: calc(13px / var(--map-k));
  font-weight: 700;
  paint-order: stroke;
  stroke: rgba(18, 32, 54, 0.85);
  stroke-width: calc(3px / var(--map-k));
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.map-seat-tick.is-on { opacity: 1; }
.map-seat-tick.is-outside { display: none; }

/* With the tick carrying it, a won cell needs less of an outline. */
.map-labels.show-nums .map-seat-tick.is-on { font-size: calc(11px / var(--map-k)); }
