/* giving-map-marks.css — the Giving Map's mark vocabulary: tier/LOD reveal
 * system, routes/braids, land/registers, settlements, engraving, motion,
 * pilot's depth, the pocket chart.
 * Extracted VERBATIM from map.html's inline style block (quiet split,
 * phase 3). ORDER IS LOAD-BEARING: several same-specificity cascades below
 * (ghost lanes, braid reveals, dtier hides) only work because of rule
 * order — do not "clean up" or re-sort this file. Loads AFTER
 * giving-map.css. Versioned in lockstep with gm-render.js: new mark
 * classes land in both. */
/* semantic zoom: tier-2 detail fades in past 1.7× (id-scoped to outrank
   later per-mark opacity rules like .route) */
#map .tier-2 { opacity: 0; pointer-events: none; transition: opacity 0.35s; }
#map.z2 .tier-2 { opacity: 1; pointer-events: auto; }
#map.z2 .route.tier-2, #map.z2 .route-arrow.tier-2 { opacity: 0.65; }
#map .tier-3 { opacity: 0; pointer-events: none; transition: opacity 0.35s; }
#map.z3 .tier-3 { opacity: 1; pointer-events: auto; }
/* z4 "Afoot" (settlements round 2): the village layer, ≥5× — district
   tails and future deep-detail. Same cumulative-class pattern as z2/z3. */
#map .tier-4 { opacity: 0; pointer-events: none; transition: opacity 0.35s; }
#map.z4 .tier-4 { opacity: 1; pointer-events: auto; }
/* a hover-lit isle names itself at any zoom (round 81) — a funded-fleet
   glow with a hidden tier label read as a mystery landmass. Specificity
   0-1-2 outranks every 0-1-1 tier hide above. */
#map .island-label.harbor-hot { opacity: 1; }
#map .dtier-4 { opacity: 0; pointer-events: none; transition: opacity 0.35s; }
#map.z4 .dtier-4 { opacity: 1; }
.city.tier-4 .city-label { font-size: 5.5px; }
/* decor LOD tiers (round G0): opacity-only twins of .tier-2/.tier-3 for pure
   decoration — decor must stay pointer-events:none at every zoom (unlike the
   data .tier-* rules above, which flip pointer-events on), so these get their
   own classes rather than reusing .tier-2/.tier-3. Base hide rule covers both
   tiers; the z2/z3 reveals follow so neither can be shadowed by a later
   same-specificity tier rule. */
#map .dtier-2, #map .dtier-3 { opacity: 0; pointer-events: none; transition: opacity 0.35s; }
#map.z2 .dtier-2 { opacity: 1; }
#map.z3 .dtier-3 { opacity: 1; }
/* ghost lanes: minor trade routes stay faintly visible one tier early — the
   lane stroke only (labels/arrows/ships keep the normal tier reveal). Ordering
   matters: the z3 rule must follow the z2 ghost rule (same specificity, and at
   3.2× the svg carries BOTH .z2 and .z3). */
#map .route.tier-2 { opacity: 0.13; }
#map.z2 .route.tier-3 { opacity: 0.13; }
#map.z3 .route.tier-3, #map.z3 .route-arrow.tier-3 { opacity: 0.65; }
/* hovering a landmass (or sea) lights its whole fan, ghosts included */
#map .route.tier-2.route-hot, #map .route.tier-3.route-hot { opacity: 0.95; }
#map .route-arrow.tier-2.route-hot, #map .route-arrow.tier-3.route-hot { opacity: 0.9; }
/* ── braided trades (round 24). Children are fully hidden at z1 (no ghost —
   they'd double-ink under their trunk) and reveal at their tier's zoom
   while the trunk thins to a residual spine. Order matters: these sit
   after the ghost rules; the route-hot overrides sit last. ── */
#map .route.braid-child, #map.z2 .route.braid-child { opacity: 0; }
#map.z2 .route.braid-child.tier-2, #map.z2 .route-arrow.braid-child.tier-2 { opacity: 0.9; }
#map.z3 .route.braid-child.tier-3, #map.z3 .route-arrow.braid-child.tier-3 { opacity: 0.9; }
#map.z2 .route.braid-trunk:not(.braid-z3), #map.z2 .route-arrow.braid-trunk:not(.braid-z3) { opacity: 0.22; }
#map.z2 .route-label.braid-trunk:not(.braid-z3) { opacity: 0.55; }
#map.z3 .route.braid-trunk.braid-z3, #map.z3 .route-arrow.braid-trunk.braid-z3 { opacity: 0.22; }
#map.z3 .route-label.braid-trunk.braid-z3 { opacity: 0.55; }
/* hover (kin lighting) overrides everything above — a hot trunk re-inks
   fully and hot strands reveal even before their zoom */
#map .route.braid-child.route-hot, #map.z2 .route.braid-child.route-hot { opacity: 0.95; }
#map.z2 .route.braid-trunk.route-hot, #map.z3 .route.braid-trunk.route-hot { opacity: 1; }
#map.z2 .route-arrow.braid-trunk.route-hot, #map.z3 .route-arrow.braid-trunk.route-hot { opacity: 0.9; }
.city.tier-3 .city-label { font-size: 7px; }
/* coastRow sky-labels (round 68): a hairline leader ties each harbor-front
   label down to its hall on the shore below */
.label-leader { fill: none; stroke: var(--label-ink); stroke-width: 0.45; opacity: 0.4; }
.harbor.tier-3 .harbor-label { font-size: 7px; }
.island-label.tier-3, .island-label.small.tier-3 { font-size: 9px; }
.island-label.small.tier-3 .island-value { font-size: 7px; }
.group-foreign .land { stroke-dasharray: 2 4; }
.group-ea .land { fill: var(--land-ea); stroke-dasharray: 3 3; stroke-width: 1.8; }
.group-ea .terrain { display: none; }
/* glass isles (settlements round 2): the FAW isles ride at ×100
   magnification as first-class islands — the fine-beaded double coast is
   one tell; the flourish caption + every tip carry the ×N disclosure */
.group-glass .land { fill: var(--land-ea); stroke-dasharray: 1.2 2.6; stroke-width: 1.7; stroke-linecap: round; }
.group-glass .terrain { display: none; }
/* the cartographer's loupe (round 63): each single glass platform wears its
   magnifier — brass rim + handle ring the island, the ×N power stamped past
   the grip — so "this is off-scale" is visible without reading a tip. The
   FAW chain shares one tiny caption loupe by its flourish instead. */
.loupe { pointer-events: none; }
.loupe-rim { fill: none; stroke: var(--cartouche-edge); stroke-width: 2.6; opacity: 0.92; }
.loupe-rim-inner { fill: none; stroke: var(--cartouche-edge); stroke-width: 0.8; opacity: 0.55; }
.loupe-handle { stroke: var(--cartouche-edge); stroke-width: 4.8; stroke-linecap: round; opacity: 0.92; }
.loupe-ferrule { stroke: var(--cartouche-edge); stroke-width: 6.4; stroke-linecap: butt; opacity: 0.85; }
.loupe-glint { fill: none; stroke: var(--label-halo); stroke-width: 2.4; stroke-linecap: round; opacity: 0.55; }
.loupe-mult { font-size: 11px; font-weight: 700; font-style: italic; fill: var(--value-ink); text-anchor: middle; paint-order: stroke; stroke: var(--label-halo); stroke-width: 2.5px; }
.caption-loupe .loupe-rim { stroke-width: 1.4; }
.caption-loupe .loupe-handle { stroke-width: 2; }
.loupe-mult-caption { text-anchor: start; font-size: 10px; }
.group-recipient .land { stroke-dasharray: 1 3.5; stroke-linecap: round; }
/* recipient-sector provinces (round 15-16): recipient land carries its own
   hue pair — alts of the source green and yellow, related but distinct, so
   recipient land never reads as a source. Washed provinces split
   sector-fed (west, public share) / sector-private (east) via the condo
   mechanism; all-private sectors (.sector-solo) fill sector-private whole.
   (Round 26: recipient land is a BUILT PLATFORM — the register rules below
   swap the dotted coast for solid sea-walls; overlap disclosure moved to
   the register ledger row in the cartouche.) */
