svg.map { width:100%; height:auto; display:block; background:var(--sea);
  border:1px solid var(--rule); max-height: 15rem; }
svg.map .land { fill:var(--land); stroke:none }
svg.map .lakes { fill:var(--sea); stroke:none }
/* The fade is on the paths, not the group: a group's opacity composites every
   child, the lit one included, and no rule on the child can undo it. */
svg.map .kin { fill:none; stroke:var(--dim); stroke-width:.15% }
svg.map :where(.kin path) { opacity:.5 }
/* **On the paths, not on the groups.** `--shape` is set per path from its
   `data-kind`, and a `fill:var(--shape)` on the enclosing `<g>` resolves the
   variable *once, at the group*, then paints every child by inheriting the
   computed colour — so every kind came out in the group's own fallback and the
   colour-coding was invisible. Custom properties inherit; the declaration that
   reads one has to live where the value does.

   **`:where()`, because these are on the paths too.** `svg.map .members path`
   is (0,2,2) — `.map` is a class — and outranked `svg.map .hi` at (0,2,1), so a
   member or a subject under the pointer never changed colour: every watershed on
   every map, while pins, the parent outline and kin (styled on the group) lit
   fine. Flattened to (0,1,1), the highlight wins on specificity and not on
   where it happens to sit in the file. */
svg.map :where(.members path) { fill:color-mix(in srgb,var(--shape) 8%,transparent);
  stroke:var(--shape); stroke-width:.18%; opacity:.75 }
svg.map .parent { fill:none; stroke:var(--dim); stroke-width:.25%;
  stroke-dasharray:1%,.8% }
svg.map :where(.subject path) { fill:color-mix(in srgb,var(--shape) 22%,transparent);
  stroke:var(--shape); stroke-width:.35% }

/* --- one hue per shape kind ---
 *
 * A wide frame draws land regions, watersheds, open water and settlements at
 * once — the Northeast Siberia map has all four — and in one accent they read as
 * a single field of overlapping outlines with no way to tell a drainage divide
 * from a coastline from a bay. The kind is declared in `edition/geo/` and travels
 * on the path as `data-kind` (`geomap.owned`), so this is a lookup and not a
 * guess.
 *
 * **Still the shape kind and not the entity class, though the two now agree.**
 * This axis was chosen when `place:` covered a village and a peninsula alike, so
 * the class could not have told a coastline from a drainage divide. The four
 * geographical classes fixed that — `land:`↔`region`, `river:`↔`watershed`,
 * `water:`↔`marine`, `place:`↔a pin — and the rules still key off `data-kind`,
 * because that is what `edition/geo/` declares and what actually travels on the
 * path. Reading the class instead would be a second copy of a fact the store
 * already states, held to it by nothing.
 *
 * `edition.css`'s families are a *coarser* cut of the same axis, not a different
 * one: prose separates land from water and stops, because "point or region" is a
 * question about a map and the map is right here to answer it. The one place the
 * two agree exactly is `--pin`, which paints a settlement's dot here and its name
 * in the sentence beside it.
 *
 * Five kinds, five hues, and `--shape` is the indirection that keeps it one
 * declaration each rather than one per layer.
 *
 * `--basin` for a watershed was already here, as the `.basin` mark on the
 * subject; this generalises it to every watershed on the map instead of only
 * the one being looked at, and the old mark stays because it also decides the
 * *rivers*' relationship to their divide. */
svg.map { --shape:var(--accent) }
svg.map [data-kind="watershed"] { --shape:var(--basin) }
svg.map [data-kind="marine"]    { --shape:var(--water) }
svg.map [data-kind="langarea"]  { --shape:var(--abstract) }
svg.map [data-kind="region"]    { --shape:var(--accent) }
/* The `basin` mark on the root — set by `edition_ui.map_context` when the
   subject's `area:` names a watershed — used to carry a colour rule here: a
   drainage divide drawn in the accent against the blue trunk inside it
   read as two unrelated things. `data-kind="watershed"` now says the same thing
   about *every* watershed on the map rather than only the one being looked at,
   so the rule is gone and the mark is left to the class list, where `map.js` and
   anything else that wants to know what kind of subject this is can still read
   it. Reinstating a paint rule here would also put it in a specificity contest
   with `.hi`, which the comment at the foot of this file exists to warn about. */
/* **Present and unpainted.** The extents of descendants no other layer can
   identify — Chukotka on the Russian Far East's map, which `member_shapes`
   descends straight through. Drawn at all so a hover has something to find;
   drawn invisible because a box on every one of them at once is a field of
   rectangles over the thing you were reading. Set on the group so the `.hi`
   rule on a path simply overrides it, no specificity contest. */
svg.map .extents { fill:none; stroke:none }
svg.map .rivers { fill:none; stroke:var(--water); stroke-width:.22%;
  stroke-linecap:round; opacity:.85 }
/* **A settlement is not a region and must not share its colour.** A pin sits on
   top of whatever boundary contains it, and in the accent it read as one
   more mark in the same family — on the Chukchee Peninsula that is 34 dots over
   an outline of the same colour. `--pin` was declared in the theme and used nowhere; this is
   what it was for. */
