/* SpreadMap.aspx, ruling 433, lane w590-spreadmaprender, EXTENDED ruling 434
   (w599-inlinemaps) for the entity-page inline maps. The wm-svg/wm-outline/
   wm-places/wm-dot classes come from _map/worldmap.svg (w578-spreadmapgeo),
   whose own header comment deliberately leaves their presentation to "the
   next lane's stylesheet"; this is that stylesheet.

   TWO SCOPES NOW, ONE RENDERER (CLAUDE.md, "one renderer per concept"). The
   rules that only the full /spread-map page uses (the tradition picker, the
   year slider, the spoken chronology) stay scoped under .smpage, the article
   wrapper only that page emits. Everything the MAP ITSELF needs, the legend,
   the SVG sizing, the status-encoded markers and the chronological list
   shape, is scoped under .mapviz instead, a class SpreadMap.aspx.vb's own map
   and list sections now also carry alongside their .smpage ancestor, so
   Entity.aspx.vb's inline spread and locator sections (ruling 434) can reuse
   the identical rules by giving their own section the same class, with no
   duplicate copy of any selector in this file.

   Body copy in rem, components in em, per the site's own accessibility
   rule, so the A-/A+ control and 150-200% browser zoom both still work.
   Nothing here restates a color that already has a --token (site.css). */

/* THE TRADITION PICKER IS A NATIVE SELECT (owner feedback, w621-mobilepolish,
   2026-08-10), replacing a box grid that "dies at scale": eight boxes read
   fine, a hundred-plus does not, and a select's own option list stays
   performant however many traditions eventually carry spread events, with no
   layout of its own to break. rem/em throughout so the A-/A+ control and
   150-200% zoom both still reach it, same as every other control on the
   site. flex-wrap so the label, select and button stack cleanly on a narrow
   phone instead of being forced into one cramped row. */
.smpage .sm-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6em;
  margin: 1em 0;
}
.smpage .sm-picker label {
  font-weight: 600;
}
.smpage .sm-picker select {
  flex: 1 1 14em;
  min-width: 10em;
  padding: .4em .6em;
  border: 1px solid var(--edge);
  border-radius: .4em;
  background: var(--panel);
  color: var(--ink);
}

/* ---- the map ------------------------------------------------------------ */

.mapviz .sm-legend {
  color: var(--muted);
}

.mapviz .sm-mapwrap {
  max-width: 100%;
  overflow-x: auto;
}
/* MAP HEIGHT IS CAPPED (owner feedback, w608-mapquality, 2026-08-10): the
   map was tall enough that the slider sat below the fold, forcing a
   scroll-slide-scroll cycle to watch the spread animate. The viewBox is a
   fixed 2:1 (720x360), and height:auto already derives the rendered height
   from the rendered width with no distortion, so capping WIDTH at twice the
   target viewport-height fraction caps height at that fraction exactly:
   116vh here means the map can never render taller than 58vh, leaving the
   slider (built by js/spreadmap.js directly beneath the map wrap in the
   markup, so it never has to be positioned there by CSS) room to sit in the
   same viewport below it. Two declarations on purpose, the same fallback
   shape site.css's own dvh rule already uses (site.css, the .sec max-height
   comment): dvh tracks the real visible viewport as a mobile URL bar
   retracts and returns, vh is the wider-supported fallback a browser
   without dvh keeps instead of dropping the whole declaration. */
.mapviz .wm-svg {
  display: block;
  width: min(100%, 60rem, 116vh);
  width: min(100%, 60rem, 116dvh);
  height: auto;
  color: var(--muted);
}
/* The base country layer is data plumbing, not decoration: the owner read
   its 155 faint dots as noise on the Christianity page (2026-08-10). Only a
   tradition's own event markers and a locator's single dot may draw. */
.mapviz .wm-places .wm-dot {
  display: none;
}

/* THE COASTLINE IS THINNER THAN THE ASSET DRAWS IT (owner QA, 2026-08-10,
   w641-spreadmapfix). _map/worldmap.svg carries stroke-width="1.8" as a
   presentation attribute on its outline group, which a stylesheet rule
   outranks, so the asset itself is untouched and every other consumer of it
   keeps the geometry it always had. Two things this buys, both from the
   owner's own report. A 1.8-wide stroke on a land polygon only three or four
   units across fills it in solid, so the smallest islands render as filled
   specks the same size as an event marker: the "small stray dot, roughly in
   the southern Indian Ocean, where no event exists" is wm-land-3, the
   Kerguelen group, real land drawn as a blob. And a thinner coast leaves the
   markers, which are what a reader came for, as the heaviest marks on the
   map instead of competing with 1,330 vertices of coastline. */