.group-sector .land { fill: var(--sector-fed); stroke-dasharray: 1 3.5; stroke-linecap: round; }
.group-sector.sector-solo .land { fill: var(--sector-private); }
.group-sector .condo-coast { stroke-dasharray: 1 3.5; stroke-linecap: round; }
.group-sector .condo-private { fill: var(--sector-private); }
.shore-land { fill: var(--land); stroke: var(--coast); stroke-width: 1.6; stroke-dasharray: 2 4; stroke-linejoin: round; }
.shore-fed { fill: var(--land-fed); }
/* ports read --lane when a src-* class is present (round 61: color-coded at
   both ends), else keep the neutral coast ink */
.port-quay { stroke: var(--lane, var(--coast)); stroke-width: 2; stroke-linecap: round; }
.port-pier { stroke: var(--lane, var(--coast)); stroke-width: 1.2; }
.port-label { font-size: 10px; font-weight: 600; fill: var(--label-ink); paint-order: stroke; stroke: var(--label-halo); stroke-width: 2.5px; }
.port-value { font-size: 8.5px; font-style: italic; fill: var(--value-ink); paint-order: stroke; stroke: var(--label-halo); stroke-width: 2px; }
.island-link { cursor: pointer; }
.island-link:hover .land { stroke-width: 2.2; }
.city.tier-2 .city-label { font-size: 8.5px; }
.harbor.tier-2 .harbor-label { font-size: 8px; }
.route-label.tier-2 { font-size: 10px; }
.mtn-label.tier-2 { font-size: 8.5px; }
.mtn-value.tier-2 { font-size: 7.5px; }

/* ── map styling ── */
.ocean { fill: var(--sea); }
.graticule { stroke: var(--sea-line); stroke-width: 1.5; fill: none; }
/* the paper grain: a baked 256px noise tile repeated over the frame, outside
   the svg — compositor-cheap and steady at every zoom (the old in-svg
   feTurbulence rect re-rasterized on every repaint and its noise scaled with
   the camera). Sits under the HTML chrome (z-index 5) but over the plate. */
.map-frame::after { content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none; background: url(grain.png) repeat; opacity: var(--grain-opacity); }

.coast-ring { stroke: var(--coast-ring); }
.coast-ring.ring1 { opacity: 0.4; } .coast-ring.ring2 { opacity: 0.65; } .coast-ring.ring3 { opacity: 1; }
.waterline { fill: none; stroke: var(--coast); stroke-width: 0.9; pointer-events: none; }
.land { fill: var(--land); stroke: var(--coast); stroke-width: 1.6; stroke-linejoin: round; }
.terrain { fill: var(--terrain); pointer-events: none; }
.group-fed .land { fill: var(--land-fed); }
.group-daf .land { fill: var(--land-daf); stroke-dasharray: 7 5; }
.group-multi .land { fill: var(--land-fed); }
.condo-private { fill: var(--condo-private); pointer-events: none; }
.condo-divider { stroke: var(--coast); stroke-width: 1; stroke-dasharray: 3 3; pointer-events: none; }
.condo-coast { fill: none; stroke: var(--coast); stroke-width: 1.6; stroke-linejoin: round; pointer-events: none; }
/* physics-cluster districts (round A): a dashed "parish border" around a
   cluster's members, and the cluster-name "state" flourish. The border only
   surfaces once its cluster's halls do (z3); the name rides the flourish tiers. */
.parish-border { fill: none; stroke: var(--coast); stroke-width: 0.8; stroke-dasharray: 2 4; stroke-linejoin: round; opacity: 0; pointer-events: none; transition: opacity 0.2s; }
svg.z3 .parish-border { opacity: 0.45; }
.flourish.cluster-name { letter-spacing: 0.1em; opacity: 0.72; }
/* named "states" (round E): dashed borders around a group of existing cities,
   with a crowning flourish. Shown from z2 (region altitude), heavier than a
   parish border. */
.state-border { fill: none; stroke: var(--label-ink); stroke-width: 1.2; stroke-dasharray: 5 5; stroke-linejoin: round; opacity: 0; pointer-events: none; transition: opacity 0.2s; }
svg.z2 .state-border { opacity: 0.5; }
.flourish.state-name { letter-spacing: 0.14em; opacity: 0.78; }
/* localized easter-egg glyphs (round E+): engraved line-art in label ink, a
   discovery reward at z4 "Afoot" (the .egg group carries .tier-4, which gates
   visibility + pointer-events). Glyph-only + hover tip — no persistent text,
   so they never enter the label-collision lint (the ?lint=1 egg census
   measures the hit discs instead). Each egg carries an invisible hit disc
   (the 1px strokes were the whole click target before), a faint gold ground
   stain — the only at-rest hint that the mark is deliberate — and a dotted
   gold ring that blooms when found. */
.egg-art { fill: none; stroke: var(--label-ink); stroke-width: 1.2; stroke-linejoin: round; stroke-linecap: round; opacity: 0.85; }
.egg-art-fill { fill: var(--label-ink); stroke: none; opacity: 0.85; }
.egg { cursor: help; }
.egg-hit { fill: transparent; stroke: none; }
.egg-stain { fill: var(--gold); stroke: none; opacity: 0.09; pointer-events: none; }
/* light theme: 9% gold disappears into the cream parchment — ink it up */
[data-theme="light"] .egg-stain { opacity: 0.17; }
/* the Silent Partner (round 80): a slate seam in the map's public-money
   colour, surfacing through the gold Foundations coast — the gold/slate tint
   contract weaponized as the joke, so this one fill is slate, not label-ink */
.egg-seam { fill: var(--land-fed); stroke: none; opacity: 0.55; pointer-events: none; }
[data-theme="light"] .egg-seam { opacity: 0.66; }
.egg:hover .egg-seam { opacity: 0.9; }
.egg-ring { fill: none; stroke: var(--gold); stroke-width: 1.1; stroke-dasharray: 2 3.5; opacity: 0; transition: opacity 0.25s; pointer-events: none; }
.egg:hover .egg-ring { opacity: 0.9; }
.egg:hover .egg-art, .egg:hover .egg-art-fill { opacity: 1; }
/* the round-19 one-offs share the dressing (round 57): their own art
   classes ink up when found; the triangle's reward is a gold edge, since
   a hit surface over its interior would steal the wreck it encloses */
.egg:hover .dragon-line, .egg:hover .dragon-eye, .egg:hover .dragon-coin, .egg:hover .dragon-z,
.egg:hover .voyager-path, .egg:hover .voyager-body, .egg:hover .voyager-label,
.egg:hover .current-line, .egg:hover .current-arrow,
.egg:hover .bottle-line, .egg:hover .pond-reed { opacity: 1; }
.egg.triangle:hover .triangle-line { stroke: var(--gold); opacity: 0.8; }

/* ── the three registers (round 26). Atolls: the lagoon fill says "money
   only pauses here" — land turned back to water inside a reef ring.
   Platforms: solid double-struck sea-walls (the dotted-coast channel
   retires here), deck grid over the sovereignty wash, pilings, riveted
   expansion joints; micro-platforms get bollards and the recipient gold. ── */
.register-atoll .land { fill: var(--lagoon); stroke-dasharray: 2 3.5; stroke-linecap: round; }
.register-atoll .terrain { display: none; }
.register-platform .land { stroke: var(--platform-wall); stroke-width: 1.7; stroke-dasharray: none; stroke-linejoin: miter; }
.register-platform .condo-coast { stroke: var(--platform-wall); stroke-width: 1.7; stroke-dasharray: none; stroke-linejoin: miter; }
.register-platform.group-recipient .land { stroke-width: 1.4; fill: var(--sector-private); }
/* condo recipient isles (round 68 follow-up): a split isle's BASE is the
   public green — same grammar as the co-funded provinces — with the warm
   private band painted over its gift side; unsplit recipients stay gold */
