/* Forecast American — highway signage design system, hemisphere cut
 *
 * Sibling to Forecast Eagle, Forecast Canada and weather.city, and deliberately
 * readable as one network: the same warm paper ground, the same Overpass / Overpass
 * Mono, the same guide-sign panel, exit chips, section rules and card grid. What
 * changes site to site is which colour holds the panel, and what the roadway
 * vocabulary is.
 *
 * The panel colour, and why it is blue
 * ------------------------------------
 * The network's palette is the U.S. MUTCD's, where colour is a job rather than a
 * decoration:
 *
 *     GREEN  #04663d  guide and wayfinding      — where you are, where you can go
 *     BLUE   #0a5ca8  services                  — what is available here
 *     BROWN  #6b4b2f  recreation and culture     — the land itself
 *     RED    #b0242e  regulatory and warning     — stop, and severe weather
 *
 * Forecast Eagle's panel is guide green. Forecast Canada could not also be green
 * without the two being indistinguishable, so it took maple red. This site takes
 * **service blue**, and the choice is not arbitrary: green and red are already spoken
 * for by the two siblings a reader is most likely to arrive from, and blue is the one
 * remaining MUTCD colour that carries a large panel without reading as an alarm.
 * Guide green stays exactly where it is — the section rules, the live badge, the
 * north-American accent — so nothing in the network's grammar moves. Only the panel.
 *
 * The regions are the beautiful part
 * ----------------------------------
 * Four accents sit alongside the Interstate set, one per region, and they are what
 * make a hemisphere legible at a glance:
 *
 *     --na  #04663d  guide green      North America
 *     --ca  #b5551f  copper           Central America
 *     --cb  #0d8d9c  turquoise        The Caribbean
 *     --sa  #6d4aa8  amethyst         South America
 *
 * A region's accent is carried all the way down — the front-page card, the map fill,
 * the region page's rules, the chip on a country masthead — so the colour tells you
 * where you are before the words do. Copper is far enough from the crimson red and
 * from the desaturated brown to never be confused with either at a glance, which is
 * the only constraint that mattered in picking it.
 *
 * There is no yellow anywhere on this site, including the amber Forecast Canada uses
 * for a watch. Copper does that job here instead.
 *
 * Roadway vocabulary, replacing the Interstate set:
 *   - the route shield is a Pan-American marker rather than a numbered Interstate:
 *     the highway runs the length of everything this site covers, and no single
 *     shield design is shared along it, so it carries the hemisphere's count
 *   - exit chips are labelled in the three languages of the Americas,
 *     EXITS · SALIDAS · SAÍDAS, the way Forecast Canada labels its own bilingually
 *   - distances and resolutions are km, because they are everywhere south of Texas
 */

:root {
  --paper: #e7e2d8;
  --paper2: #f3efe7;
  --card: #ffffff;
  --ink: #14181b;
  --ink2: #474339;

  /* Service blue — the guide-sign panel, and the site's primary note. */
  --sign: #0a5ca8;
  --sign-dk: #08406f;
  --sign-tx: #ffffff;
  --sign-sub: #cfe2f6;

  /* Guide green — section rules, the live badge, anything that does wayfinding. */
  --green: #04663d;
  --green-dk: #02452a;
  --green-sub: #bdebcf;

  --blue: #0a5ca8;
  --navy: #103e7e;
  --blue-sub: #cfe2f6;

  --brown: #6b4b2f;
  --brown-dk: #4a3320;
  --brown-sub: #e6d8c7;

  --red: #b0242e;
  --red-dk: #7d1620;
  --red-sub: #f7d6d9;

  /* the four regions */
  --na: #04663d;  --na-dk: #02452a;  --na-sub: #d6e6d3;
  --ca: #b5551f;  --ca-dk: #7d3812;  --ca-sub: #f3ddce;
  --cb: #0d8d9c;  --cb-dk: #075a65;  --cb-sub: #cfe9ec;
  --sa: #6d4aa8;  --sa-dk: #452c6f;  --sa-sub: #e0d7f0;

  --line: #c9c5bc;
  --line2: #e4e1d9;
  --mut: #8b877d;

  /* The sea. One value, used by the hero and by every country outline, so the
     hemisphere and the close-up are recognisably the same map. */
  --sea: #c3d8e2;
  --sea-dk: #a9c5d3;

  --font: 'Overpass', Helvetica, Arial, sans-serif;
  --mono-font: 'Overpass Mono', ui-monospace, monospace;
  --maxw: 1140px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; }
img, svg { max-width: 100%; }

.mono { font-family: var(--mono-font); font-variant-numeric: tabular-nums; }
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 18px; }
.dim { color: var(--ink2); }
.faint { color: var(--mut); }
[hidden] { display: none !important; }