.mapviz .wm-outline {
  stroke-width: 1.3;
}

.mapviz .sm-events a {
  cursor: pointer;
}
/* THE HALO (owner QA, 2026-08-10, w641-spreadmapfix). An opaque disc in the
   page's own background colour, drawn under every marker by
   App_Code/View/SpreadMapMarkup.vb, so a marker sitting on a coastline
   clears the line behind it instead of merging into it. This is the fix for
   the owner's "no marker renders where that event belongs": the marker was
   there, correctly projected, and drawn in the coastline's own colour on top
   of the coastline. */
.mapviz .sm-events .sm-halo {
  fill: var(--ground);
  stroke: none;
  pointer-events: none;
}
/* The generous hit target: a transparent circle well past the visible
   dot's own radius, painted under it, so the clickable/hoverable/focusable
   area is never limited to the small visual mark alone. */
.mapviz .sm-events .sm-hit {
  fill: rgba(0, 0, 0, 0);
  pointer-events: all;
}
.mapviz .sm-events .sm-core {
  stroke: none;
}
.mapviz .sm-events .sm-ring {
  fill: none;
  stroke-width: 1.2;
}
.mapviz .sm-events a.sm-hidden {
  display: none;
}

/* Status drives emphasis by SIZE, FILL PATTERN and COLOR together, never by
   color alone (ruling 433): an arrival is a small, lighter, filled dot; an
   established or dominant presence is larger and more solid, dominant
   carrying its own outer ring; a suppression is a dashed, hollow ring
   rather than a plain dot, signalling an interruption that could resume; a
   revival is filled again with its own ring in the positive tone; and a
   near-disappearance is a thin, solid hollow ring, visually distinct rather
   than simply absent from the map. */
/* AN ARRIVAL IS INK, NOT THE COASTLINE'S OWN COLOUR (owner QA, 2026-08-10,
   w641-spreadmapfix). This rule read fill:var(--muted);opacity:.8, and
   .mapviz .wm-svg sets color:var(--muted) while the outline strokes with
   currentColor, so the smallest marker in the set was drawn in exactly the
   colour of the line it usually sits on, at 80% of even that. var(--ink) is
   the body-text token: the highest-contrast mark available against the page
   in both themes, and one no coastline ever uses. Size and fill still carry
   the status distinction alongside colour, so nothing here makes status
   colour-only. */
.mapviz .sm-status-arrived .sm-core {
  fill: var(--ink);
}
.mapviz .sm-status-established .sm-core {
  fill: var(--gold-soft);
}
.mapviz .sm-status-dominant .sm-core {
  fill: var(--gold);
}
.mapviz .sm-status-dominant .sm-ring {
  stroke: var(--gold);
  opacity: .6;
}
.mapviz .sm-status-revived .sm-core {
  fill: var(--shared);
}
.mapviz .sm-status-revived .sm-ring {
  stroke: var(--shared);
  stroke-dasharray: 2 2;
}
.mapviz .sm-status-suppressed .sm-core {
  fill: none;
  stroke: var(--dark-c);
  stroke-width: 1.4;
}
.mapviz .sm-status-suppressed .sm-ring {
  stroke: var(--dark-c);
  stroke-dasharray: 1.5 1.5;
  opacity: .8;
}
.mapviz .sm-status-extinct .sm-core {
  fill: none;
  stroke: var(--dark-c);
  stroke-width: 1;
  opacity: .85;
}

.mapviz .sm-events a:focus-visible .sm-ring,
.mapviz .sm-events a:focus-visible .sm-core {
  stroke: var(--gold);
  stroke-width: 2.6;
}

.mapviz .sm-maplabel {
  margin-top: .75em;
  padding: .6em .9em;
  border: 1px solid var(--edge);
  border-radius: .4em;
  background: var(--panel);
  min-height: 1.4em;
  color: var(--ink);
}
.mapviz .sm-maplabel a {
  font-weight: 600;
}