.register-platform.group-recipient.has-condo .land { fill: var(--sector-fed); }
.group-recipient .condo-private { fill: var(--sector-private); }
.register-platform.island-link:hover .land { stroke-width: 2.6; }
.wall-echo { fill: none; stroke: var(--platform-wall); stroke-width: 0.7; opacity: 0.55; pointer-events: none; }
.piling { stroke: var(--platform-wall); stroke-width: 1; opacity: 0.6; fill: none; pointer-events: none; }
.bollard { fill: var(--platform-wall); stroke: none; opacity: 0.85; pointer-events: none; }
.deck-line { stroke: var(--deck-grid); stroke-width: 1; fill: none; }
.deck-grid { pointer-events: none; }
.platform-echo { stroke-dasharray: none; }
.condo-divider.platform-joint { stroke: var(--platform-wall); stroke-width: 1; stroke-dasharray: 6 3; }
.rivet { fill: var(--platform-wall); opacity: 0.7; }
.rivet-g { pointer-events: none; }
.legend-lagoon { fill: var(--lagoon); stroke: var(--coast); stroke-width: 0.9; stroke-dasharray: 2 2; }
.legend-platform { fill: var(--sector-fed); stroke: var(--platform-wall); stroke-width: 1; }
.legend-deck { stroke: var(--deck-grid); stroke-width: 0.9; fill: none; }
.legend-row { cursor: help; }

.mtn-body { fill: var(--land); stroke: var(--mtn); stroke-width: 1.6; stroke-linejoin: round; }
.mtn-ridge { fill: none; stroke: var(--mtn); stroke-width: 1; opacity: 0.75; }
.mtn-hachure { fill: none; stroke: var(--mtn); stroke-width: 0.9; opacity: 0.55; stroke-linecap: round; }
.mtn-snow { fill: none; stroke: var(--mtn-snow); stroke-width: 1.6; stroke-linejoin: round; }
/* Fog Above the Summit (Ensign Peak): a permanent cloud bank over the summit +
   a dashed ghost apex — the undisclosed reserves the 13F can't show. Drawn in
   the snow/cloud tone (bright on the dark chart, a soft grey on the light one)
   so it reads as weather on the island fill; brightens when the peak is hovered. */
.mtn-fog-band { fill: none; stroke: var(--mtn-snow); stroke-width: 1.5; stroke-linecap: round; opacity: 0.78; pointer-events: none; }
.mtn-fog-ghost { fill: none; stroke: var(--mtn-snow); stroke-width: 1.2; stroke-dasharray: 2 3; stroke-linecap: round; opacity: 0.5; pointer-events: none; }
[data-theme="light"] .mtn-fog-band { stroke: var(--mtn); opacity: 0.6; }
[data-theme="light"] .mtn-fog-ghost { stroke: var(--mtn); opacity: 0.52; }
.mountain:hover .mtn-fog-band { opacity: 0.98; }
.mountain:hover .mtn-fog-ghost { opacity: 0.72; }
/* the Debt Pit (round 84): a peak's ink, but torn. mtn-body's round join
   blunts every cut-back on a mark this small — mitre the corners and thin
   the line so the jags survive. The fill is NOT --land: a hole has to be
   darker than the ground it is in, and on the light chart the land tone is
   the palest thing on the island (it read as a sand patch). The floor then
   darkens again, so the mark carries depth as well as tear. */