/* ── thin utility bar ─────────────────────────────────── */
.util {
  background: var(--ink); color: #cfccc4; border-bottom: 3px solid var(--sign);
  position: sticky; top: 0; z-index: 100; box-shadow: 0 1px 8px rgba(0, 0, 0, .22);
}
.util .bar {
  max-width: 1560px; margin: 0 auto; padding: 0 18px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  min-height: 34px; flex-wrap: wrap;
}
.util .mono { font-size: 11px; letter-spacing: .06em; }
.util .lnks { display: flex; gap: 16px; flex-wrap: wrap; }
.util a { color: #e9e7e0; font-weight: 700; font-size: 11px; letter-spacing: .06em; }
.util a:hover { color: var(--sign-sub); text-decoration: none; }
.util a[aria-current="page"] { color: var(--sign-sub); }

/* ── region strip ─────────────────────────────────────────
   The second tier of the masthead, and the site's real navigation: four regions is a
   short enough list to sit permanently on every page, and a reader who wants the
   Caribbean wants it from wherever they happen to be. Each carries its own accent as
   a left rule, so the strip is also the colour key for the whole site. */
.regbar {
  background: var(--sign-dk); color: var(--sign-sub);
  border-bottom: 1px solid rgba(0, 0, 0, .25);
}
.regbar .bar {
  max-width: 1560px; margin: 0 auto; padding: 5px 18px;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.regbar .lbl {
  font: 700 9px var(--mono-font); letter-spacing: .14em;
  color: rgba(255, 255, 255, .55); white-space: nowrap;
}
.regbar .lnks { display: flex; gap: 5px; flex-wrap: wrap; }
.regbar a {
  font: 800 11px var(--font); letter-spacing: .02em; color: #fff;
  padding: 2px 8px 2px 7px; border-radius: 3px; white-space: nowrap;
  border-left: 3px solid transparent;
}
.regbar a.na { border-left-color: #64b78d; }
.regbar a.ca { border-left-color: #e08a4f; }
.regbar a.cb { border-left-color: #4fc4d2; }
.regbar a.sa { border-left-color: #a98ede; }
.regbar a:hover { background: rgba(255, 255, 255, .18); text-decoration: none; }
.regbar a[aria-current="page"] { background: #fff; color: var(--sign-dk); }

/* ── guide sign panel ─────────────────────────────────── */
.sign {
  background: var(--sign); border-radius: 10px; color: var(--sign-tx);
  padding: 26px 24px 24px; position: relative;
  box-shadow: inset 0 0 0 4px var(--sign), inset 0 0 0 6px rgba(255, 255, 255, .9),
              0 10px 30px rgba(0, 0, 0, .16);
}
.sign a { color: #fff; }
.signhead { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.signhead > img, .signhead > svg { width: 62px; height: 62px; flex: none; display: block; }
.word {
  font-weight: 900; font-size: clamp(28px, 5.4vw, 50px); line-height: .92;
  letter-spacing: -.02em; margin: 0;
}
.word .yl { color: var(--sign-sub); }
.tag {
  margin: 8px 0 0; font-weight: 700; font-size: clamp(13px, 2.2vw, 16px);
  color: var(--sign-sub); letter-spacing: .01em;
}

/* The route marker. There is no one Pan-American Highway shield — Peru signs it as
   PE-1, Chile as Ruta 5, Argentina as RN3 — so this is the network's own blank in the
   guide-sign idiom rather than a transcription of a real one, and it carries a count
   instead of a route number. White on the panel, the way the Trans-Canada marker is
   on Forecast Canada. */
.shield {
  background: #fff; color: var(--green); border-radius: 4px 4px 10px 10px;
  padding: 5px 11px 7px; text-align: center; line-height: 1; flex: none;
  display: inline-block; box-shadow: 0 2px 0 rgba(0, 0, 0, .18);
}
.shield .a { font-size: 8px; font-weight: 700; letter-spacing: .14em; color: var(--green); display: block; }
.shield .b { font-size: 22px; font-weight: 900; letter-spacing: .02em; display: block; color: var(--green-dk); }
.shield .c { font-size: 8px; font-weight: 700; letter-spacing: .12em; color: var(--green); display: block; }

/* Exit-style chips. Three languages, because the road runs through all three. */
.exits { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; align-items: center; }
.exits .lbl { font-size: 11px; font-weight: 700; letter-spacing: .12em; color: var(--sign-sub); }
.mm {
  background: rgba(255, 255, 255, .12); border: 1.5px solid rgba(255, 255, 255, .6);
  border-radius: 5px; padding: 6px 12px; font-family: inherit; font-weight: 700;
  font-size: 12px; letter-spacing: .03em; cursor: pointer; color: #fff;
}
.mm:hover { background: #fff; color: var(--sign); text-decoration: none; }

/* A flag riding in the masthead, on a country page. Given a white keyline so a flag
   with a white field — Honduras, Argentina, Guatemala — still reads as an object on
   the blue rather than bleeding into the panel. */
.signflag {
  width: 84px; height: 63px; flex: none; display: block; border-radius: 3px;
  object-fit: cover; box-shadow: 0 0 0 2px rgba(255, 255, 255, .95),
                                 0 3px 10px rgba(0, 0, 0, .3);
}

/* ── section rule header ──────────────────────────────── */
section { padding: 26px 0 4px; }
.rule { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.rule .ln {
  height: 3px; flex: 1; color: var(--green); opacity: .6;
  background: repeating-linear-gradient(90deg, currentColor 0 18px, transparent 18px 34px);
}
.rule h2 {
  margin: 0; color: var(--green); font-size: 15px; font-weight: 900;
  text-transform: uppercase; letter-spacing: .12em; white-space: nowrap;
}
.rule .sub { color: var(--mut); font-size: 11px; font-weight: 700; letter-spacing: .06em;
  font-family: var(--mono-font); text-transform: uppercase; }
.rule.blue h2, .rule.blue .ln { color: var(--blue); }
.rule.brown h2, .rule.brown .ln { color: var(--brown); }
.rule.red h2, .rule.red .ln { color: var(--red); }
.rule.na h2, .rule.na .ln { color: var(--na); }
.rule.ca h2, .rule.ca .ln { color: var(--ca); }
.rule.cb h2, .rule.cb .ln { color: var(--cb); }
.rule.sa h2, .rule.sa .ln { color: var(--sa); }

/* ── cards ────────────────────────────────────────────── */
.card-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.card {
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 0; overflow: hidden; display: block; color: inherit;
  box-shadow: 0 6px 22px rgba(0, 0, 0, .08); transition: transform .14s, box-shadow .14s;
}
a.card:hover { transform: translateY(-2px); box-shadow: 0 10px 26px rgba(0, 0, 0, .13); text-decoration: none; }
.card .chead {
  background: var(--green); color: #fff; padding: 9px 14px;
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .35);
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  font-weight: 900; letter-spacing: .02em;
}
.card .chead.blue { background: var(--blue); }
.card .chead.red { background: var(--red); }
.card .chead.brown { background: var(--brown); }
.card .chead.na { background: var(--na); }
.card .chead.ca { background: var(--ca); }
.card .chead.cb { background: var(--cb); }
.card .chead.sa { background: var(--sa); }
.card .chead .k { font-size: 10px; font-weight: 700; letter-spacing: .1em;
  color: rgba(255, 255, 255, .78); font-family: var(--mono-font); }
.card .cbody { padding: 14px; }
.card h3 { margin: 0 0 5px; font-size: 17px; font-weight: 900; letter-spacing: -.01em; }
.card p { margin: 0; color: var(--ink2); font-size: 13.5px; font-weight: 600; line-height: 1.5; }

.panel {
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 16px; box-shadow: 0 6px 22px rgba(0, 0, 0, .08);
}
.panel p { font-size: 14px; font-weight: 600; color: var(--ink2); }
.panel p:first-child { margin-top: 0; }
.panel p:last-child { margin-bottom: 0; }

/* ── the country grid ─────────────────────────────────────
   The heart of the site: fifty-five flags, each one a way in. The flag is the whole
   left column rather than an icon beside the name, because at this size a flag is
   recognised faster than any label — which is the entire reason for showing them.
   The region's accent runs down the left edge as a five-pixel rule, so a grid sorted
   by region reads as four blocks without needing four headings. */
.countrygrid { display: grid; gap: 11px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.cty {
  display: flex; align-items: stretch; gap: 0; background: var(--card);
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden; color: inherit;
  box-shadow: 0 5px 16px rgba(0, 0, 0, .06);
  transition: transform .13s, box-shadow .13s, border-color .13s;
  position: relative;
}
a.cty:hover { transform: translateY(-2px); box-shadow: 0 11px 24px rgba(0, 0, 0, .13);
  text-decoration: none; }
.cty .edge { width: 5px; flex: none; background: var(--line); }
.cty.na .edge { background: var(--na); } .cty.na:hover { border-color: var(--na); }
.cty.ca .edge { background: var(--ca); } .cty.ca:hover { border-color: var(--ca); }
.cty.cb .edge { background: var(--cb); } .cty.cb:hover { border-color: var(--cb); }
.cty.sa .edge { background: var(--sa); } .cty.sa:hover { border-color: var(--sa); }
.cty .fl {
  width: 52px; height: 39px; flex: none; margin: 12px 0 12px 11px; border-radius: 2px;
  object-fit: cover; background: var(--line2);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .16), 0 1px 3px rgba(0, 0, 0, .18);
}
.cty .txt { padding: 11px 12px 11px 11px; min-width: 0; flex: 1 1 auto; }
.cty .nm { display: block; font-size: 14.5px; font-weight: 900; letter-spacing: -.01em;
  line-height: 1.2; }
.cty .sub { display: block; font-family: var(--mono-font); font-size: 9.5px;
  font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--mut);
  margin-top: 3px; }
.cty .tm { display: flex; align-items: center; gap: 5px; font-size: 19px; font-weight: 900;
  letter-spacing: -.02em; margin-top: 5px; line-height: 1; min-height: 21px; }
.cty .tm .un { font-size: 11px; font-weight: 800; color: var(--mut); }

/* A country with a site of its own is not a page here, and the card says so before it
   is clicked: an outbound arrow, and the sibling's name where the capital would be. */
.cty .out { position: absolute; top: 7px; right: 9px; font-size: 11px; font-weight: 900;
  color: var(--mut); }
a.cty:hover .out { color: var(--sign); }
.cty.linked { background: linear-gradient(180deg, #fff 0%, var(--paper2) 100%); }

/* ── the weather symbols ──────────────────────────────────
   Drawn by assets/wxicons.js as inline SVG rather than set as emoji. The cloud takes
   `currentColor`, so a symbol sitting in muted text is muted and one in body text is
   not; the sun, the rain and the bolt carry their own colour, because a grey sun is
   not a sun and the whole job of the symbol is to separate "cloudy" from "raining"
   before the word underneath is read. */
.wxi { display: inline-block; vertical-align: -.16em; flex: none;
  color: var(--ink2); }
.placetile .gl .wxi { color: var(--mut); }
.cty .tm .wxi { color: var(--mut); }
.nowcond .wxi { color: var(--ink2); margin-right: 9px; vertical-align: -.22em; }

/* ── flags elsewhere ──────────────────────────────────── */
.flagchip { display: inline-flex; align-items: center; gap: 7px; }
.flagchip img { width: 22px; height: 16.5px; border-radius: 1px; object-fit: cover;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .18); }

/* ── controls ─────────────────────────────────────────── */
.btn {
  cursor: pointer; border: 1px solid var(--line); background: #fff; color: var(--ink2);
  border-radius: 3px; font-family: var(--font); font-weight: 700; font-size: 11.5px;
  letter-spacing: .02em; padding: 7px 12px; line-height: 1.3;
}
.btn:hover { border-color: var(--green); color: var(--ink); }
.btn:disabled { opacity: .5; cursor: default; }
/* The same chip as a link. `.btn` was written for <button>, which is already
   inline-block and carries no underline; an anchor is neither, so it arrives as
   underlined running text with the padding collapsed. */
a.btn { display: inline-block; text-decoration: none; }
a.btn:hover { text-decoration: none; }

/* A list inside a prose panel: no bullet, but the hanging indent a bullet would have
   given, so a wrapped second line does not run back under the term it belongs to. */
.panel ul.plain { list-style: none; margin: 10px 0 0; padding: 0; }
.panel ul.plain li { margin: 0 0 9px; padding-left: 14px; border-left: 2px solid var(--line2); }
.panel ul.plain li:last-child { margin-bottom: 0; }
select, input[type="text"], input[type="search"] {
  background: #fff; border: 1px solid var(--line); color: var(--ink);
  border-radius: 3px; padding: 6px 9px; font-family: var(--font);
  font-weight: 700; font-size: 12px;
}
select:focus, input:focus, .btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
label { font-size: 9.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--mut); }

.seg { display: flex; }
.seg button { font: 700 11px var(--mono-font); background: var(--card); color: var(--ink2);
  border: 1px solid var(--line); border-left-width: 0; padding: 5px 9px; cursor: pointer; }
.seg button:first-child { border-left-width: 1px; border-radius: 4px 0 0 4px; }
.seg button:last-child { border-radius: 0 4px 4px 0; }
.seg button:hover { color: var(--ink); }
.seg button.on { background: var(--sign); color: #fff; border-color: var(--sign-dk); }
.seg button:disabled { cursor: not-allowed; }
/* A segment the active model cannot drive at all — GFS publishes no pressure field, so
   it has no isobars to draw. Greyed as a block rather than hidden, for the same reason
   the field picker greys instead of removing: "this model does not have that" is
   information, and a control strip that changes length as you switch models is
   disorienting. */
/* A field that a model publishes over part of the globe on purpose — GFS's
   ocean-only MSLP. Set apart from the description rather than run into it, because it
   is a caveat about *this* model rather than a fact about the field. */
.xp-masknote { color: var(--sign); font-style: italic; }

.seg.unavailable { opacity: .35; }
.seg.unavailable button { cursor: not-allowed; text-decoration: line-through;
  text-decoration-thickness: 1px; }

.unitrow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.unitrow .lbl { font-family: var(--mono-font); font-size: 10.5px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--mut); }

/* ── badges ───────────────────────────────────────────── */
.badge { display: inline-block; padding: 3px 9px; border-radius: 3px;
  font-size: 10px; font-weight: 900; letter-spacing: .08em; text-transform: uppercase; }
.badge-live { background: var(--green); color: #fff; }
.badge-new { background: var(--sign); color: #fff; }
.badge-soon { background: #efece5; color: var(--mut); border: 1px solid var(--line); }

.stamp { font-family: var(--mono-font); font-size: 10.5px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase; color: var(--mut); }

/* ── breadcrumbs ──────────────────────────────────────── */
.crumbs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-family: var(--mono-font); font-size: 11px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--mut); margin: 0 0 12px; }
.crumbs a { color: var(--green); }
.crumbs .sep { color: var(--line); }

/* ══════════════════════════════════════════════════════════════════════════
   The hemisphere map
   ------------------------------------------------------------------------
   Flat colour, not relief. The whole point of this map is that a country is a
   thing you click, and a photographic basemap fights that — Forecast Canada's
   front page makes the same call for the same reason. Land is the region's
   accent at low saturation, sea is one flat value, and the accent at full
   strength is reserved for the two things that are live: a hovered country and
   its outline.
   ══════════════════════════════════════════════════════════════════════════ */
.herostage { position: relative; margin: 16px auto 0; max-width: 900px;
  background: linear-gradient(180deg, #d3e3ea 0%, var(--sea) 55%, var(--sea-dk) 100%);
  border: 1px solid var(--line); border-radius: 10px; padding: 10px;
  box-shadow: inset 0 0 0 3px rgba(255, 255, 255, .55), 0 10px 28px rgba(0, 0, 0, .10); }
.herostage svg { display: block; width: 100%; height: auto;
  opacity: 0; transition: opacity .5s ease; }
.herostage svg.in { opacity: 1; }

#heroMap .cn path { stroke: rgba(255, 255, 255, .85); stroke-width: 1.1;
  stroke-linejoin: round; transition: fill .13s ease, stroke-width .13s ease;
  cursor: pointer; }
#heroMap .cn.na path { fill: #cfe0cd; }
#heroMap .cn.ca path { fill: #f0d8c8; }
#heroMap .cn.cb path { fill: #c9e5e8; }
#heroMap .cn.sa path { fill: #ddd4ec; }
/* A country with a site of its own is drawn a shade back, the way Forecast Canada
   ghosts the United States: still land, plainly not this site's subject. */
#heroMap .cn.linked path { fill: #cfcdc4; }
#heroMap .cn a:hover path, #heroMap .cn path.on { stroke: #fff; stroke-width: 2.2; }
#heroMap .cn.na a:hover path, #heroMap .cn.na path.on { fill: var(--na); }
#heroMap .cn.ca a:hover path, #heroMap .cn.ca path.on { fill: var(--ca); }
#heroMap .cn.cb a:hover path, #heroMap .cn.cb path.on { fill: var(--cb); }
#heroMap .cn.sa a:hover path, #heroMap .cn.sa path.on { fill: var(--sa); }
#heroMap .cn.linked a:hover path { fill: var(--sign); }
#heroMap .cn a:focus path { outline: none; stroke: #fff; stroke-width: 2.6; }

/* Hovering a region — in the strip at the top or on its card — lights every country
   in it at once. It is the answer to the question a reader who has never had to place
   Curaçao actually has, which is not "where is Curaçao" but "which of these is the
   Caribbean". */
#heroMap .cn.lit path { stroke: #fff; stroke-width: 2; }
#heroMap .cn.na.lit path { fill: var(--na); }
#heroMap .cn.ca.lit path { fill: var(--ca); }
#heroMap .cn.cb.lit path { fill: var(--cb); }
#heroMap .cn.sa.lit path { fill: var(--sa); }

/* The invisible disc a speck is clicked by. It has to be in the flow to take a
   pointer, so it is filled transparent rather than hidden. */
#heroMap .hit { fill: transparent; cursor: pointer; }
#heroMap .cn a:hover .hit { fill: rgba(13, 141, 156, .22); }

/* Equator and the two tropics. Dashed, thin, and under everything — they are a
   reference, not a feature, and on this map they are also the reason half the
   forecasts on it look the way they do. */
#heroMap .lines path { fill: none; stroke: rgba(30, 70, 92, .3); stroke-width: 1;
  stroke-dasharray: 7 7; pointer-events: none; }
#heroMap .lines path.major { stroke-width: 1.8; stroke: rgba(30, 70, 92, .42); }
#heroMap .lines text { font-family: var(--mono-font); font-size: 11px; font-weight: 700;
  fill: rgba(20, 55, 74, .55); letter-spacing: .1em; pointer-events: none; }

#heroMap .lead { stroke: rgba(30, 45, 55, .5); stroke-width: .9; fill: none;
  pointer-events: none; }
#heroMap .lbl text { font-family: var(--mono-font); font-size: 15px; font-weight: 700;
  letter-spacing: .06em; fill: #1c2a33; paint-order: stroke;
  stroke: rgba(255, 255, 255, .8); stroke-width: 3.2; stroke-linejoin: round;
  pointer-events: none; }

.herohint { position: absolute; transform: translate(-50%, -190%); pointer-events: none;
  background: var(--ink); color: #fff; border-radius: 5px; padding: 5px 10px;
  font-family: var(--mono-font); font-size: 11px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
  opacity: 0; transition: opacity .12s ease; z-index: 3; }
.herohint.show { opacity: 1; }

.herolegend { display: flex; gap: 16px; flex-wrap: wrap; align-items: center;
  justify-content: center; margin-top: 11px; }
.herolegend .lg { display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono-font); font-size: 10.5px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase; color: var(--mut); }
.herolegend .sw { width: 13px; height: 13px; border-radius: 3px; border: 1px solid rgba(0,0,0,.15); }

/* ── the island strip ─────────────────────────────────────
   Twenty-eight Caribbean entries cannot be labelled on a hemisphere map and cannot be
   left off the site, so they get a strip of their own directly under it: flag, name,
   nothing else. It is the same solution an atlas uses for the Lesser Antilles, and it
   doubles as the answer to "which of these am I looking at". */
.islands { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px;
  justify-content: center; }
.isl { display: inline-flex; align-items: center; gap: 6px; background: var(--card);
  border: 1px solid var(--line); border-radius: 20px; padding: 4px 11px 4px 5px;
  font-size: 12px; font-weight: 800; color: inherit; transition: .12s; }
.isl img { width: 20px; height: 15px; border-radius: 1px; object-fit: cover;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .18); }
.isl:hover { border-color: var(--cb); color: var(--cb-dk); transform: translateY(-1px);
  text-decoration: none; }

/* ══════════════════════════════════════════════════════════════════════════
   Country pages
   ══════════════════════════════════════════════════════════════════════════ */

/* the live conditions headline.
   The place, the station and the raw report run the full width of the panel rather
   than sharing the temperature's column: the station line is the caveat that makes
   the number honest — which aerodrome, how far, how high — and it is a sentence, not
   a caption. Squeezed beside a 78 px numeral it wrapped four times and read as fine
   print, which is exactly the wrong weight for it. */
.nowplace { font-size: 20px; font-weight: 900; letter-spacing: -.01em; margin: 0 0 2px; }
.nowstation { font-family: var(--mono-font); font-size: 11.5px; font-weight: 700;
  color: var(--mut); letter-spacing: .02em; margin: 0 0 16px;
  padding-bottom: 13px; border-bottom: 1px solid var(--line2); }
.nowraw { font-size: 11.5px; color: var(--mut); word-break: break-word; margin: 0;
  background: var(--paper2); border: 1px solid var(--line2); border-radius: 5px;
  padding: 8px 10px; }
#nowstamp { margin: 15px 0 6px; }

.nowcard { display: grid; gap: 18px; grid-template-columns: minmax(210px, 300px) 1fr;
  align-items: center; }
@media (max-width: 660px) { .nowcard { grid-template-columns: 1fr; } }
.nowtemp { display: flex; align-items: baseline; gap: 10px; }
.nowtemp .deg { font-size: clamp(52px, 11vw, 78px); font-weight: 900; line-height: .95;
  letter-spacing: -.03em; color: var(--ink); }
.nowtemp .un { font-size: 17px; font-weight: 900; color: var(--mut); }
/* No reading. An em dash at 78 px is a black bar and reads as a redaction, so the
   empty state is set small and muted — it is an absence, and it should look like one. */
.nowtemp.none .deg { font-size: 40px; color: var(--mut); }
.nowtemp.none .un { display: none; }
.nowcond { font-size: 17px; font-weight: 800; margin: 9px 0 0;
  display: flex; align-items: center; }
.nowmeta { display: grid; gap: 10px 22px; grid-template-columns: repeat(auto-fit, minmax(126px, 1fr)); }
.nowmeta div { border-left: 3px solid var(--green); padding-left: 10px; }
.nowmeta .k { display: block; font-family: var(--mono-font); font-size: 10px;
  font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--mut); }
.nowmeta .v { display: block; font-size: 17px; font-weight: 800; }

/* place tiles carrying a live reading */
.placegrid { display: grid; gap: 11px;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); }
.placetile { background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 13px; display: block; color: inherit; position: relative;
  box-shadow: 0 5px 18px rgba(0, 0, 0, .07); transition: transform .14s, box-shadow .14s; }
a.placetile:hover { transform: translateY(-2px); box-shadow: 0 9px 22px rgba(0, 0, 0, .12);
  text-decoration: none; }
.placetile .nm { font-size: 15px; font-weight: 900; letter-spacing: -.01em; display: block; }
.placetile .sub { font-family: var(--mono-font); font-size: 10px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--mut); }
.placetile .row { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 9px; }
.placetile .tm { font-size: 27px; font-weight: 900; line-height: 1; letter-spacing: -.02em; }
.placetile .gl { font-size: 21px; line-height: 1; }
.placetile .cd { font-size: 12px; font-weight: 700; color: var(--ink2); margin-top: 4px;
  min-height: 1.2em; }
/* the capital, marked with a rule rather than a second colour or a glyph */
.placetile.cap { box-shadow: inset 3px 0 0 var(--sign), 0 5px 18px rgba(0, 0, 0, .07); }

/* The selected place — the one the headline is showing. It is the only state on this
   page that is not data, so it gets the panel colour and nothing else does. */
.placetile[aria-current="true"] { border-color: var(--sign);
  box-shadow: 0 0 0 2px var(--sign-sub), 0 8px 20px rgba(0, 0, 0, .12); }
.placetile[aria-current="true"].cap { box-shadow: inset 3px 0 0 var(--sign),
  0 0 0 2px var(--sign-sub), 0 8px 20px rgba(0, 0, 0, .12); }
.placetile { cursor: pointer; }
.placetile:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* A place whose station is silent, or which has none. Dimmed rather than hidden:
   that a country has gaps in its observing network is information, and in this
   hemisphere it is often the most interesting thing on the page. */
.placetile.quiet { opacity: .62; }
.placetile.quiet .tm { color: var(--mut); }
.ctymap .dot.quiet { fill: var(--mut); opacity: .55; }

/* the seven-day column set */
.fcstrip { display: grid; gap: 9px;
  grid-template-columns: repeat(auto-fill, minmax(122px, 1fr)); }
.fcday { background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 11px 12px; }
.fcday .d { font-family: var(--mono-font); font-size: 10.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--green); }
.fcday .g { font-size: 25px; line-height: 1.15; }
.fcday .t { font-size: 22px; font-weight: 900; letter-spacing: -.02em; }
.fcday .t .lo { color: var(--blue); }
.fcday .c { font-size: 12px; font-weight: 600; color: var(--ink2); line-height: 1.35; }
.fcday .p { font-family: var(--mono-font); font-size: 10.5px; font-weight: 700;
  color: var(--blue); letter-spacing: .05em; }