.mapviz .sm-mapnote {
  color: var(--faint);
  font-style: italic;
  margin-top: .5em;
}

/* ---- zoom, lane w2644-spreadmapzoom, owner request 2026-08-19 -------------
   js/spreadmap.js's own "zoom" section carries the full design rationale
   (no external tile service or map library, never traps a plain wheel or a
   one-finger touch at the default view, no animation so prefers-reduced-
   motion has nothing to override). This is the visual half only. */

/* position:relative so the zoom bar (an absolutely positioned child JS
   appends) places against the MAP, not the page; overflow-x:auto is
   unaffected, since zooming changes what the SVG draws inside its own box,
   never the box's own rendered size. */
.mapviz .sm-mapwrap {
  position: relative;
}
/* touch-action:none ONLY once genuinely zoomed in (js/spreadmap.js toggles
   this class in lockstep with its own scale > 1 check), so a one-finger
   touch at the default whole-world view keeps its ordinary browser
   scrolling behaviour, never trapped, and only a reader who has already
   zoomed in gets the map's own drag-to-pan instead of the page scrolling
   under their finger, which is the standard expectation once a map is
   genuinely zoomed. */
.mapviz .sm-mapwrap.sm-zoomed {
  touch-action: none;
}

/* THE BORDER LAYER IS HIDDEN AT THE DEFAULT VIEW (_map/worldmap.svg's own
   wm-borders group, country political boundaries), and reveals only once
   js/spreadmap.js has set data-zoom-tier="country" on this wrap, exactly
   the owner's "as you go deeper" instruction: nothing new competes with the
   event markers at the view every existing spread map already renders
   correctly today. */
.mapviz .wm-borders {
  opacity: 0;
}
.mapviz .sm-mapwrap[data-zoom-tier="country"] .wm-borders {
  opacity: .85;
}

/* THE ZOOM BAR, an em-sized overlay in the map's own corner, built entirely
   by script (there is no non-script way to move an SVG viewBox, so nothing
   here is ever a dead control shipped to a no-script reader). Sized and
   spaced in em against the bar's own font size, never a fixed px box around
   text, so the A-/A+ control and 150-200% browser zoom both still reach
   every control here exactly as the rest of this file's own controls do. */
.mapviz .sm-zoombar {
  position: absolute;
  top: .6em;
  right: .6em;
  display: flex;
  align-items: center;
  gap: .3em;
  padding: .3em;
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: .5em;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .18);
}
/* GENEROUS HIT AREA, owner instruction for this lane: central-field vision
   loss makes a small target the weakest interaction, so every zoom control
   is sized past the WCAG 2.5.8 24px floor at DEFAULT text size already
   (2.4em against this bar's own 1em base), and grows further with the A+
   control since nothing here is a fixed px box. */
.mapviz .sm-zoombtn {
  flex: none;
  min-width: 2.4em;
  min-height: 2.4em;
  padding: 0 .5em;
  border: 1px solid var(--edge);
  border-radius: .4em;
  background: var(--ground);
  color: var(--ink);
  font-weight: 700;
  font-size: 1.15em;
  font-family: inherit;
  line-height: 1;
  cursor: pointer;
}
.mapviz .sm-zoombtn.sm-zoomreset {
  font-size: .8em;
  font-weight: 600;
  min-width: 3.2em;
}
.mapviz .sm-zoombtn:hover:not(:disabled) {
  border-color: var(--gold);
  color: var(--gold);
}
.mapviz .sm-zoombtn:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
.mapviz .sm-zoombtn:disabled {
  opacity: .45;
  cursor: default;
}
.mapviz .sm-zoomreadout {
  min-width: 3em;
  text-align: center;
  font-weight: 600;
  color: var(--muted);
  font-size: .9em;
}

/* ---- the slider ----------------------------------------------------------- */

/* THE SLIDER'S OWN STYLING IS SCOPED TO .mapviz, NOT .smpage (w608-mapquality,
   2026-08-10). The slider used to exist only on the full /spread-map page,
   so scoping its rules to that page's own .smpage wrapper cost nothing; now
   js/spreadmap.js builds the identical control inside the entity-page inline
   section too (.entsm mapviz, never .smpage), and .mapviz is the umbrella
   class this file already uses for exactly this job on the map and list
   rules above. Rescoping here is what makes the same one control render
   correctly on both surfaces with no second copy of any of these rules,
   matching the file's own "TWO SCOPES NOW, ONE RENDERER" header comment. */