.pit-body { fill: #20242a; stroke-linejoin: miter; stroke-miterlimit: 6; stroke-width: 1.1; }
.pit-deep { opacity: 0.42; }
[data-theme="light"] .pit-body { fill: #b0ab8e; }
[data-theme="light"] .pit-deep { opacity: 0.5; }
/* light theme: white-on-cream snowcaps are invisible — re-ink with the
   mountain line instead of the (near-white) snow color */
[data-theme="light"] .mtn-snow { stroke: var(--mtn); stroke-width: 0.5; }
.volcano-smoke { fill: none; stroke: var(--value-ink); stroke-width: 1.1; opacity: 0.7; stroke-linecap: round; }
circle.volcano-smoke { fill: var(--value-ink); stroke: none; opacity: 0.45; }
.hill-line { fill: none; stroke: var(--mtn); stroke-width: 1.1; opacity: 0.6; stroke-linecap: round; }
.tree-leaf, .tree-pine { fill: var(--tree-fill); stroke: var(--tree-line); stroke-width: 0.9; stroke-linejoin: round; }
.tree-trunk { fill: none; stroke: var(--tree-line); stroke-width: 0.9; stroke-linecap: round; }
.forest { pointer-events: none; }

/* themed island structures — decoration, never data */
.struct-line { fill: none; stroke: var(--struct-line); stroke-width: 1; opacity: 0.85; stroke-linecap: round; stroke-linejoin: round; }
ellipse.struct-line { opacity: 0.7; }
.struct-fill { fill: var(--struct-fill); stroke: none; }
.struct-dash { fill: none; stroke: var(--struct-line); stroke-width: 0.9; stroke-dasharray: 4 4; opacity: 0.75; }
.struct-accent { fill: var(--gold); stroke: none; opacity: 0.9; }
.struct-red { fill: var(--route); stroke: var(--route); stroke-width: 1; opacity: 0.8; }
.struct-window { fill: none; stroke: var(--struct-line); stroke-width: 0.7; opacity: 0.6; }
/* canonical struct classes (round G0) — shared vocabulary for future art
   rounds: .struct-shade is the SE-face hatch (NW-light convention), .struct-line-hv
   is the heavy silhouette weight. */
.struct-shade { fill: none; stroke: var(--struct-line); stroke-width: 0.7; opacity: 0.5; stroke-linecap: round; }
.struct-line-hv { fill: none; stroke: var(--struct-line); stroke-width: 1.6; opacity: 0.9; stroke-linecap: round; stroke-linejoin: round; }

/* sea vignettes: ghost line-art beside each sea's label */
.sea-art { fill: none; stroke: var(--sea-ink); stroke-width: 1.1; opacity: 0.55; stroke-linecap: round; stroke-linejoin: round; }
circle.sea-art, ellipse.sea-art { fill: none; }
.sea-art-g { pointer-events: none; }

/* cartouche legend swatches sample the real land palette */
.legend-land { fill: var(--land); stroke: var(--coast); stroke-width: 1; }
.legend-sw { stroke: var(--coast); stroke-width: 0.9; }
.legend-sw-fed { fill: var(--land-fed); }
.legend-sw-priv { fill: var(--land); }
.legend-sw-daf { fill: var(--land-daf); stroke-dasharray: 3 2; }
.mtn-label { font-size: 11px; font-weight: 700; fill: var(--label-ink); text-anchor: middle; paint-order: stroke; stroke: var(--label-halo); stroke-width: 3px; }
.mtn-value { font-size: 9.5px; font-style: italic; fill: var(--value-ink); text-anchor: middle; paint-order: stroke; stroke: var(--label-halo); stroke-width: 2.5px; }

.flag-pole { stroke: var(--value-ink); stroke-width: 1.6; stroke-linecap: round; fill: none; }
.flag-cloth { fill: var(--route); opacity: 0.85; }
.flag-finial { fill: var(--value-ink); }

.city-link { cursor: pointer; }
.city-link:hover .city-label { text-decoration: underline; }

.inset-box { fill: var(--sea); stroke: var(--cartouche-edge); stroke-width: 1.6; opacity: 0.97; }
.inset-title { font-size: 16px; font-weight: 700; fill: var(--ink); }
.inset-sub { font-size: 10.5px; font-style: italic; fill: var(--ink-2); }
.inset-label { font-size: 9.5px; fill: var(--label-ink); text-anchor: middle; paint-order: stroke; stroke: var(--label-halo); stroke-width: 2.5px; }
.inset-isle .land { stroke-width: 1.2; }

.island-label { font-size: 17px; font-weight: 700; text-anchor: middle; fill: var(--label-ink); paint-order: stroke; stroke: var(--label-halo); stroke-width: 3.5px; letter-spacing: 0.02em; pointer-events: none; }
.island-label.small { font-size: 12px; }
.island-value { font-size: 13px; font-weight: 400; fill: var(--value-ink); font-style: italic; }
.island-label.small .island-value { font-size: 10.5px; }

.sea-label { font-style: italic; fill: var(--sea-ink); text-anchor: middle; letter-spacing: 0.22em; }
.sea-value { font-size: 0.62em; letter-spacing: 0.08em; }
.sea-link { cursor: pointer; }
.sea-link:hover tspan:first-child { text-decoration: underline; text-underline-offset: 3px; }
.sea-ext { font-size: 0.55em; letter-spacing: 0; opacity: 0.6; }

.gkey-tick { stroke: var(--sea-ink); stroke-width: 0.8; stroke-dasharray: 2 3; opacity: 0.7; }
.gkey-label { font-size: 10px; font-style: italic; fill: var(--value-ink); paint-order: stroke; stroke: var(--label-halo); stroke-width: 2px; }
.gkey-lane { stroke: var(--route); fill: none; stroke-linecap: round; opacity: 0.75; }
/* fleet-inks legend: mini-lanes in the cartouche icon cell + inked source words */
.legend-lane { fill: none; stroke: var(--lane, var(--route)); stroke-width: 2.4; stroke-linecap: round; stroke-dasharray: 4 3; }
.legend-ink { fill: var(--lane, var(--route)); font-weight: 600; }
.legend-fray { fill: none; stroke: var(--route); stroke-width: 1.5; stroke-linecap: round; opacity: 0.85; }
/* crest medallions: engraved marker ink + one red accent, pure decoration */
.crest { pointer-events: none; }
.crest-ring { fill: var(--sea); fill-opacity: 0.8; stroke: var(--city-stroke); stroke-width: 1.1; }
.crest-line { fill: none; stroke: var(--city-stroke); stroke-width: 1; stroke-linecap: round; stroke-linejoin: round; }
circle.crest-line, ellipse.crest-line { fill: none; }
.crest-fill { fill: var(--city-stroke); stroke: none; }
.crest-red { fill: var(--route-closed); stroke: none; }
.crest-red-line { fill: none; stroke: var(--route-closed); stroke-width: 1.1; stroke-linecap: round; }

.region-label { fill: var(--region-ink); font-weight: 700; letter-spacing: 0.42em; pointer-events: none; }
.region-label.region-small { letter-spacing: 0.24em; }

.route { stroke: var(--lane, var(--route)); stroke-linecap: round; opacity: 0.75; transition: opacity 0.15s; }
.route-closed { stroke: var(--route-closed); opacity: 0.8; }
.route-arrow { fill: var(--lane, var(--route)); opacity: 0.75; transition: opacity 0.15s; }
.route-hot { opacity: 1; filter: drop-shadow(0 0 4px var(--lane, var(--route))); }
/* fleet inks (round 23): a lane flies its SOURCE's colors — src-* classes set
   --lane, and every route-family rule reads var(--lane, var(--route)), so
   unclassed lanes (DAF-outbound, the world's aid) keep the terracotta and the
   closed USAID lane keeps its red. Palette mirrors the public-vs-private
   crosstab, atlas-toned; CVD-checked against both seas. */
.src-ind  { --lane: var(--lane-ind); }
.src-fdn  { --lane: var(--lane-fdn); }
.src-corp { --lane: var(--lane-corp); }
.src-beq  { --lane: var(--lane-beq); }
.src-fed  { --lane: var(--lane-fed); }
/* the DAF ink (round 77): pass-through gold — El DAFrado's deferred gold
   sails the whole system, sponsor strand → confluence → distributary, so
   one continuous color IS the route's legibility. Clay stays the world's. */
.src-daf  { --lane: var(--lane-daf); }
/* the remittance ink (remittance round): UNINKED by design — parchment, the
   paper's own tone, because these dollars sit outside every source ledger on
   this chart (not Giving USA, not aid). Pale on the dark sea, sepia on the
   light. The Sending Strand's foreshore band wears the same non-ink. */
.src-remit { --lane: var(--lane-remit); }
/* the Remittances isle (remittance-isle round): real land, area-exact —
   but OFF the Giving USA ledger, so it wears the off-ledger dashes (the
   foreign-register grammar) over a parchment-warmed land tone. */
.group-remit .land { fill: var(--land-remit); stroke-dasharray: 2 4; }
/* c4 fleet (fog-bank round): non-deductible advocacy money — real, raised,
   and OFF the Giving USA ledger like the remittances, so it flies the same
   off-ledger dashes over a cold fog-gray: the donors are legally unlisted. */
.group-c4 .land { fill: var(--land-c4); stroke-dasharray: 2 4; }
.remit-strand-band { fill: none; stroke: var(--lane-remit); stroke-width: 13; opacity: 0.3; stroke-linejoin: round; stroke-linecap: round; }
.remit-strand-mark { fill: none; stroke: var(--lane-remit); stroke-width: 1.2; stroke-dasharray: 1.6 4.4; opacity: 0.8; stroke-linecap: round; }
.remit-strand-label { fill: var(--lane-remit); opacity: 0.85; }

.anchor-line { fill: none; stroke: var(--city-stroke); stroke-width: 1.5; stroke-linecap: round; }
.anchor-ripple { fill: none; stroke: var(--sea-ink); stroke-width: 1; opacity: 0.55; }
.harbor-hit { fill: transparent; stroke: none; }
.harbor-label { font-size: 10.5px; font-style: italic; fill: var(--sea-ink); paint-order: stroke; stroke: var(--label-halo); stroke-width: 2.5px; }
/* hovering a funder/evaluator isle lights its harbors (fundedBy), tier
   opacity overridden so the fleet reveals at any zoom — mirrors route-hot */
.harbor-hot { filter: drop-shadow(0 0 4px var(--route)); }
.harbor-hot .harbor-label { fill: var(--route); }
#map .harbor.tier-2.harbor-hot, #map .harbor.tier-3.harbor-hot { opacity: 1; }
/* settled halls share the funder-glow pathway (and its any-zoom reveal) */
.settlement.harbor-hot .city-label { fill: var(--route); }
#map .settlement.tier-3.harbor-hot, #map .settlement.tier-4.harbor-hot { opacity: 1; pointer-events: auto; }
/* city marks as cross-light targets (fed wiring round) — same pathway */
.city.harbor-hot .city-label { fill: var(--route); }
#map .city.tier-2.harbor-hot, #map .city.tier-3.harbor-hot, #map .city.tier-4.harbor-hot { opacity: 1; pointer-events: auto; }
/* fundedBy islands (round 44): the shoals glass platform glows from CG */
#map .island.tier-2.harbor-hot, #map .island.tier-3.harbor-hot, #map .island.tier-4.harbor-hot { opacity: 1; pointer-events: auto; }
.route-hit { stroke: transparent; }
/* the DAF formation boundary (round 79): the dashed gold hull the
   distributaries connect to — territorial line, quieter than a lane */
.daf-bound { stroke: var(--lane, var(--route)); stroke-width: 2.6; stroke-dasharray: 9 5; stroke-linecap: round; opacity: 0.85; }
.route-label { font-size: 13px; font-style: italic; fill: color-mix(in srgb, var(--label-ink) 65%, var(--lane, var(--route))); text-anchor: middle; paint-order: stroke; stroke: var(--label-halo); stroke-width: 3px; pointer-events: none; }
.route-label.closed { fill: var(--route-closed); }

.wreck-fill { fill: var(--route-closed); opacity: 0.16; stroke: none; }
.wreck-line { fill: none; stroke: var(--route-closed); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.wreck-plank { fill: none; stroke: var(--route-closed); stroke-width: 0.9; opacity: 0.7; }
.wreck-sail { fill: none; stroke: var(--route-closed); stroke-width: 1; opacity: 0.85; stroke-linejoin: round; }
.wreck-wave { fill: none; stroke: var(--sea-ink); stroke-width: 1.3; opacity: 0.75; stroke-linecap: round; }

.ship-hull { fill: var(--lane, var(--route)); stroke: none; opacity: 0.95; }
.ship-line { fill: none; stroke: var(--lane, var(--route)); stroke-width: 1.4; stroke-linecap: round; }
.ship-sail { fill: var(--mtn-snow); stroke: var(--coast); stroke-width: 0.9; opacity: 0.95; stroke-linejoin: round; }
.ship-pennant { fill: var(--lane, var(--route)); }
.ship-wake { fill: none; stroke: var(--sea-ink); stroke-width: 1.1; opacity: 0.6; stroke-linecap: round; }
.ship { cursor: pointer; }

/* berth piers (round 61): the destination end of every drawn lane, in the
   lane's source ink. Reveal/opacity rides the same tier classes as routes. */
.pier { pointer-events: none; }
.pier-quay { fill: none; stroke: var(--lane, var(--route)); stroke-width: 2; stroke-linecap: round; }
.pier-finger { fill: none; stroke: var(--lane, var(--route)); stroke-width: 1.1; opacity: 0.85; }
.pier-bollard { fill: var(--lane, var(--route)); stroke: none; }
.pier-mast-line { fill: none; stroke: var(--lane, var(--route)); stroke-width: 1.1; }
#map .pier { opacity: 0.85; transition: opacity 0.15s; }
#map .pier.tier-2, #map .pier.tier-3 { opacity: 0; }
#map.z2 .pier.tier-2 { opacity: 0.75; }
#map.z3 .pier.tier-3 { opacity: 0.75; }
#map .pier.route-hot { opacity: 1; }
/* the open roadstead (DAF-out): a harbor-limit arc + mooring buoys — the
   deliberately-untargeted flow anchors offshore, claiming no port */
.roadstead-arc { fill: none; stroke: var(--route); stroke-width: 1.1; stroke-dasharray: 5 5; opacity: 0.55; }
.roadstead-buoy { fill: none; stroke: var(--route); stroke-width: 1.2; }

.wave2 { fill: none; stroke: var(--sea-ink); stroke-width: 1.2; opacity: 0.3; stroke-linecap: round; pointer-events: none; }

/* ── engraved richness pass (round 17) — all decoration, no figures ── */
/* shoaling stipple: engraved dots in the shallows just off every coast */
.shoal { fill: none; stroke: var(--sea-ink); stroke-width: 1.15; stroke-linecap: round; pointer-events: none; }
/* dark-theme z2 sea bump (round G0): chop/shoal texture underreads at 1.7×
   against the dark ocean fill. Dark is the :root default, so the bump is
   unscoped (.wave2 base opacity 0.3, .shoal's inline SVG opacity 0.32, each
   ~20% relative); the light-theme override below restores the original
   values, since light's paler sea doesn't need the boost. */
#map.z2 .wave2 { opacity: 0.36; }
#map.z2 .shoal { opacity: 0.38; }
[data-theme="light"] #map.z2 .wave2 { opacity: 0.3; }
[data-theme="light"] #map.z2 .shoal { opacity: 0.32; }
/* decorative rivers on the great landmasses */
.river { fill: none; stroke: var(--river); stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
/* short hachure ticks just inside large coasts — the engraver's shadow */
.coast-hachure { fill: none; stroke: var(--coast); stroke-width: 0.7; opacity: 0.35; stroke-linecap: round; pointer-events: none; }
/* rhumb-line fan from the compass rose, under everything but the ocean —
   split major (aligned with the 8 main compass points) / minor (halves) */
.rhumb { stroke: var(--sea-line); stroke-width: 1; fill: none; pointer-events: none; }
.rhumb-major { opacity: 0.1; }
.rhumb-minor { opacity: 0.06; stroke-dasharray: 4 3; }
/* shadow flank on mountain east faces */
.mtn-shade { fill: var(--mtn); opacity: var(--mtn-shade-op); stroke: none; pointer-events: none; }
/* engraved double-rule map frame */
.frame-rule { fill: none; stroke: var(--cartouche-edge); pointer-events: none; }
/* neatline tick band + corner medallions (Engraver's Pass) */
.frame-tick { fill: none; stroke: var(--cartouche-edge); stroke-width: 0.6; opacity: 0.4; pointer-events: none; }
.frame-tick.major { stroke-width: 1.2; opacity: 0.6; }
.medallion { pointer-events: none; }
.medallion-ring { fill: none; stroke: var(--cartouche-edge); stroke-width: 0.9; opacity: 0.55; }
.medallion-line { fill: none; stroke: var(--cartouche-edge); stroke-width: 0.8; opacity: 0.55; stroke-linecap: round; }
/* graduated-key framing: bracket rule + corner ticks + drafting dividers */
.gkey-bracket { fill: none; stroke: var(--sea-ink); stroke-width: 0.9; opacity: 0.55; stroke-linecap: round; }
.gkey-divider { fill: none; stroke: var(--sea-ink); stroke-linecap: round; }
/* torn edges on the two off-scale shores (Engraver's Pass) */
.torn-fiber { fill: none; stroke: var(--coast); stroke-width: 0.5; opacity: 0.55; stroke-linecap: round; pointer-events: none; }
.torn-fiber.thick { stroke-width: 0.8; }
.torn-inner { fill: none; stroke: var(--coast); stroke-width: 1; opacity: 0.3; stroke-dasharray: 6 4; pointer-events: none; }
.torn-scrap { fill: none; stroke: var(--coast); stroke-width: 2; opacity: 0.5; stroke-linecap: round; pointer-events: none; }
/* Engraver's Pass ocean creatures: pure decor, inert at every zoom */
.decor-inert { pointer-events: none; }

.city { cursor: default; }
.town-house { fill: var(--city-fill); stroke: var(--city-stroke); stroke-width: 1.3; stroke-linejoin: round; }
.town-door { fill: none; stroke: var(--city-stroke); stroke-width: 0.8; opacity: 0.8; }
.keep-wall, .keep-tower { fill: var(--gold); stroke: var(--gold-stroke); stroke-width: 1.2; stroke-linejoin: round; }
.keep-gate { fill: none; stroke: var(--gold-stroke); stroke-width: 1; }
.keep-flag { fill: var(--route); }
.city-label { font-size: 11.5px; fill: var(--label-ink); paint-order: stroke; stroke: var(--label-halo); stroke-width: 3px; }

.peak-label { font-size: 10.5px; font-style: italic; fill: var(--value-ink); paint-order: stroke; stroke: var(--label-halo); stroke-width: 2.5px; }

/* storm pennant (fed F-3): gale warning for sieges survived — sea ink,
   swallowtail, deliberately unlike the donor banner flags */
.storm-pennant { fill: var(--sea-ink); stroke: var(--sea-ink); stroke-width: 0.6; stroke-linejoin: round; opacity: 0.85; }
.ruin-col, .ruin-fallen { fill: none; stroke: var(--route-closed); stroke-width: 1.4; stroke-linejoin: round; stroke-linecap: round; }
.ruin-flute { fill: none; stroke: var(--route-closed); stroke-width: 0.7; opacity: 0.6; }
.ruin-ground { fill: none; stroke: var(--route-closed); stroke-width: 0.9; opacity: 0.5; stroke-dasharray: 2 3; }
.ruin-rubble { fill: var(--route-closed); opacity: 0.7; }
.ruin-label { font-size: 11px; font-style: italic; fill: var(--route-closed); paint-order: stroke; stroke: var(--label-halo); stroke-width: 2.5px; }

.lh-rock { fill: var(--land); stroke: var(--coast); stroke-width: 1.2; }
.lh-tower { fill: var(--city-fill); stroke: var(--city-stroke); stroke-width: 1.3; stroke-linejoin: round; }
.lh-band { fill: none; stroke: var(--city-stroke); stroke-width: 1; opacity: 0.8; }
.lh-light { fill: var(--gold); stroke: var(--gold-stroke); stroke-width: 0.9; }
.lh-rays { stroke: var(--gold); stroke-width: 1.4; fill: none; stroke-linecap: round; }
.lh-wave { fill: none; stroke: var(--sea-ink); stroke-width: 1.1; opacity: 0.6; stroke-linecap: round; }
.beacon-label { font-size: 11px; fill: var(--sea-ink); paint-order: stroke; stroke: var(--label-halo); stroke-width: 2.5px; }

.flourish { font-style: italic; fill: var(--sea-ink); text-anchor: middle; letter-spacing: 0.14em; opacity: 0.8; }
.serp-line { fill: none; stroke: var(--sea-ink); stroke-width: 1.6; opacity: 0.8; stroke-linecap: round; stroke-linejoin: round; }
.serp-spike { fill: none; stroke: var(--sea-ink); stroke-width: 1.2; opacity: 0.75; stroke-linecap: round; }
.serp-eye { fill: var(--sea-ink); opacity: 0.9; }
.serp-ripple { fill: none; stroke: var(--sea-ink); stroke-width: 1; opacity: 0.45; stroke-linecap: round; }
/* round 19 easter eggs: the dragon sleeps in land ink, the current and
   Voyager ride the sea ink; flourishes with tooltips invite the hover */
.flourish-tip { cursor: help; }
.dragon-line { fill: none; stroke: var(--value-ink); stroke-width: 1.25; opacity: 0.7; stroke-linecap: round; stroke-linejoin: round; }
.dragon-eye { fill: none; stroke: var(--value-ink); stroke-width: 1; opacity: 0.8; stroke-linecap: round; }
.dragon-coin { fill: none; stroke: var(--value-ink); stroke-width: 0.85; opacity: 0.55; }
.dragon-z { fill: var(--value-ink); opacity: 0.55; font-style: italic; font-weight: 700; }
.dragon { cursor: help; }
.hourglass-line { fill: none; stroke: var(--value-ink); stroke-width: 1; opacity: 0.75; stroke-linecap: round; }
.hourglass-sand { fill: var(--value-ink); opacity: 0.5; }
.voyager-path { fill: none; stroke: var(--sea-ink); stroke-width: 1.1; stroke-dasharray: 1.5 5; opacity: 0.6; stroke-linecap: round; }
.voyager-body { fill: none; stroke: var(--sea-ink); stroke-width: 1.1; opacity: 0.85; stroke-linecap: round; }
.voyager-label { font-size: 9px; font-style: italic; fill: var(--sea-ink); opacity: 0.8; text-anchor: middle; }
.voyager { cursor: help; }
.current-line { fill: none; stroke: var(--sea-ink); stroke-width: 1.15; opacity: 0.5; stroke-linecap: round; stroke-dasharray: 10 6; }
.current-arrow { fill: none; stroke: var(--sea-ink); stroke-width: 1.15; opacity: 0.55; stroke-linecap: round; }
.pond { fill: var(--sea); stroke: var(--coast); stroke-width: 0.9; }
.pond-reed { fill: none; stroke: var(--value-ink); stroke-width: 0.9; opacity: 0.6; stroke-linecap: round; }
.bottle-line { fill: none; stroke: var(--sea-ink); stroke-width: 1; opacity: 0.8; stroke-linecap: round; stroke-linejoin: round; }
.triangle-line { fill: none; stroke: var(--sea-ink); stroke-width: 1.1; stroke-dasharray: 7 5; opacity: 0.45; stroke-linejoin: round; }
.berth-anchor .anchor-line { stroke-dasharray: 2 2; opacity: 0.55; }

.compass-ring { fill: none; stroke: var(--sea-ink); stroke-width: 1.4; opacity: 0.7; }
.compass-ring.inner { opacity: 0.35; }
.compass-ring.hairline { stroke-width: 0.6; opacity: 0.4; }
.compass-line { stroke: var(--sea-ink); stroke-width: 1; opacity: 0.55; }
.compass-needle { stroke: var(--sea-ink); stroke-width: 0.7; opacity: 0.4; fill: none; }
.compass-pt-dark { fill: var(--sea-ink); opacity: 0.9; }
.compass-pt-light { fill: var(--mtn-snow); opacity: 0.75; stroke: var(--sea-ink); stroke-width: 0.5; }
.compass-hub { fill: var(--gold); stroke: var(--gold-stroke); stroke-width: 0.8; }
.compass-label { fill: var(--sea-ink); font-size: 15px; text-anchor: middle; font-style: italic; }
/* the fleur-de-lis north: the one earned plate-chrome gold, fixed px */
.compass-fleur-vein { stroke: var(--gold); stroke-width: 1.5; fill: none; opacity: 0.85; }

.cartouche-box { fill: var(--cartouche-bg); stroke: var(--cartouche-edge); stroke-width: 1.6; opacity: 0.96; }
.cartouche-inner { fill: none; stroke: var(--cartouche-edge); stroke-width: 0.8; opacity: 0.7; }
.cartouche-title { font-size: 31px; font-weight: 700; fill: var(--ink); letter-spacing: 0.02em; }
.cartouche-sub { font-size: 17px; font-style: italic; fill: var(--ink-2); }
.cartouche-note { font-size: 12.5px; fill: var(--ink-2); }
.cartouche-credit { font-size: 11px; font-style: italic; fill: var(--ink-2); opacity: 0.8; }
/* strapwork corners + swash fleuron (Engraver's Pass) — fixes the two
   previously-unstyled classes (cartouche-curl/-diamond fell back to a
   default black fill) as part of the same corner rework */
.cartouche-curl { fill: none; stroke: var(--cartouche-edge); stroke-width: 0.9; opacity: 0.7; stroke-linecap: round; stroke-linejoin: round; }
.cartouche-diamond { fill: var(--cartouche-edge); opacity: 0.6; }
.cartouche-strap { fill: none; stroke: var(--cartouche-edge); stroke-width: 0.9; opacity: 0.6; stroke-linecap: round; stroke-linejoin: round; }
/* engraved-statuary allegories, capped small, no facial marks */
.cartouche-figure { fill: none; stroke: var(--cartouche-edge); stroke-width: 1; opacity: 0.8; stroke-linecap: round; stroke-linejoin: round; }
.cartouche-figure-fill { fill: var(--cartouche-edge); opacity: 0.4; stroke: none; }
/* the naming-rights siren's figure — sea-ink family, matches the resident
   creatures rather than the plate's bronze/edge ink */
.figure-line { fill: none; stroke: var(--sea-ink); stroke-width: 1; opacity: 0.8; stroke-linecap: round; stroke-linejoin: round; }
.figure-fill { fill: var(--sea-ink); opacity: 0.45; stroke: none; }

/* ── motion: the map breathes — money drifts down its lanes, ships ride at
   anchor, the volcano smokes, the lighthouse turns. Purely decorative and
   fully disabled under prefers-reduced-motion. ── */
@media (prefers-reduced-motion: no-preference) {
  /* the lane drift is JS-ticked now (the drift block in gm-interact.js):
     a CSS stroke-dashoffset animation forces a whole-document SVG layout
     every frame in Blink — ~486ms of main thread per idle second for 26
     paths, measured. The keyframes that remain animate transform/opacity
     only, which the compositor handles off the main thread. */
  .ship-bob { animation: ship-bob 4.5s ease-in-out infinite; }
  .volcano-smoke { animation: smoke-drift 6s ease-in-out infinite; }
  .lh-light, .lh-rays { animation: lh-pulse 3.5s ease-in-out infinite; }
}
@keyframes ship-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(1.7px); } }
@keyframes smoke-drift { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2.2px); } }
@keyframes lh-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }

/* ── pilot's depth (round 27) ── */
#pinned { display: none; position: fixed; z-index: 3200; max-width: 360px; background: var(--tip-bg); border: 1px solid var(--gold); border-radius: 6px; padding: 10px 30px 10px 12px; font-size: 0.82rem; line-height: 1.45; color: var(--ink); box-shadow: 0 8px 30px rgba(0,0,0,0.4); }
#pinned .tip-note { color: var(--ink-2); font-size: 0.76rem; margin-top: 3px; }
.pin-close { position: absolute; top: 5px; right: 6px; background: none; border: none; color: var(--ink-2); cursor: pointer; font-size: 13px; font-family: inherit; line-height: 1; }
.pin-close:hover { color: var(--ink); }

/* harbor registers (round 61): the pinned card widens into a ledger.
   The coverage meter and the veil row are structural honesty devices —
   a ranked list without them implies completeness the filings don't have. */
#pinned.pin-ledger { max-width: 430px; max-height: 76vh; overflow-y: auto; }
.reg-hint { color: var(--gold); font-size: 0.72rem; margin-top: 5px; opacity: 0.85; }
/* source links on a pinned card. Only ever rendered inside #pinned — #tooltip
   is pointer-events:none, so a link in a hover cannot be clicked at all. */
.pin-src { margin-top: 7px; font-size: 0.74rem; }
.pin-src a { color: var(--gold); text-decoration: none; border-bottom: 1px dotted var(--gold); }
.pin-src a:hover { border-bottom-style: solid; }
#pinned .tip-note a { color: var(--gold); text-decoration: none; border-bottom: 1px dotted var(--gold); }
#pinned .tip-note a:hover { border-bottom-style: solid; }
.harbor-register { margin-top: 8px; border-top: 1px solid var(--tip-edge); padding-top: 7px; }
.reg-head { font-variant: small-caps; letter-spacing: 0.06em; color: var(--gold); font-size: 0.78rem; }
.reg-meter { height: 7px; margin: 6px 0 3px; border: 1px solid var(--gold-stroke); border-radius: 2px; overflow: hidden;
  background: repeating-linear-gradient(-45deg, transparent 0 3px, var(--ink-2) 3px 4px); opacity: 0.9; }