/* the 24-hour scroller */
.hrscroll { overflow-x: auto; padding-bottom: 4px; }
.hrrow { display: flex; gap: 8px; min-width: max-content; }
.hrcell { flex: 0 0 auto; width: 74px; text-align: center; background: var(--card);
  border: 1px solid var(--line); border-radius: 7px; padding: 9px 4px; }
.hrcell .h { font-family: var(--mono-font); font-size: 10px; font-weight: 700;
  color: var(--mut); letter-spacing: .05em; }
.hrcell .g { font-size: 17px; line-height: 1.3; }
.hrcell .t { font-size: 16px; font-weight: 900; }
.hrcell .p { font-family: var(--mono-font); font-size: 10px; font-weight: 700;
  color: var(--blue); }

/* the country outline map */
.ctymap { background: linear-gradient(180deg, #d8e6ec 0%, var(--sea) 100%);
  border: 1px solid var(--line); border-radius: 8px; padding: 8px; }
/* Chile is fourteen times taller than it is wide and Greenland is not far off. Left
   alone those render as a metre-long column, so the frame is capped and the outline
   letterboxes inside it — the shape stays honest, which a squashed viewBox would not. */
.ctymap svg { display: block; width: 100%; height: auto; max-height: 620px; }
.ctymap .ghost { fill: #cdc8bd; stroke: #b9b3a5; stroke-width: 1.2; }
.ctymap .home { fill: #f0ece2; stroke: var(--sign); stroke-width: 2.4; stroke-linejoin: round; }
.ctymap .road { fill: none; stroke: var(--brown); stroke-width: 1.1; opacity: .5;
  stroke-linecap: round; stroke-linejoin: round; }
.ctymap .dot { fill: var(--green); stroke: #fff; stroke-width: 2; cursor: pointer; }
.ctymap .dot.cap { fill: var(--red); stroke-width: 2.4; }
.ctymap text.lb { font-family: var(--font); font-weight: 800; fill: #fff;
  paint-order: stroke; stroke: rgba(12, 16, 20, .88); stroke-width: 4;
  stroke-linejoin: round; pointer-events: none; }
.ctymap text.gh { font-family: var(--mono-font); font-weight: 700; font-size: 15px;
  fill: rgba(255, 255, 255, .9); paint-order: stroke; stroke: rgba(60, 55, 45, .7);
  stroke-width: 3.4; stroke-linejoin: round; letter-spacing: .1em; }

/* the facts row under a country masthead */
.facts { display: grid; gap: 1px; background: var(--line);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.facts div { background: var(--card); padding: 11px 13px; }
.facts .k { display: block; font-family: var(--mono-font); font-size: 9.5px;
  font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--mut); }
.facts .v { display: block; font-size: 16px; font-weight: 900; margin-top: 3px; }
.facts .v small { font-size: 11px; font-weight: 700; color: var(--mut); }

/* the neighbour compass */
.compass { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.compass .nb { display: inline-flex; align-items: center; gap: 7px; background: var(--card);
  border: 1px solid var(--line); border-radius: 7px; padding: 7px 12px;
  font-size: 13.5px; font-weight: 800; color: inherit; }
.compass .nb:hover { border-color: var(--green); text-decoration: none; }
.compass .nb img { width: 20px; height: 15px; border-radius: 1px; object-fit: cover;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .18); }
.compass .nb .ar { color: var(--green); font-weight: 900; }

/* ── footer ───────────────────────────────────────────── */
.site-footer {
  border-top: 3px solid var(--sign); margin-top: 44px; padding: 20px 0 34px;
  color: var(--ink2); font-size: 12.5px; font-weight: 600; background: #ddd8ce;
}
.site-footer a { color: var(--navy); font-weight: 800; }
.site-footer .cols { display: flex; flex-wrap: wrap; gap: 22px 44px;
  justify-content: space-between; margin-bottom: 16px; }
.site-footer h4 { font-family: var(--mono-font); font-size: 10px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--mut); margin: 0 0 7px; }
.site-footer .col a { display: block; padding: 2px 0; color: var(--ink2); font-weight: 700; }
.site-footer .col a:hover { color: var(--sign); }
.site-footer .fine { max-width: 720px; line-height: 1.55; }

/* the zero-station notice, and the stale-feed notice — the same element, in copper
   rather than red, because neither is a warning and this site keeps red for warnings */
#obswarn { background: var(--ca-sub); border: 1px solid #dda87f; border-radius: 7px;
  padding: 10px 13px; font-size: 13.5px; font-weight: 700; color: var(--ca-dk);
  margin: 0 0 13px; }

.skip {
  position: absolute; left: -9999px; top: 0; background: var(--sign); color: #fff;
  padding: 9px 14px; z-index: 200; font-weight: 800;
}
.skip:focus { left: 0; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

@media (max-width: 620px) {
  #heroMap .lbl text { font-size: 21px; }
  #heroMap .lines text { font-size: 15px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   The model explorer
   ------------------------------------------------------------------------
   The one dark component on a site that is otherwise paper throughout. That
   is deliberate and it is the same call weather.city makes for its national
   outlook figures: a model raster is a photograph of a field, it is dense and
   saturated, and a warm paper ground fights it. Framing it in a dark inset
   says "this is imagery" the way a mount says it around a print.

   Everything around the frame stays on paper, so the page still reads as part
   of the site rather than as a different application.
   ══════════════════════════════════════════════════════════════════════════ */

.wrap-wide { max-width: 1560px; margin: 0 auto; padding: 0 18px; }
.sign-tight { padding: 16px 20px 15px; }
.sign-tight .signhead > img { width: 52px; height: 52px; }

.xp { margin-top: 18px; }

/* ── the control bars ─────────────────────────────────── */
.xp-bar {
  display: flex; gap: 20px; flex-wrap: wrap; align-items: flex-start;
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 15px; box-shadow: 0 6px 22px rgba(0, 0, 0, .07);
}
.xp-bar2 { margin-top: 9px; padding: 10px 15px; }
.xp-grp { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.xp-grow { flex: 1 1 320px; }
.xp-desc { margin: 2px 0 0; font-size: 12px; font-weight: 600; color: var(--mut);
  line-height: 1.4; }

/* The model picker. Three buttons, each carrying the centre that made the model and
   the resolution it runs at — because on this page "which model" and "whose model"
   are the same question, and the answer is the reason to click. */
.mdls { display: flex; gap: 7px; flex-wrap: wrap; }
.mdl {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  background: var(--card); border: 1.5px solid var(--line); border-radius: 7px;
  padding: 7px 13px 6px; cursor: pointer; font-family: var(--font); color: var(--ink2);
  transition: border-color .12s, background .12s, color .12s; line-height: 1.15;
}
.mdl .n { font-size: 15px; font-weight: 900; letter-spacing: -.01em; color: var(--ink); }
.mdl .c { font-family: var(--mono-font); font-size: 9px; font-weight: 700;
  letter-spacing: .1em; color: var(--mut); }
.mdl .r { font-family: var(--mono-font); font-size: 9px; font-weight: 700;
  letter-spacing: .06em; color: var(--mut); }
.mdl:hover:not(:disabled) { border-color: var(--sign); }
.mdl.on { background: var(--sign); border-color: var(--sign-dk); }
.mdl.on .n, .mdl.on .c, .mdl.on .r { color: #fff; }
.mdl.on .c, .mdl.on .r { color: var(--sign-sub); }
.mdl.dead { opacity: .4; cursor: not-allowed; }

/* The field picker. A field the active model does not publish is greyed rather than
   removed — see the note in explorer.js. */
.flds { display: flex; gap: 5px; flex-wrap: wrap; }
.fld {
  font: 800 11.5px var(--font); letter-spacing: .02em; background: var(--card);
  color: var(--ink2); border: 1px solid var(--line); border-radius: 5px;
  padding: 6px 11px; cursor: pointer; transition: .12s;
}
.fld:hover:not(:disabled) { border-color: var(--green); color: var(--ink); }
.fld.on { background: var(--green); border-color: var(--green-dk); color: #fff; }
.fld.off { opacity: .35; cursor: not-allowed; text-decoration: line-through;
  text-decoration-thickness: 1px; }

.rgns { display: flex; gap: 5px; flex-wrap: wrap; }
.rgn {
  font: 700 11px var(--mono-font); letter-spacing: .04em; text-transform: uppercase;
  background: var(--card); color: var(--ink2); border: 1px solid var(--line);
  border-radius: 20px; padding: 5px 12px; cursor: pointer; transition: .12s;
}
.rgn:hover { border-color: var(--cb); color: var(--cb-dk); }

/* Shelved framings, on the South America map only.
 *
 * The hemisphere page offers six boxes and a flat wrapped row is right for six. The
 * scoped page offers forty — fourteen countries, the editorial sub-regions, Brazil's
 * five and Argentina's five, and three ocean frames — and forty pills in one
 * undifferentiated row is a wall: a reader looking for the Altiplano would have to read
 * past every country to find it. So each tier gets a labelled shelf, and the labels are
 * the sector table's own groups rather than anything this stylesheet decides.
 *
 * The whole row scrolls rather than growing without limit, because it sits above the
 * map and the map is what the page is for. */
.rgns:has(.rgn-shelf) {
  display: block; max-height: 172px; overflow-y: auto; padding-right: 4px;
}
.rgn-shelf {
  display: flex; gap: 5px; flex-wrap: wrap; align-items: center;
  padding: 5px 0; border-top: 1px solid var(--line2);
}
.rgn-shelf:first-child { border-top: 0; padding-top: 0; }
.rgn-lab {
  font: 900 9px var(--mono-font); letter-spacing: .12em; text-transform: uppercase;
  color: var(--mut); min-width: 92px; flex: none;
}
/* Amethyst here, where the hemisphere page's pills hover turquoise: on a page whose
   subject is South America the framings are the region, and the region accent is what
   the rest of the site uses to say so. */
.rgn-shelf .rgn:hover { border-color: var(--sa); color: var(--sa-dk); }

#opacity { width: 150px; accent-color: var(--sign); }

/* ── the map stage ────────────────────────────────────── */
.xp-stage {
  position: relative; margin-top: 11px; border-radius: 10px; overflow: hidden;
  background: #0a0e14; border: 1px solid #223142;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .22);
}
#map { width: 100%; height: min(74vh, 820px); min-height: 420px; }

/* MapLibre's own chrome, re-dressed to the site rather than left as its default blue */
.maplibregl-ctrl-group { border-radius: 6px !important; box-shadow: 0 2px 8px rgba(0,0,0,.3) !important; }
.maplibregl-ctrl-scale { background: rgba(10,14,20,.6) !important; border-color: rgba(255,255,255,.4) !important;
  color: #dfe6ea !important; font-family: var(--mono-font) !important; font-size: 10px !important; }

.xp-hud {
  position: absolute; top: 12px; left: 12px; right: 12px; display: flex;
  justify-content: space-between; align-items: flex-start; gap: 12px;
  pointer-events: none; z-index: 2;
}
.xp-stamp {
  background: rgba(10, 14, 20, .82); border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 6px; padding: 7px 12px; color: #fff; line-height: 1.15;
}
.xp-stamp .sv { display: block; font: 900 17px var(--mono-font); letter-spacing: .02em; }
.xp-stamp .sf { display: block; font: 700 10.5px var(--mono-font); letter-spacing: .1em;
  color: #9fc4e0; margin-top: 2px; }

.xp-read {
  background: rgba(10, 14, 20, .82); border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 6px; padding: 7px 12px; text-align: right; min-width: 120px;
}
.xp-read:empty { display: none; }
.xp-read .pv { display: block; font: 900 19px var(--mono-font); color: #fff; }
.xp-read .pv.dim { color: #6f8496; }
.xp-read .pxy { display: block; font: 700 10px var(--mono-font); letter-spacing: .06em;
  color: #9fb3c4; margin-top: 2px; }

.xp-attrib {
  position: absolute; bottom: 0; right: 0; z-index: 2;
  background: rgba(10, 14, 20, .74); color: #b9c9d6; border-radius: 6px 0 0 0;
  padding: 5px 11px; font: 700 10px var(--mono-font); letter-spacing: .05em;
  text-transform: uppercase;
}
.xp-attrib a { color: #9fc4e0; }

/* The pinned point for the compare readout. A ring rather than a filled dot: whatever
   is under it is the thing being measured, and a solid marker hides it. */
.pinmark {
  width: 17px; height: 17px; border-radius: 50%;
  border: 2.5px solid #fff; box-shadow: 0 0 0 2px rgba(10, 14, 20, .75);
  background: transparent; cursor: crosshair;
}

.xp-offset {
  margin: 9px 0 0; font: 700 12px var(--font); color: var(--ca-dk);
  background: var(--ca-sub); border: 1px solid #dda87f; border-radius: 6px;
  padding: 8px 12px;
}

/* ── legend and compare ───────────────────────────────── */
.xp-legend, .xp-compare {
  margin-top: 11px; background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 12px 15px; box-shadow: 0 6px 22px rgba(0, 0, 0, .07);
}
.lg-head { display: flex; justify-content: space-between; align-items: baseline;
  gap: 14px; flex-wrap: wrap; margin-bottom: 9px; }
.lg-t { font-size: 14.5px; font-weight: 900; letter-spacing: -.01em; }
.lg-u { font-family: var(--mono-font); font-size: 11px; font-weight: 700;
  color: var(--mut); margin-left: 5px; }

.lg-bar { height: 15px; border-radius: 3px; border: 1px solid var(--line);
  overflow: hidden; }
/* A banded table draws hard steps and a continuous ramp draws a gradient, from the
   same stop array — the only thing that differs is whether the colour is allowed to
   interpolate, which is exactly the difference between the two products. */
.lg-bar.banded { display: flex; }
.lg-bar.banded span { flex: 1 1 0; }
.lg-ax { display: flex; justify-content: space-between; margin-top: 4px;
  font: 700 10px var(--mono-font); color: var(--mut); }

.cmp-rows { display: grid; gap: 9px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.cmp-empty { grid-column: 1 / -1; margin: 0; font-size: 13px; font-weight: 600;
  color: var(--mut); }
.cmp {
  border: 1px solid var(--line); border-radius: 7px; padding: 9px 12px;
  background: var(--paper2); display: flex; flex-direction: column; gap: 1px;
}
/* The model currently drawn on the map is marked, so the column you are reading is
   tied to the picture you are looking at. */
.cmp.on { border-color: var(--sign); background: #fff;
  box-shadow: inset 3px 0 0 var(--sign); }
.cmp .cm { font-family: var(--mono-font); font-size: 10px; font-weight: 700;
  letter-spacing: .11em; text-transform: uppercase; color: var(--mut); }
.cmp .cv { font-size: 21px; font-weight: 900; letter-spacing: -.02em; line-height: 1.15; }
.cmp .cs { font-family: var(--mono-font); font-size: 10px; font-weight: 700;
  color: var(--mut); }

/* ── the timeline, shared with the sibling sites ──────── */
.timeline {
  display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
  margin-top: 11px; background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 10px 14px 9px; box-shadow: 0 6px 22px rgba(0, 0, 0, .07);
}
.tl-side { display: flex; flex-direction: column; gap: 5px; }
.tl-lab { font-size: 9px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--mut); }
.tl-transport { display: flex; align-items: center; gap: 5px; }
.tl-track { flex: 1 1 340px; min-width: 240px; display: flex; flex-direction: column; }
.tl-track input[type="range"] { width: 100%; margin: 0; accent-color: var(--sign); }
.tl-ticks { position: relative; height: 23px; margin: 3px 9px 0; pointer-events: none; }
.tl-ticks .tk { position: absolute; top: 0; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; }
.tl-ticks .tk.at-start { transform: translateX(-2px); align-items: flex-start; }
.tl-ticks .tk.at-end { transform: translateX(calc(-100% + 2px)); align-items: flex-end; }
.tl-ticks .tk i { width: 1px; height: 5px; background: var(--line); display: block; }
.tl-ticks .tk span { font: 700 8.5px var(--mono-font); color: var(--mut);
  white-space: nowrap; line-height: 1; margin-top: 3px; letter-spacing: .02em; }
.tl-ticks .tk.day i { height: 9px; width: 2px; background: var(--sign); }
.tl-ticks .tk.day span { color: var(--ink2); font-weight: 800; }
.tl-buffer { height: 2px; margin: 2px 9px 0; border-radius: 2px; background: var(--line2);
  overflow: hidden; transition: opacity .4s ease .3s; }
.tl-buffer::before { content: ""; display: block; height: 100%; width: var(--pct, 0%);
  background: var(--sign); transition: width .15s linear; }
.tl-buffer.is-full { opacity: 0; }
.tl-ends { display: flex; justify-content: space-between; gap: 10px;
  font: 700 9.5px var(--mono-font); color: var(--mut); letter-spacing: .02em; }
.tl-count { font: 900 13px var(--mono-font); color: var(--ink); }

/* The explorer fades in once the catalogs are in and the first frame is placed —
   without it the page shows a working map with no field on it for a beat, which reads
   as broken rather than as loading. */
.xp-stage, .xp-legend, .xp-compare, .timeline { transition: opacity .3s ease; }
body:not(.ready) .xp-legend, body:not(.ready) .xp-compare { opacity: .45; }

@media (max-width: 700px) {
  #map { height: 62vh; }
  .xp-hud { top: 8px; left: 8px; right: 8px; }
  .xp-stamp .sv { font-size: 14px; }
}

/* The map's own failure state. MapLibre needs WebGL2 and some machines do not have it;
   the rest of the page is still worth reading, so the frame says what happened instead
   of sitting black and empty. */
.xp-nomap {
  margin: 0; padding: 40px 30px; text-align: center; color: #b9c9d6;
  font-size: 14px; font-weight: 700; line-height: 1.6; max-width: 560px;
  margin-inline: auto;
}

/* ── the explorer's second tier of controls ───────────────
   Everything above the fold is the reading instrument — model, field, run, time. The
   rest is how the map *looks*, which matters and is not what anyone opens the page
   for, so it folds away behind one summary. Open it and it is all there; leave it shut
   and the map is bigger. */
.xp-more {
  margin-top: 9px; background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: 0 6px 22px rgba(0, 0, 0, .07); overflow: hidden;
}
.xp-more > summary {
  cursor: pointer; padding: 10px 15px; font-family: var(--mono-font);
  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink2); list-style: none; display: flex; align-items: center; gap: 8px;
}
.xp-more > summary::-webkit-details-marker { display: none; }
.xp-more > summary::before { content: "▸"; color: var(--sign); font-size: 13px; }
.xp-more[open] > summary::before { content: "▾"; }
.xp-more > summary:hover { color: var(--sign); }
.xp-bar3 { border: 0; border-top: 1px solid var(--line2); border-radius: 0;
  box-shadow: none; gap: 24px; }

.xp-inline { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.xp-inline select { max-width: 168px; }

/* A checkbox and its word, as one target. Used for the boundary overlays and the
   Smooth switch — both are on/off facts about the picture rather than settings, so
   they read as a list of things that are or are not drawn. */
.switch {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  font-family: var(--font); font-size: 12px; font-weight: 700; color: var(--ink2);
  letter-spacing: 0; text-transform: none;
}
.switch input { accent-color: var(--sign); margin: 0; cursor: pointer; }
.switch:hover { color: var(--ink); }
.switch input:disabled { cursor: not-allowed; }
.switch:has(input:disabled) { opacity: .45; cursor: not-allowed; }

.overlay-box {
  display: grid; gap: 3px 14px; grid-template-columns: repeat(2, minmax(120px, 1fr));
}

/* Sub-controls of the wind mode segment, styled as subordinate to it: indented under
   a rule, smaller labels, and absent outright when the mode has nothing for them to
   change — barbs have no seeding and no animation speed. */
.wind-opts {
  display: flex; flex-direction: column; gap: 5px; margin-top: 6px;
  padding-left: 9px; border-left: 2px solid var(--line2);
}
.wind-opt { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.wind-opt label { font-size: 9px; letter-spacing: .09em; }
.wind-opt select { padding: 3px 5px; font-size: 11px; font-weight: 700; min-width: 92px; }

/* The wind overlay is a canvas of its own above the map, because a streamline
   animation composites frame to frame and must not be cleared by MapLibre's redraw.
   It takes no pointer events, so the map still drags and the probe still reads
   through it. */
#wind-overlay { position: absolute; inset: 0; z-index: 4; pointer-events: none; }

/* MapLibre's attribution, re-dressed to the site. It carries OpenStreetMap and
   whichever imagery basemap is on, and both of those are conditions of use. */
.maplibregl-ctrl-attrib {
  background: rgba(10, 14, 20, .74) !important; color: #b9c9d6 !important;
  font-family: var(--mono-font) !important; font-size: 10px !important;
}
.maplibregl-ctrl-attrib a { color: #9fc4e0 !important; }

@media (max-width: 860px) {
  .overlay-box { grid-template-columns: 1fr; }
  .xp-bar3 { gap: 16px; }
}