.mapviz .sm-sliderhost {
  margin-top: .5em;
}
.mapviz .sm-slider {
  border: 1px solid var(--edge);
  border-radius: .5em;
  padding: 1em;
  background: var(--panel);
}
.mapviz .sm-sliderrow {
  display: flex;
  align-items: center;
  gap: .75em;
  flex-wrap: wrap;
}
.mapviz .sm-sliderrow label {
  font-weight: 600;
}
.mapviz .sm-sliderrow input[type="range"] {
  flex: 1 1 12em;
  min-width: 8em;
}
.mapviz .sm-yearout {
  font-weight: 600;
  min-width: 6em;
  text-align: right;
}
/* THE PLAY/PAUSE TRANSPORT CONTROL, ruling 456, w813-spreaduifix. A real
   button so it never needs its own keyboard wiring; sized in em against
   the row's own font size (not the site's canonical .btn, whose padding
   is fixed px) so it grows with the A-/A+ control and 150-200% zoom
   exactly like every other control in this row. flex:none keeps it from
   competing with the range input for the row's stretch space, matching
   .sm-yearout beside it; min-height keeps it comfortably past the WCAG
   2.5.8 24px floor at default size without pinning it there. */
.mapviz .sm-playpause {
  flex: none;
  min-height: 2.2em;
  padding: .4em .9em;
  border: 1px solid var(--edge);
  border-radius: .4em;
  background: var(--panel);
  color: var(--ink);
  font-weight: 600;
  font-size: 1em;
  font-family: inherit;
  cursor: pointer;
}
.mapviz .sm-playpause:hover {
  border-color: var(--gold);
  color: var(--gold);
}
.mapviz .sm-playpause:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
.mapviz .sm-status {
  margin: .75em 0 0;
  color: var(--muted);
}
.mapviz .sm-current {
  margin-top: .75em;
}
.mapviz .sm-currenthd {
  font-size: 1em;
  margin: 0 0 .4em;
}
.mapviz .sm-currentlist {
  list-style: decimal;
  padding-left: 1.4em;
  display: flex;
  flex-direction: column;
  gap: .4em;
  margin: 0;
  /* WIDTH MISMATCH, owner report 2026-08-11, clarifying w813-spreaduifix
     below: not overflow, a design defect. The intro paragraph above every
     .dvpage surface (.lede/.entlede/.lead) is capped at var(--measure), the
     site's one text-column token; this list sat uncapped inside its .sec
     card and ran the full card width instead of matching it. Same token,
     no new number, so it stays in lockstep with every other prose column
     on the site if --measure ever changes. The slider ROW above this list
     (.sm-sliderrow, the range input) is deliberately left alone: the
     owner's report was about the links list, not the control. */
  max-width: var(--measure);
}
/* DEFENSIVE HARDENING, w813-spreaduifix, owner report 2026-08-11: "the
   event links render wider than their container." Not reproduced live at
   any width from a phone-narrow forced 640px frame through desktop, nor at
   100-200% text, on either the standalone map or this entity-page inline
   section (own testing and the conductor's independent pass agreed), so
   this is not a confirmed-then-fixed defect; it is the CLAUDE.md flex-row
   rule ("every flex row of text either wraps or gives its shrinkable
   member min-width:0") applied to the one place in this file that was
   missing it. Both lists are column-direction flex, where a bare li can
   still refuse to shrink below its own min-content width in an engine that
   computes that from an unbroken run of characters rather than the longest
   word; min-width:0 removes that floor with no visible effect where it was
   never binding, and overflow-wrap catches the one input this markup does
   not fully control, an event or place name with no break opportunity at
   all. If the owner's report reproduces again, it was not this.

   IT DID REPRODUCE, restated 2026-08-11 (w831-widthfix), and it was not
   this: the owner clarified it was never clipping or overflow, it was
   the list running wider than the paragraph above it. That fix is the
   max-width:var(--measure) on .sm-list and .sm-currentlist just above
   this comment. Both fixes stand; they address different reports. */
.mapviz .sm-list li,
.mapviz .sm-currentlist li {
  min-width: 0;
}
.mapviz .sm-list a,
.mapviz .sm-currentlist a,
.mapviz .sm-meta {
  overflow-wrap: anywhere;
}
.mapviz .sm-currentlist a {
  font-weight: 600;
}