.reg-meter span { display: block; height: 100%; background: var(--gold); }
.reg-cover { font-size: 0.74rem; color: var(--ink-2); margin-bottom: 5px; }
.reg-cover b { color: var(--ink); font-weight: 600; }
table.reg-rows { width: 100%; border-collapse: collapse; font-size: 0.76rem; }
.reg-rows td { padding: 1.5px 4px 1.5px 0; vertical-align: baseline; }
/* the chip hugs its own text — as a <td> border it stretched down the whole
   height of a tall row */
.reg-kind { text-align: center; vertical-align: baseline; white-space: nowrap; }
.reg-chip { display: inline-block; font-size: 0.6rem; letter-spacing: 0.04em; color: var(--ink-2); border: 1px solid var(--tip-edge); border-radius: 3px; padding: 0 3px; line-height: 1.35; }
.reg-chip.reg-kind-pf, .reg-kind-pf { color: var(--gold); border-color: var(--gold-stroke); }
.reg-chip.reg-kind-daf, .reg-kind-daf { color: var(--ink-2); border-style: dashed; }
.reg-chip.reg-kind-gov, .reg-kind-gov { color: var(--lane-fed); border-color: var(--lane-fed); }
.reg-chip.reg-kind-corp, .reg-kind-corp { color: var(--lane-corp); border-color: var(--lane-corp); }
.reg-chip.reg-kind-self, .reg-kind-self { color: var(--lane-ind); border-color: var(--lane-ind); }
.reg-chip.reg-kind-veil, .reg-kind-veil { color: var(--ink-2); background: repeating-linear-gradient(-45deg, transparent 0 2px, rgba(128,128,128,0.25) 2px 3px); }
.reg-chip.reg-kind-individual, .reg-kind-individual { color: var(--lane-ind); border-color: var(--lane-ind); }
.reg-chip.reg-kind-in-kind, .reg-kind-in-kind { color: var(--lane-corp); border-color: var(--lane-corp); border-style: dotted; }
/* WALL was the only one of the nine kinds with no rule of its own — it fell
   through to the plain grey chip. A recognition-wall tier is named-but-not-
   measured, so it gets a dotted edge in the muted ink: visibly a different
   claim from the filed figures above it. */
