/* The map page only. Loaded by /map/ and nothing else, because 171 polygons
   of styling on every country page is 171 polygons nobody asked for.

   ONE RULE ABOUT THIS FILE. The base rule and the state rules must share the
   same selector prefix. They did not on the first pass: the base was
   `#worldmap path` and the states were `path[data-state=x]`, so an ID
   outranked every state and the whole map rendered in the unpainted land
   colour with the JavaScript setting data-state correctly the entire time.
   Nothing threw, nothing 404'd, and the page looked deliberate.
   tests/test_map.py now compares the prefixes. */

:root{
  /* Ordinal ramp, worst last. Deliberately not a hue circle: the states are
     ranked, so the colour is ranked — deep green through to red, with the
     no-data state stepping out of the ramp entirely into neutral, because it
     is not a degree of anything. Rows whose references merely disagree are
     NOT in the ramp's grey — they get the colour their data earns plus a
     dashed edge, because withholding an answer we have is not caution. */
  --m-identical:#1B6B52; --m-adapter:#86BCA4; --m-earth_lost:#D4941C;
  --m-converter:#B0402D; --m-no_data:#BFC3BF;
  --m-low:#5069A8; --m-high:#A8843D;
  --m-land:#D8DAD5; --m-edge:#FDFDFC; --m-origin:#16181A;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --m-identical:#57B694; --m-adapter:#2F6E58; --m-earth_lost:#C39633;
    --m-converter:#BC5B4C; --m-no_data:#474D50;
    --m-low:#7D92CE; --m-high:#C8A566;
    --m-land:#2B3134; --m-edge:#151A1C; --m-origin:#F2F4F4;
  }
}
:root[data-theme="dark"]{
  --m-identical:#57B694; --m-adapter:#2F6E58; --m-earth_lost:#C39633;
  --m-converter:#BC5B4C; --m-no_data:#474D50;
  --m-low:#7D92CE; --m-high:#C8A566;
  --m-land:#2B3134; --m-edge:#151A1C; --m-origin:#F2F4F4;
}

/* A map wants the window, not a column. The masthead shrinks to a rule with a
   wordmark on it, and everything that is not the map stays at reading width. */
body > header.mast{padding-block:.45rem;border-bottom:1px solid var(--rule)}
body > header.mast .wordmark{font-size:1rem}

.mapctl{display:flex;gap:.6rem;align-items:center;flex-wrap:wrap;margin:1rem 0 .6rem}
.mapctl label{font-weight:600}
.mapctl select{font:inherit;padding:.45rem .6rem;border:1px solid var(--rule);
  border-radius:6px;background:var(--card);color:var(--ink);max-width:min(24rem,100%)}
.mapctl button{font:inherit;padding:.45rem .7rem;border:1px solid var(--rule);
  border-radius:6px;background:var(--sunk);color:var(--ink-soft);cursor:pointer}
.mapctl button[hidden]{display:none}

.maplegend{list-style:none;padding:0;margin:0 0 .6rem;display:flex;flex-wrap:wrap;
  gap:.35rem 1rem;font-size:.88rem;color:var(--ink-soft)}
.maplegend li{display:flex;align-items:center;gap:.4rem;cursor:default}
.maplegend li[hidden]{display:none}
.sw{width:.9rem;height:.9rem;border-radius:3px;display:inline-block;
  border:1px solid rgba(128,128,128,.4)}
.sw-identical{background:var(--m-identical)} .sw-adapter{background:var(--m-adapter)}
.sw-earth_lost{background:var(--m-earth_lost)} .sw-converter{background:var(--m-converter)}
.sw-low{background:var(--m-low)} .sw-high{background:var(--m-high)}
.sw-no_data{background:var(--m-no_data)}
.sw-provisional{background:var(--m-land);
  background-image:repeating-linear-gradient(45deg,transparent 0 3px,rgba(128,128,128,.75) 3px 5px)}

/* Full bleed out of the reading column. The map is the page. */
.mapwrap{position:relative;width:100vw;margin-left:calc(50% - 50vw);
  margin-bottom:1.4rem;background:var(--sunk);
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
#worldmap{display:block;width:100%;height:auto;
  /* Tall enough to be worth looking at, never taller than the window. */
  max-height:calc(100vh - 11rem)}