svg.map .pin { fill:var(--pin); stroke:var(--card); stroke-width:.15% }
svg.map .pin-label { fill:var(--fg); font-family:var(--ui);
  paint-order:stroke; stroke:var(--sea); stroke-width:.4%;
  stroke-linejoin:round }

/* --- the highlight ---
 *
 * Whatever the pointer is resting on, wherever the link is: a `contains` row, a
 * node in the atlas tree, a name in the running text. Every path and pin carries
 * the entity it belongs to (`geomap.owned`), because nothing about a path's
 * geometry leads back to a record — a member is the nearest descendant *with* a
 * shape, found by descending through those without, and two entities may share
 * one polygon outright.
 *
 * **Last in the file, and every layer rule kept below it in specificity.** A
 * highlight has to beat all of them, and it does so on specificity: `svg.map
 * .hi` is (0,2,1), and a layer rule that reaches the path itself is kept under
 * it with `:where()` — `svg.map .members path` was (0,2,2) and won, which is
 * why no watershed lit for as long as that rule stood.
 * It used to need `svg.map.basin .subject.hi` spelled out beside it, because a
 * `.basin` colour rule outweighed a bare `.hi` and kept the subject red under
 * the pointer — the one shape a reader hovers first. That rule is gone:
 * `data-kind` colours every watershed rather than only the subject, and it sets
 * a custom property instead of a paint, so it enters no contest at all. **A
 * paint rule that reaches a path at (0,2,1) or above breaks the highlight
 * silently** — a tie goes to whichever comes last.
 *
 * `--hi` is its own colour rather than `--sel`. `--sel` is a *state* — the
 * selected card, the draft tag — and it is muted so it can sit beside text all
 * day. This has to carry across a frame of coastline and half a dozen basins at
 * a glance, so it is louder, thicker, and haloed: the stroke is nearly four times
 * a member's, and the pin gets a ring rather than a bigger dot, because `r` is
 * geometry and not something a stylesheet should be reaching into.
 */
svg.map .hi {
  stroke:var(--hi); stroke-width:.75%; stroke-linejoin:round;
  fill:color-mix(in srgb,var(--hi) 45%,transparent);
  paint-order:stroke; opacity:1 }
/* The parent outline is dashed to say it is context rather than subject; under
   the pointer it is the thing being asked about, so it closes up. An extent
   keeps its dashes for the opposite reason — it is a viewport and not a
   boundary, and that stays true while you are looking straight at it. */
svg.map .parent .hi { fill:none; stroke-dasharray:none }
svg.map .extents .hi { stroke-dasharray:1.6%,1.2%; stroke-width:.55%;
  fill:color-mix(in srgb,var(--hi) 16%,transparent) }
svg.map circle.pin.hi { fill:var(--hi); stroke:var(--hi);
  stroke-width:1.2%; stroke-opacity:.35 }

/* --- the tree under the map ---
 *
 * What the map is framed on, and why. It ends at the first common ancestor
 * because that is the node the frame sits on: the tree is a picture of the
 * frame rather than a second navigation, and a reader who wants to know why
 * two villages are shown across half of Chukotka can read the answer directly
 * under the picture that raised the question.
 *
 * **Only what a map means is here.** The shape — the rails, the indentation, the
 * dimmed node and the fold — is `.ent-tree` in edition.css, because the card's
 * `.kin-tree` draws the other hierarchy and the two have to look like one thing
 * for a reader who has learnt to read either. What is left below is the controls,
 * which exist because a node on a map can be painted or not: `.off` is a hidden
 * node — still present, still clickable, saying so.
 */
.map-tree li.off > a.node, .map-tree li.off > .pill { opacity:.6;
  text-decoration:line-through }
/* **At the front of the row and always the same size**, so each is in the same
   place on every row at that depth and names line up whether it shows or not. */
.map-tree button, .map-tree a.entry { display:inline-flex; align-items:center;
  justify-content:center; width:1.3rem; height:1.25rem; margin:.05rem .15rem .05rem 0;
  padding:0; border:1px solid var(--dim); background:var(--bg); color:var(--fg);
  font-size:1rem; line-height:1; text-decoration:none; vertical-align:middle;
  cursor:pointer }
.map-tree button:hover, .map-tree a.entry:hover { background:var(--fg); color:var(--bg) }
/* **Always there on anything selected or hidden**: a selected row is the one a
   reader is working on, and the only way back from a hidden one is its `◌`. On any
   other row they wait for the pointer or the keyboard, or a column of marks beside
   every name reads as a toolbar rather than as a list of places.
   Opacity and not `visibility`, which would keep them out of the tab order. The
   innermost row only: every ancestor of a hovered row is hovered too, which lit
   the controls of the whole chain. A screen with no pointer has no hover to wait
   for, so there they always show. */
.map-tree li > button, .map-tree li > a.entry { opacity:0 }
.map-tree li.sel > button, .map-tree li.sel > a.entry,
.map-tree li.off > button, .map-tree li.off > a.entry,
.map-tree li:hover:not(:has(li:hover)) > button,
.map-tree li:hover:not(:has(li:hover)) > a.entry,
.map-tree li > button:focus-visible, .map-tree li > a.entry:focus-visible { opacity:1 }
@media (hover:none) { .map-tree li > button, .map-tree li > a.entry { opacity:1 } }
/* The rows are taller now, so the box holds about as many of them as it did. */
#secondary .map-tree { max-height:28ch }