.reg-chip.reg-kind-banded, .reg-kind-banded { color: var(--ink-2); border-style: dotted; }
/* a band is a threshold, not an audited amount — never let it read as one */
.reg-band { color: var(--ink-2); font-style: italic; font-size: 0.72rem; }
.reg-name { color: var(--ink); }
.reg-note { color: var(--ink-2); font-size: 0.68rem; }
/* a roster note owns the full width of the ledger rather than the sliver
   left over beside two nowrap money columns */
tr.reg-noterow td.reg-note { padding: 0 0 4px 0; line-height: 1.4; }
.reg-amt { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); white-space: nowrap; }
.reg-year { text-align: right; color: var(--ink-2); font-size: 0.7rem; white-space: nowrap; }
.reg-year a { color: var(--ink-2); text-decoration: underline dotted; }
.reg-year a:hover { color: var(--gold); }
tr.reg-veil td { border-top: 1px dashed var(--tip-edge); padding-top: 4px; }
tr.reg-veil .reg-amt, tr.reg-veil .reg-name { color: var(--ink-2); }
.reg-src { color: var(--ink-2); font-size: 0.68rem; padding-bottom: 4px; }
.reg-departed { margin-top: 6px; font-size: 0.7rem; color: var(--ink-2); font-style: italic; }
.reg-foot { margin-top: 6px; font-size: 0.68rem; color: var(--ink-2); border-top: 1px solid var(--tip-edge); padding-top: 4px; }

/* quay-ring: the z3 mooring ring on register-bearing towns */
#map .quay-ring { fill: none; stroke: var(--gold-stroke); stroke-width: 0.7; stroke-dasharray: 2.5 2; opacity: 0; transition: opacity 0.3s; }
#map.z3 .quay-ring { opacity: 0.75; }
.altitude { position: absolute; left: 14px; bottom: 14px; z-index: 5; font-size: 0.74rem; font-style: italic; color: var(--ink-2); background: var(--cartouche-bg); border: 1px solid var(--cartouche-edge); border-radius: 10px; padding: 3px 12px; opacity: 0.92; pointer-events: none; }
.rod { pointer-events: none; }
.rod-line { stroke: var(--gold); stroke-width: 1.4; stroke-dasharray: 5 4; fill: none; stroke-linecap: round; }
.rod-label { font-size: 12px; font-style: italic; fill: var(--gold); text-anchor: middle; paint-order: stroke; stroke: var(--label-halo); stroke-width: 3px; }
.region-label.region-hot { pointer-events: auto; cursor: help; }
.island.land-hot .land, .island.land-hot .condo-coast { stroke-width: 2.6; }
#map .route-label.tier-2.route-hot, #map .route-label.tier-3.route-hot { opacity: 1; }

#tooltip { display: none; position: fixed; z-index: 3100; max-width: 340px; background: var(--tip-bg); border: 1px solid var(--tip-edge); border-radius: 6px; padding: 9px 12px; font-size: 0.82rem; line-height: 1.45; color: var(--ink); box-shadow: 0 6px 24px rgba(0,0,0,0.3); pointer-events: none; }
#tooltip .tip-note { color: var(--ink-2); font-size: 0.76rem; margin-top: 3px; }