/* Base and states share this prefix. See the note at the top of the file. */
#worldmap path{fill:var(--m-land);stroke:var(--m-edge);
  /* With vector-effect the width is screen pixels, so the first pass's
     0.004 was four thousandths of a pixel — mathematically a border and
     visually nothing. */
  stroke-width:.55;vector-effect:non-scaling-stroke;
  transition:fill .18s ease,opacity .18s ease}
#worldmap path[data-state=identical]{fill:var(--m-identical)}
#worldmap path[data-state=adapter]{fill:var(--m-adapter)}
#worldmap path[data-state=earth_lost]{fill:var(--m-earth_lost)}
#worldmap path[data-state=converter]{fill:var(--m-converter)}
#worldmap path[data-state=no_data]{fill:var(--m-no_data)}
#worldmap path[data-state=low]{fill:var(--m-low)}
#worldmap path[data-state=high]{fill:var(--m-high)}
#worldmap path[data-state=origin]{fill:var(--m-origin)}
/* Provisional rows keep the colour their data earns and wear the caveat as a
   marking rather than losing the answer to a grey fill. A dashed edge because
   it survives any fill underneath it and does not need a second polygon. */
#worldmap path[data-grade=provisional]{stroke:var(--ink-soft);stroke-width:1;
  stroke-dasharray:3 2}
.mapchips a[data-grade=provisional]{border:1px dashed var(--ink-soft)}
#worldmap a{cursor:pointer}
#worldmap a:hover path{stroke:var(--ink);stroke-width:1.4}
#worldmap a:focus-visible path{outline:none;stroke:var(--ink);stroke-width:2}
#worldmap.dimming path:not(.match){opacity:.18}

/* The inspector is docked, not floating. A cursor-following panel on a map
   this size spends its life covering the country next to the one being read,
   and it cannot be reached at all by keyboard or on a touchscreen. Docked, it
   is in the same place every time and it answers focus as readily as hover. */
.mapinspect{position:absolute;left:.75rem;bottom:.75rem;z-index:5;
  min-width:13rem;max-width:min(20rem,60vw);
  background:var(--card);border:1px solid var(--rule);border-radius:8px;
  padding:.55rem .7rem;font-size:.86rem;line-height:1.4;
  box-shadow:0 6px 20px rgba(0,0,0,.18)}
.mapinspect b{display:block;font-size:1rem}
.mapinspect .m-facts{color:var(--ink-soft)}
.mapinspect .m-state{margin-top:.3rem;font-weight:600}
.mapinspect .m-hint{color:var(--ink-faint);display:block;margin-top:.3rem}
.mapinspect .m-grade{display:block;margin-top:.3rem;color:var(--ink-soft);
  border-left:3px solid var(--ink-faint);padding-left:.45rem}
@media (max-width:640px){
  .mapinspect{position:static;margin:.6rem .75rem .75rem;max-width:none;
    box-shadow:none}
  #worldmap{max-height:none}
}

.mapchips{list-style:none;padding:0;margin:.6rem 0 1.6rem;display:flex;
  flex-wrap:wrap;gap:.35rem}
.mapchips a{display:inline-block;padding:.2rem .55rem;border-radius:999px;
  border:1px solid var(--rule);background:var(--card);font-size:.84rem;
  text-decoration:none;color:var(--ink)}
.mapchips a[data-state=identical]{background:var(--m-identical);color:#fff;border-color:transparent}
.mapchips a[data-state=adapter]{background:var(--m-adapter);color:#10201a;border-color:transparent}
.mapchips a[data-state=earth_lost]{background:var(--m-earth_lost);color:#1c1405;border-color:transparent}
.mapchips a[data-state=converter]{background:var(--m-converter);color:#fff;border-color:transparent}
.mapchips a[data-state=no_data]{background:var(--m-no_data);color:#1a1c1d;border-color:transparent}
.mapchips a[data-state=low]{background:var(--m-low);color:#fff;border-color:transparent}
.mapchips a[data-state=high]{background:var(--m-high);color:#17120a;border-color:transparent}
.mapchips a[data-state=origin]{background:var(--m-origin);color:var(--ground);border-color:transparent}