/* SHORT-VIEWPORT FALLBACK, REMOVED (owner ruling, 2026-08-12, w940-mapscroll).
   This block used to dock the slider host with position:sticky under a
   700px viewport-height media query, the same pattern site.css's own
   .azjump bar uses. On the owner's own hardware, a short viewport is the
   common case, not the fallback: the docked bar stayed pinned under the
   header for as long as its containing section was in view, and every
   line of article and list content the reader scrolled past underneath it
   rendered BEHIND a bar that never moved, which is what he reported three
   times as "the map sitting on top of the content" and "the browser will
   not scroll past the map." The map itself was never the obstruction; the
   .azjump comparison this rule was built on does not hold, because that
   bar is a page-level navigation aid meant to stay reachable, while this
   one sits inside a single content section and pinning it hides the
   section's own following content from under itself. Owner instruction,
   verbatim: the slider is not sticky, ever, under any viewport size; it
   sits in normal document flow with the map it controls and scrolls away
   with it like any other content. No smaller sticky bar, no collapse
   button: pinning content over content is the defect itself, not its
   size. Nothing replaces this rule; .sm-sliderhost now carries only the
   base .5em margin-top rule above and is a normal flow child of .mapviz
   at every viewport height. */

/* ---- the spoken chronology -------------------------------------------------- */

.smpage .sm-spoken p {
  margin: 0 0 .6em;
}
.smpage .sm-morenote {
  color: var(--faint);
  font-style: italic;
}

/* ---- the full chronology list ----------------------------------------------- */

.mapviz .sm-listnote {
  color: var(--muted);
}
.mapviz .sm-list {
  list-style: decimal;
  padding-left: 1.4em;
  display: flex;
  flex-direction: column;
  gap: 1em;
  margin: 0;
  /* WIDTH MISMATCH, owner report 2026-08-11 (w831-widthfix), a design
     defect distinct from the w813-spreaduifix overflow hardening above:
     "the width constraint should be the same width of the paragraph above
     it." Every .dvpage intro paragraph (.lede/.entlede/.lead) is capped at
     var(--measure); this list, and its .sm-currentlist twin in the slider
     panel above, sat uncapped inside their .sec card and ran the full card
     width. Same token both places, so a change to --measure moves every
     text column, including these, together. */
  max-width: var(--measure);
}
.mapviz .sm-list li {
  padding-bottom: .75em;
  border-bottom: 1px solid var(--edge);
}
.mapviz .sm-list > li:last-child {
  border-bottom: none;
}
.mapviz .sm-list a {
  font-weight: 600;
}
.mapviz .sm-meta {
  display: block;
  color: var(--muted);
  margin-top: .2em;
}

/* ---- entity-page inline maps, ruling 434, w599-inlinemaps -------------------

   .entsm is the compact SPREAD SECTION on a religion or denomination page
   (Entity.aspx.vb BuildSpreadSection): its own map plus a short list, both
   reusing the .mapviz rules above with no restyling of their own. .entloc is
   the small LOCATOR on a sacred site or country page (BuildLocatorMap): one
   dot, no list, deliberately narrower than the tradition map so it balances
   the page rather than dominating it, per the brief's own instruction. */

.entsm .mapviz,
.entloc .mapviz {
  margin-top: .5em;
}
.entsm-more {
  margin-top: .5em;
}
.entsm-more a {
  font-weight: 600;
}

/* The locator stays visually modest: a fixed narrower ceiling than the full
   tradition map's 60rem, still fluid and contained below it. */
.entloc-map {
  max-width: 100%;
  overflow-x: auto;
}
.entloc-map .wm-svg {
  max-width: 18rem;
}

/* The locator dot is decorative (the map's own <title> already carries the
   accessible name "Location of <entity>"): a small gold-toned ring around a
   solid core, findable against the quiet country-dot layer without
   competing with it or needing a legend of its own. */
.wm-locator .wm-lochalo {
  fill: var(--ground);
  stroke: none;
}
.wm-locator .wm-locring {
  fill: none;
  stroke: var(--gold);
  stroke-width: 1.4;
  opacity: .7;
}
.wm-locator .wm-locdot {
  fill: var(--gold);
}