.notes { max-width: 1720px; margin: 22px auto 0; padding: 0 18px; font-size: 0.82rem; line-height: 1.65; color: var(--ink-2); }
.notes h2 { font-size: 0.9rem; color: var(--ink); margin-bottom: 6px; letter-spacing: 0.05em; }
.notes .legend-header { display: flex; align-items: baseline; gap: 12px; }
.notes .expand-toggle { font-size: 0.76rem; color: var(--ink-2); cursor: pointer; border: none; background: none; font-family: inherit; text-decoration: underline; text-underline-offset: 2px; padding: 0; }
.notes .expand-toggle:hover { color: var(--ink); }
.notes p { margin-bottom: 8px; }
.notes b { color: var(--ink); font-weight: 600; }
/* Thirteen collapsed one-liners stacked vertically pushed the map most of a
   screen up the page. Closed, they now sit in columns — the plate keeps the
   fold and the whole contract is still scannable at a glance. An OPEN section
   takes the full width, because its body is a paragraph, not a column. */
.note-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(430px, 1fr)); gap: 0 26px; align-items: start; }
.note-section { border-bottom: 1px solid var(--cartouche-edge); padding: 6px 0; }
.note-section:last-of-type { border-bottom: none; }
.note-section[open] { grid-column: 1 / -1; }
/* a paragraph running the full 1720px is unreadable however much room there is */
.note-section[open] .note-body { max-width: 92ch; }
.note-section summary { cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: 6px; }
.note-section summary::-webkit-details-marker { display: none; }
.note-section summary::before { content: '▸'; font-size: 0.72rem; color: var(--ink-2); flex-shrink: 0; transition: transform 0.15s; }
.note-section[open] summary::before { transform: rotate(90deg); }
.note-section summary b { color: var(--ink); font-weight: 600; }
.note-section .note-teaser { color: var(--ink-2); font-style: italic; }
.note-section .note-body { margin: 6px 0 4px 14px; }
.notes table { border-collapse: collapse; margin-top: 10px; width: 100%; max-width: 980px; }
.notes th, .notes td { text-align: left; padding: 4px 12px 4px 0; border-bottom: 1px solid var(--cartouche-edge); vertical-align: top; }
.notes th { color: var(--ink); font-weight: 600; }
.notes td:nth-child(3) { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ── the pocket chart: on a phone the plate goes full-bleed and fills the
   screen, the camera crops the world to the glass (portrait shows a tall
   slice, no letterbox — see the camera in gm-interact.js), and the pinned
   card becomes a bottom sheet. Desktop is untouched above 768px. ── */
.about-strip { display: none; }
@media (max-width: 768px), ((pointer: coarse) and (max-height: 500px)) {
  body { padding: 90px 0 40px; }
  .map-frame { aspect-ratio: auto; max-height: none; height: calc(100vh - 138px); height: calc(100dvh - 138px); }
  #zfull { display: none; }
  svg#map { height: 100%; touch-action: none; }
  .zoom-ctl { gap: 8px; }
  .zoom-ctl button { width: 44px; height: 44px; font-size: 22px; }
  #tooltip { display: none !important; }
  #pinned { left: 0 !important; right: 0; top: auto !important; bottom: 0; max-width: none; max-height: 45vh; overflow-y: auto; -webkit-overflow-scrolling: touch; border-left: none; border-right: none; border-bottom: none; border-radius: 12px 12px 0 0; padding: 14px 44px 18px 16px; }
  .pin-close { width: 34px; height: 34px; top: 8px; right: 8px; font-size: 18px; }
  #altitude { max-width: calc(100vw - 80px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .about-strip { display: block; width: 100%; height: 48px; border: none; border-top: 1px solid var(--cartouche-edge); background: var(--cartouche-bg); color: var(--ink-2); font-family: inherit; font-size: 0.82rem; font-style: italic; cursor: pointer; }
  .notes { padding: 0 16px; }
  .note-grid { grid-template-columns: 1fr; }
}
/* phones & touch devices: skip the two costly raster effects — the paper
   grain's feTurbulence and the always-running decorative animations are the
   difference between a smooth pinch and a janky one on a phone GPU */
@media (max-width: 768px), (pointer: coarse) {
  .map-frame::after { display: none; }   /* the baked grain tile */
  .ship-bob, .volcano-smoke, .lh-light, .lh-rays { animation: none !important; }
}

/* ── ?keep=1 diagnostic overlay: the keep ledger's claims (gm-services.js) ── */
.keep-debug { fill: rgba(235, 90, 90, 0.08); stroke: rgba(235, 90, 90, 0.45); stroke-width: 0.6; pointer-events: none; }
.keep-debug.keep-sea { fill: rgba(90, 160, 235, 0.08); stroke: rgba(90, 160, 235, 0.45); }

/* paper peak (round 74): an endowment that exists as private-company
   equity — a valuation, not a filing. Dashed silhouette, land showing
   through: the height is the claim, the dashes are the doubt. */
.mtn-paper .mtn-body { fill: none; stroke-dasharray: 5 3.5; stroke-width: 2.1; }
.mtn-paper .mtn-shade { opacity: 0.18; }
.mtn-paper .mtn-ridge { stroke-dasharray: 3 2.5; stroke-width: 1.4; }
.mtn-paper .mtn-hachure { opacity: 0.55; stroke-dasharray: 2.5 2; }
.mtn-paper .mtn-snow { display: none; }

/* ── The Estate Survey (tracts) ─────────────────────────────────────────────
   An island's major uses of funds, drawn as area-exact tracts of its own
   land. Two dresses, one mechanism: enclosure fields on a natural coast
   (hedge + ridge-and-furrow), surveyed lots on a built platform (joint line
   + lot grid), so a tract never contradicts its island's register.

   The fill is deliberately almost nothing — a breath of ink over the terrain
   rather than a colour fill. These are fields on a map, not a stacked bar
   chart; the ENCLOSURE carries the reading, and the area carries the data. */
.tract-g { pointer-events: none; }
.tract { pointer-events: auto; }
.tract-fill { fill: var(--terrain); opacity: 0.28; pointer-events: none; }
.tract-hedge { stroke: var(--coast); stroke-width: 0.9; stroke-dasharray: 5 2 1.5 2; stroke-linejoin: round; opacity: 0.62; pointer-events: none; }
.tract-joint { stroke: var(--platform-wall); stroke-width: 0.9; stroke-dasharray: 6 3; stroke-linejoin: round; opacity: 0.6; pointer-events: none; }
/* furrows are texture, not information — they stay faint and only surface
   once the reader is close enough for the field to be the subject */
.tract-furrow, .tract-lotline { fill: none; stroke: var(--coast); stroke-width: 0.45; opacity: 0; pointer-events: none; transition: opacity 0.25s; }
svg.z2 .tract-furrow, svg.z3 .tract-furrow, svg.z4 .tract-furrow { opacity: 0.2; }
svg.z2 .tract-lotline, svg.z3 .tract-lotline, svg.z4 .tract-lotline { opacity: 0.16; }
.tract:hover .tract-fill { opacity: 0.5; }
.tract:hover .tract-hedge, .tract:hover .tract-joint { opacity: 0.95; }

/* the tract name sits at the pole of inaccessibility of its own field, so it
   can never wander out of the enclosure it names */
.tract-label-g { pointer-events: none; }
.tract-label { font-size: 10px; font-weight: 600; fill: var(--label-ink); text-anchor: middle; paint-order: stroke; stroke: var(--label-halo); stroke-width: 3px; letter-spacing: 0.01em; }
.tract-value { font-size: 8.5px; font-style: italic; fill: var(--value-ink); text-anchor: middle; paint-order: stroke; stroke: var(--label-halo); stroke-width: 2.5px; }
