/* Forecast Eagle — the explorer chrome, shared by every model viewer.
 *
 * Six pages carried this in six near-identical <style> blocks. Converged here for the
 * same reason the viewer modules were: one stylesheet cannot drift into six.
 *
 * The layout is the change worth explaining. The first cut put every control — the
 * field picker, the label-case menu, the GIF button — into one flat toolbar of some
 * thirty widgets above the map, all at the same visual weight. A reader needs three
 * things nine times out of ten: what field, what place, what time. On a phone that
 * toolbar stacked into a screen and a half before the map appeared.
 *
 * So the controls now have a hierarchy that follows the signage system the site
 * already uses:
 *
 *   .primary   the guide sign — field · place · cycle, directly above the map
 *   .deck      the map, its timeline and legend, with the .drawer beside it
 *   .drawer    the services panel — overlays, labels, boundaries, colour, output
 *              shape, export. A side panel on a wide screen; a fold-out under the
 *              legend on a narrow one, closed until asked for.
 *
 * Every element id the viewer modules look up is unchanged. This is a re-arrangement
 * of the same document, not a new one.
 */

.explorer { max-width: 1560px; margin: 0 auto; padding: 10px 18px 28px; }
/* Clear of a sideways phone's notch (the pages are `viewport-fit=cover`); zero insets,
   and so the plain 18px, everywhere else. */
.explorer {
  padding-left: max(18px, env(safe-area-inset-left));
  padding-right: max(18px, env(safe-area-inset-right));
}

/* ── title bar ─────────────────────────────────────────── */
.titlebar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 4px 0 10px; }
.titlebar h1 { margin: 0; font-size: 22px; font-weight: 900; letter-spacing: -.01em; }
.titlebar .sub { font-size: 12px; font-weight: 700; color: var(--mut); }
.title-tools { margin-left: auto; display: flex; gap: 6px; align-items: center; position: relative; }
.title-tools .btn { font-size: 10.5px; padding: 6px 10px; letter-spacing: .06em; }
#copy-link.done { border-color: var(--sign); color: var(--sign); }

#status {
  display: none; margin: 0 0 10px; padding: 11px 14px; border-radius: 4px;
  background: var(--card); border: 1px solid var(--line); color: var(--ink2);
  font-weight: 700; font-size: 13px;
}
#status.is-error { border-color: var(--shield-red); color: #8a1f2c; }

/* ── the guide sign: field · place · cycle ─────────────── */
.primary {
  display: flex; flex-wrap: wrap; gap: 10px 20px; align-items: flex-start;
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 10px 13px; margin-bottom: 10px; box-shadow: 0 6px 22px rgba(0,0,0,.08);
  border-top: 4px solid var(--sign);
}
.pgroup { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.pgroup > div { display: flex; gap: 5px; align-items: center; flex-wrap: wrap; }
.pgroup-place { flex: 3 1 560px; }
.pgroup-tools { margin-left: auto; align-self: flex-end; }
.chips { display: flex; gap: 5px; flex-wrap: wrap; }
.field-btn, .element-btn, .domain-btn, .sector-btn, .region-btn { font-size: 11px; padding: 5px 9px; }
.sector-btn:disabled { opacity: .4; }
.domain-selects { display: flex; gap: 5px; flex-wrap: wrap; align-items: center; }
.domain-selects select { font-size: 11px; padding: 5px 7px; max-width: 190px; }
#place-search { font-size: 11px; padding: 5px 8px; width: 190px; }
/* Forecast Euro's polar links. `display: contents` rather than a flex row of its own:
   they belong in the same wrapping line as the country picker and the projection, so
   they wrap with them instead of dropping to a line by themselves on a narrow screen.
   Amber ground, because they leave the page for the two views a Mercator map cannot
   draw. A page without them never matches these. */
#polar-links { display: contents; }
.polar-link { font-size: 11px; padding: 5px 9px; border-color: var(--amber); }
.polar-link:hover { background: var(--amber); color: #3a2a00; }
#cycle-select, #ramp { font-size: 11px; padding: 5px 7px; }
.cycle-nav { display: flex; gap: 4px; align-items: center; }
.cycle-nav .btn { padding: 5px 7px; font-size: 11px; }
#domain-note, #member-note, #pending { font-size: 10.5px; font-weight: 600; color: var(--mut); max-width: 46ch; }
.member-btn { min-width: 3.2em; }

/* Field picker, grouped — REFS only, where 33 fields are four different kinds of
   thing. Every other explorer publishes no `group` key, so `#fields` keeps the plain
   wrapping chip strip it has always had and none of this applies. Same shape as the
   sector menu below, deliberately: a labelled row reads the same way in both. */
#fields.fields-grouped { flex-direction: column; align-items: flex-start; gap: 6px; }
.field-group { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.field-group-label {
  font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--mut); min-width: 92px;
}

/* Sector menu, grouped the way the NWS groups its regions: one labelled row per group
   for the US sector hierarchy (#sectors). A global model's framings (#regions, the
   GlobalNav) flow into one another instead, so on a wide screen the world, the
   continents and the basins are two rows rather than four (Forecast Euro). */
#sectors { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
#regions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 18px; }
.sector-group { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.sector-group-label {
  font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--mut); min-width: 62px;
}

/* Only a narrow screen needs a way to open the drawer; on a wide one it is always
   there. */
.drawer-toggle { display: none; }

/* ── the deck: map beside the drawer ───────────────────── */
.deck { display: grid; grid-template-columns: minmax(0, 1fr) 296px; gap: 12px; align-items: start; }
.deck-main { min-width: 0; }

.drawer {
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 6px 22px rgba(0,0,0,.08); padding: 4px 13px 12px;
  position: sticky; top: 44px; max-height: calc(100vh - 56px); overflow: auto;
  max-height: calc(100dvh - 56px);   /* dvh where it exists: vh overshoots under iOS's URL bar */
  border-top: 4px solid var(--blue);
}
.drawer-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 0 6px; border-bottom: 1px solid var(--line2); margin-bottom: 4px;
}
.drawer-head span { font-size: 10.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--blue); }
.drawer-head .btn { display: none; padding: 3px 8px; font-size: 11px; }
.drawer .group { display: flex; flex-direction: column; gap: 5px; padding: 9px 0; border-bottom: 1px solid var(--line2); }
.drawer .group:last-child { border-bottom: 0; }
.drawer .group > div { display: flex; gap: 5px; align-items: center; flex-wrap: wrap; }
.drawer .group > label + div { margin-top: 1px; }
.drawer select { font-size: 11px; padding: 5px 7px; max-width: 100%; }
.drawer .btn { font-size: 11px; padding: 5px 9px; }
.overlay-box { display: flex; flex-wrap: wrap; gap: 4px 12px; }
.switch { display: inline-flex; align-items: center; gap: 5px; font-size: 11px;
          font-weight: 700; letter-spacing: 0; text-transform: none; color: var(--ink2); cursor: pointer; }
.switch input { accent-color: var(--sign); }
label { font-size: 10.5px; }

/* ── the stage ─────────────────────────────────────────── */
.stage-wrap {
  position: relative; border: 1px solid var(--line); border-radius: 8px;
  overflow: hidden; box-shadow: 0 6px 22px rgba(0,0,0,.08); transition: max-width .18s ease;
}
#stage {
  position: relative; width: 100%; background: #aebfcc;
  height: clamp(420px, calc(100vh - 250px), 900px);
  height: clamp(420px, calc(100dvh - 250px), 900px);
}
/* Until MapLibre injects its canvas the stage is empty: say so, in the same plate
   style as the overlays, instead of holding a flat blue-grey rectangle. */
#stage:empty::before {
  content: "LOADING MAP…"; position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(10, 14, 20, .84); border: 1px solid var(--figure-line);
  border-radius: 4px; padding: 7px 11px; color: #e9e7e0;
  font: 700 12px var(--mono-font); letter-spacing: .08em;
}
/* MapLibre's chrome, restyled to the signage system rather than its defaults. */
#stage .maplibregl-ctrl-group {
  border-radius: 3px; border: 1px solid var(--line); box-shadow: 0 2px 6px rgba(0,0,0,.18);
}
#stage .maplibregl-ctrl-group button + button { border-top: 1px solid var(--line2); }
#stage .maplibregl-ctrl-scale {
  background: rgba(255,255,255,.82); border-color: var(--ink2); color: var(--ink);
  font: 700 10px var(--font); letter-spacing: .04em;
}
#stage .maplibregl-ctrl-attrib { font: 600 10px var(--font); }

.stage-overlay {
  position: absolute; z-index: 5; pointer-events: none;
  background: rgba(10, 14, 20, .84); border: 1px solid var(--figure-line);
  border-radius: 4px; padding: 7px 11px; color: #e9e7e0; font-size: 12px; font-weight: 700;
}
.stage-overlay:empty { display: none; }
.ov-tl { top: 10px; left: 10px; }
.ov-tr { top: 10px; right: 10px; text-align: right; }
.ov-bl { bottom: 10px; left: 10px; }
.ov-title { font-weight: 900; font-size: 14px; letter-spacing: -.01em; }
.ov-sub { color: #b7c6d8; font-size: 11px; font-weight: 700; }
/* The max and min in view (maplabels.js extremes): a reading, in the plate that
   names the field, in the amber the probe uses for a pinned value. */
#extremes:not(:empty) { margin-top: 3px; color: #ffe2a0; font-weight: 800; }
/* Pointer readout: the value the map is drawing, then the position */
#coords { display: flex; gap: 9px; align-items: baseline; }
.probe-v { font-weight: 900; font-size: 13px; color: #fff; letter-spacing: -.01em; }
.probe-xy { color: #b7c6d8; font-size: 10.5px; font-weight: 700; }

/* Compass pad — the NWS sector pages' adjacent-sector arrows, four levels deep */
.compass {
  position: absolute; z-index: 6; top: 64px; left: 10px;
  display: grid; grid-template-columns: repeat(3, 26px); grid-template-rows: repeat(3, 26px);
  background: rgba(10,14,20,.84); border: 1px solid var(--figure-line); border-radius: 5px;
  padding: 3px;
}
.compass:empty { display: none; }
.compass-btn {
  background: none; border: 0; color: #e9e7e0; font-size: 11px; line-height: 1;
  cursor: pointer; border-radius: 3px; padding: 0;
}
.compass-btn:hover:not(:disabled) { background: rgba(255,255,255,.16); }
.compass-btn:disabled { opacity: .22; cursor: default; }
.compass-mid { grid-area: 2 / 2; display: grid; place-items: center;
               font: 800 9px var(--mono-font); color: #b7c6d8; letter-spacing: .02em; }
.dir-n { grid-area: 1 / 2; } .dir-w { grid-area: 2 / 1; }
.dir-e { grid-area: 2 / 3; } .dir-s { grid-area: 3 / 2; }

/* Place navigator: breadcrumb up the hierarchy, chips down it */
.navbar { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.navbar:empty { display: none; }
.crumbs { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.crumb {
  font: 800 12px var(--font); letter-spacing: .01em; color: var(--navy);
  background: none; border: 0; padding: 2px 3px; cursor: pointer; border-radius: 3px;
}
.crumb:hover { background: var(--line2); }
.crumb.on { color: var(--ink); cursor: default; text-decoration: underline;
            text-decoration-color: var(--sign); text-underline-offset: 3px;
            text-decoration-thickness: 2px; }
.crumb-sep { color: var(--mut); font-size: 10px; }
.drill-row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.drill-label { font-size: 10px; font-weight: 700; letter-spacing: .12em;
               text-transform: uppercase; color: var(--mut); white-space: nowrap; }
.drill-chips { display: flex; gap: 4px; flex-wrap: wrap; }
.chip {
  font: 700 10.5px var(--font); color: var(--ink2); background: var(--card);
  border: 1px solid var(--line); border-radius: 3px; padding: 3px 7px; cursor: pointer;
}
.chip:hover { border-color: var(--sign); color: var(--ink); }

/* ── legend and facts ───────────────────────────────────── */
.legend-row {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 10px; background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 12px 14px; box-shadow: 0 6px 22px rgba(0,0,0,.08);
}
#legend { flex: 1 1 340px; min-width: 260px; position: relative; }
.legend-bar { height: 15px; border-radius: 2px; border: 1px solid var(--line); }
.legend-ticks { position: relative; height: 15px; margin-top: 2px; }
.legend-ticks span {
  position: absolute; transform: translateX(-50%); font-size: 10px; font-weight: 700;
  color: var(--mut); font-family: var(--mono-font); white-space: nowrap;
}
.legend-units { font-size: 10px; color: var(--ink2); margin-top: 2px; font-weight: 800; letter-spacing: .08em; }
.legend-about { flex: 1 1 220px; }
.legend-about .k { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; font-weight: 700; color: var(--mut); }
.legend-about .d { font-size: 13px; font-weight: 600; color: var(--ink2); }
.legend-about a { color: var(--navy); font-weight: 800; font-size: 11.5px; }

/* Mileage-marker style facts strip */
.facts { display: flex; flex-wrap: wrap; margin-top: 12px; background: var(--card);
         border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
         box-shadow: 0 6px 22px rgba(0,0,0,.08); }
.fact { padding: 10px 20px; border-left: 1px solid var(--line2); flex: 1 1 150px; }
.fact:first-child { border-left: 0; }
.fact .k { font-size: 10.5px; font-weight: 700; letter-spacing: .1em; color: var(--mut); }
.fact .v { font-size: 15px; font-weight: 900; margin-top: 3px; white-space: nowrap; }

/* The about panel under every explorer */
.about p { color: var(--ink2); font-size: 13.5px; font-weight: 600; margin: 0 0 10px; }
.about p:last-child { margin-bottom: 0; }

/* The options button that floats over the map on a phone, and the scrim behind the
   sheet the drawer becomes on a narrow screen. Both are nothing on a wide one. A page
   that carries no `.drawer-scrim` gets one from mapchrome.js. */
.stage-options { display: none; }
.drawer-scrim { display: none; }

/* ── narrow screens ─────────────────────────────────────────────────────────
   Three tiers, and mapchrome.js exports the same three as BP — CSS cannot import
   them, so a change on either side must be made on both:
     1180px NARROW    no room for the side drawer — it becomes the fixed sheet here
     700px  PHONE     the phone-portrait layout below (map first, where the page has
                      the floating OPTIONS button, .stage-options)
     (pointer: coarse) and (max-width: 900px)  HANDHELD — JS-only (lean buffering) */
@media (max-width: 1180px) {
  .deck { display: block; }
  .drawer-head .btn { display: inline-block; }
  .drawer-toggle { display: inline-block; }
  /* The drawer floats over the map instead of stacking under the legend, so a
     changed option is visible the moment it is changed. mapchrome.js adds the scroll
     lock and moves the focus. Above the sticky utility bar (z-index 100), because
     sideways on a phone the sheet runs the full height and its CLOSE is at the top. */
  .drawer {
    display: none; position: fixed; z-index: 102;
    right: 12px; bottom: 12px; top: auto; width: min(420px, calc(100vw - 24px));
    max-height: 70vh; max-height: 70dvh; margin: 0; overflow: auto;
    box-shadow: 0 -10px 44px rgba(0, 0, 0, .35);
  }
  .drawer.open { display: block; }
  body.drawer-open .drawer-scrim { display: block; position: fixed; inset: 0; z-index: 101;
                                   background: rgba(10, 14, 20, .45); }
}

@media (max-width: 700px) {
  .explorer {
    padding: 8px 10px 24px;
    padding-left: max(10px, env(safe-area-inset-left));
    padding-right: max(10px, env(safe-area-inset-right));
  }
  /* Docked, full-width: the tablet sheet above, brought to the bottom edge. No taller
     than a little over half the screen: mapchrome.js parks the map's top under the
     utility bar as the sheet opens, and this is what leaves the upper half of the map
     to watch while an option changes (at 74vh a 390x844 phone kept under a fifth of
     it in view). */
  .drawer {
    right: 0; left: 0; bottom: 0; width: auto;
    max-height: 56vh; max-height: 56dvh; border-radius: 12px 12px 0 0;
    padding-bottom: max(12px, env(safe-area-inset-bottom));
  }
  body.drawer-open .drawer-scrim { background: rgba(0,0,0,.38); }
  /* The breadcrumb's drill chips: one row you can thumb through. */
  .drill-chips { flex-wrap: nowrap; overflow-x: auto; max-width: 100%;
                 scrollbar-width: thin; padding-bottom: 2px; }
  .drill-chips .chip { white-space: nowrap; }
  .titlebar h1 { font-size: 19px; }
  .titlebar .sub { display: none; }
  .primary { gap: 8px 14px; padding: 8px 10px; }
  .fe-search, #place-search { width: 100%; flex: 1 1 100%; }
  /* One row you can thumb through, not five rows you scroll past. */
  .chips, #fields, #elements, #domains, .sector-group {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; max-width: 100%;
    padding-bottom: 2px; -webkit-overflow-scrolling: touch;
  }
  .chips::-webkit-scrollbar, .sector-group::-webkit-scrollbar { display: none; }
  .chips .btn, .sector-group .btn, #domains .btn { white-space: nowrap; }
  /* Grouped, the scroller is each row rather than the whole picker — otherwise the
     headings scroll away from the chips they label. */
  #fields.fields-grouped { flex-wrap: wrap; overflow-x: visible; }
  .field-group {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; max-width: 100%;
  }
  .field-group::-webkit-scrollbar { display: none; }
  .field-group .btn { white-space: nowrap; }
  .field-group-label { min-width: 0; position: sticky; left: 0; }
  #sectors, #regions { max-width: 100%; }
  .sector-group-label { min-width: 54px; }
  /* On a phone the regional rows are the same places the breadcrumb's drill chips
     offer under the map; the national row and the two jump menus are enough here. */
  #sectors .sector-group:not(:first-child) { display: none; }
  #stage { height: min(62vh, 560px); height: min(62dvh, 560px); min-height: 320px; }
  /* Map first — on a page that carries the floating OPTIONS button (.stage-options).
     The controls a reader needs most — field, place, run — sit one swipe below the map
     rather than a screen and a half above it, and the map options are a sheet that
     slides over the map from the button in its corner. A page without the button keeps
     its source order and its MAP OPTIONS button (Forecast Eagle's phone layout). */
  .explorer:has(.stage-options) { display: flex; flex-direction: column; }
  .explorer:has(.stage-options) > .titlebar { order: 0; }
  .explorer:has(.stage-options) > #status { order: 1; }
  .explorer:has(.stage-options) > .deck { order: 2; }
  .explorer:has(.stage-options) > .primary { order: 3; margin-top: 10px; }
  .explorer:has(.stage-options) > .facts { order: 4; }
  .explorer:has(.stage-options) > .about { order: 5; }
  .stage-options { display: inline-block; position: absolute; z-index: 6; right: 10px; bottom: 62px;
                   font-size: 10.5px; padding: 6px 10px; box-shadow: 0 2px 8px rgba(0,0,0,.3); }
  .explorer:has(.stage-options) .drawer-toggle { display: none; }
  /* A 320px-tall stage cannot afford four plates. The field name is already the lit
     chip and the legend, and the place is the breadcrumb — so the top-left plate's
     title lines go, the compass takes its slot, and the scale bar (a reading, not a
     control) goes too. What stays: valid time, the probe readout, the compass,
     OPTIONS — and, on an accumulating field only, the rest of the top-left plate,
     because it holds the accumulation window (a fact the number cannot be read
     without) and the PER STEP / SINCE RUN START switch (a control). The compass
     then steps down below it. A page with no accumulation note loses the plate. */
  .ov-tl > .ov-title, .ov-tl > .ov-sub { display: none; }
  .ov-tl:not(:has(#accum-note:not(:empty), .accum-toggle:not([hidden]))) { display: none; }
  .compass { top: 10px; }
  .stage-wrap:has(#accum-note:not(:empty), .accum-toggle:not([hidden])) .compass { top: 92px; }
  #stage .maplibregl-ctrl-scale { display: none; }
  .compare-label { max-width: 45%; bottom: 36px; }
  .ov-title { font-size: 12.5px; }
  .ov-sub { font-size: 10px; }
  .timeline { padding: 8px 10px; gap: 10px; }
  .tl-hint { display: none; }
  .fact { flex: 1 1 45%; padding: 8px 12px; }
}

/* A phone held sideways: barely 400px tall, and the portrait rule of 60vh capped
   at 320px minimum would push the timeline below the fold. Give the map the
   height that remains after the timeline and one control row, and no more. */
@media (pointer: coarse) and (max-height: 520px) {
  #stage { height: calc(100vh - 140px); height: calc(100dvh - 140px); min-height: 240px; }
  /* Sideways there is width to spare and no height at all: the sheet docks right,
     full height, and the map keeps the left of the screen. */
  .drawer {
    top: 0; bottom: 0; right: 0; left: auto; width: min(360px, 60vw);
    max-height: none; border-radius: 12px 0 0 12px;
    padding-bottom: max(12px, env(safe-area-inset-bottom));
    padding-right: max(13px, env(safe-area-inset-right));
  }
}

/* ── the point view: a city's series through the run (mappoint.js) ── */
.point-panel {
  margin-top: 10px; background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 6px 22px rgba(0,0,0,.08); padding: 10px 14px 8px; border-left: 4px solid var(--blue);
}
.pp-head { display: flex; align-items: flex-end; gap: 14px 22px; flex-wrap: wrap; margin-bottom: 4px; }
.pp-title { display: flex; flex-direction: column; gap: 2px; min-width: 200px; }
.pp-city { font-size: 17px; font-weight: 900; letter-spacing: -.01em; }
.pp-what { font-size: 11px; font-weight: 700; color: var(--mut); letter-spacing: .04em; text-transform: uppercase; }
.pp-now { display: flex; flex-direction: column; align-items: flex-start; }
.pp-v { font: 900 26px var(--mono-font); color: var(--blue); line-height: 1; letter-spacing: -.02em; }
.pp-v small { font-size: 12px; margin-left: 3px; color: var(--ink2); font-weight: 800; }
.pp-t { font: 700 10.5px var(--mono-font); color: var(--mut); margin-top: 3px; }
.pp-tools { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pp-tools .btn { font-size: 10.5px; padding: 4px 8px; }
.pp-prog { font: 700 10.5px var(--mono-font); color: var(--sign); }
.pp-ext { font-size: 11px; font-weight: 600; color: var(--ink2); }
.pp-ext b { color: var(--ink); font-family: var(--mono-font); }
.pp-chart { display: block; width: 100%; height: 190px; cursor: crosshair; }
.pp-grid { stroke: var(--line2); stroke-width: 1; }
.pp-ylab { font: 700 11px var(--mono-font); fill: var(--mut); }
.pp-tick { stroke: var(--line); stroke-width: 1; }
.pp-tick.day { stroke: var(--sign); stroke-width: 2; }
.pp-xlab { font: 700 10.5px var(--mono-font); fill: var(--mut); }
.pp-xlab.day { fill: var(--ink2); font-weight: 800; }
.pp-area { fill: var(--sign); opacity: .08; }
.pp-line { fill: none; stroke: var(--sign); stroke-width: 2.2; stroke-linejoin: round; stroke-linecap: round; }
.pp-dot { fill: var(--card); stroke: var(--sign); stroke-width: 1.5; }
.pp-cur { stroke: var(--blue); stroke-width: 1.5; stroke-dasharray: 3 3; }
.pp-curdot { fill: var(--blue); stroke: #fff; stroke-width: 2; }
.pp-foot { font-size: 10.5px; font-weight: 600; color: var(--mut); margin-top: 2px; }
@media (max-width: 700px) { .pp-chart { height: 150px; } .pp-ext { display: none; } }

/* ── compare & verify (mapcompare.js) ─────────────────────── */
.compare-overlay { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.compare-handle {
  position: absolute; top: 50%; z-index: 7; transform: translate(-50%, -50%);
  background: #fff; color: var(--ink); border: 1px solid var(--line); border-radius: 14px;
  padding: 5px 8px; font: 900 11px var(--font); cursor: ew-resize; user-select: none;
  box-shadow: 0 2px 8px rgba(0,0,0,.3); touch-action: none;
}
.compare-label {
  position: absolute; z-index: 6; bottom: 44px; right: 10px; pointer-events: none;
  background: rgba(10,14,20,.84); border: 1px solid var(--figure-line); border-radius: 4px;
  color: #e9e7e0; padding: 6px 10px; font-size: 11px; font-weight: 700; max-width: 60%;
}
.cmp-scale { display: flex; align-items: center; gap: 6px; margin-top: 5px; font: 700 10px var(--mono-font); color: #b7c6d8; }
.cmp-scale i { flex: 1; height: 8px; border-radius: 2px; min-width: 90px;
  background: linear-gradient(90deg, rgb(55,105,255), #fff 50%, rgb(255,85,45)); }
#compare-mode button { font-size: 10px; }

.probe-ab { color: #ffd479; font: 800 11px var(--mono-font); letter-spacing: 0; }
.probe-sp { color: #9fe0ff; font: 800 12px var(--mono-font); }
#compare-span { font-size: 10.5px; padding: 3px 5px; }

/* The meteogram rows (Forecast Euro's point view; drawn by any page that hands
   mappoint.js a field list) under the headline chart, and the hover readout above it. */
.pp-row { display: grid; grid-template-columns: 118px minmax(0, 1fr); gap: 8px; align-items: center;
          border-top: 1px solid var(--line2); padding-top: 4px; margin-top: 4px; }
.pp-rowlab { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pp-rowlab b { font-size: 11px; font-weight: 800; color: var(--ink2); line-height: 1.15; }
.pp-rowlab span { font-size: 10px; font-weight: 700; color: var(--mut); letter-spacing: .04em; }
.pp-rowlab em { font: 900 14px var(--mono-font); color: var(--blue); font-style: normal; }
.pp-chart.pp-small { height: 64px; }
.pp-bar { fill: var(--sign); opacity: .75; }
.pp-run { fill: none; stroke-width: 1.6; stroke-dasharray: 5 3; opacity: .85; }
.pp-hover { stroke: var(--ink2); stroke-width: 1; stroke-dasharray: 2 2; pointer-events: none; }
.pp-tip { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 11px; font-weight: 600;
          color: var(--ink2); padding: 4px 0 2px; }
.pp-tip b { font-family: var(--mono-font); color: var(--ink); }
.pp-runs { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 10.5px; font-weight: 700;
           color: var(--ink2); margin: 2px 0 4px; }
.pp-runs i { display: inline-block; width: 14px; height: 3px; margin-right: 5px; vertical-align: middle;
             border-radius: 2px; }
.pp-tools .btn.on { background: var(--sign); color: #fff; border-color: var(--sign-dk); }
@media (max-width: 700px) { .pp-row { grid-template-columns: 84px minmax(0, 1fr); } .pp-tip { display: none; } }
/* The per-step / run-total switch sits in the stage's title card, which does not take
   the pointer; the switch must. */
.accum-toggle { pointer-events: auto; margin-top: 5px; }
.accum-toggle button { font-size: 9.5px; padding: 3px 6px; }

/* The ensemble plume in the point view, and the members' calendar under it. */
.pp-member { fill: none; stroke: #6b7480; stroke-width: .7; opacity: .35; }
.pp-band { fill: var(--sign); opacity: .16; stroke: none; }
.pp-median { fill: none; stroke: var(--ink); stroke-width: 1.4; stroke-dasharray: 4 3; }
.pp-stats { font-size: 11px; font-weight: 600; color: var(--ink2); margin: 2px 0 4px; line-height: 1.6; }
.pp-stats b { font-family: var(--mono-font); color: var(--ink); }
.pp-cal { display: block; width: 100%; max-width: 560px; height: auto; margin: 8px 0 4px; }
.pp-cal-title { font: 800 9px var(--font); fill: var(--ink2); }
.pp-cal-day { font: 700 6.5px var(--mono-font); fill: var(--mut); }
.pp-cal-lab { font: 700 6px var(--mono-font); fill: var(--mut); }
.pp-cal-foot { font: 600 6px var(--font); fill: var(--mut); }

/* The grouped field picker: quantities on one row, the statistics of the chosen one
   on the next, set apart as the second half of one choice. */
#fields .stat-row { margin-top: 2px; padding: 4px 6px; border-left: 3px solid var(--sign); background: var(--line2); border-radius: 3px; }
#fields .group-btn.on { background: var(--navy); border-color: var(--navy); color: #fff; }
#fields .stat-btn { font-size: 10.5px; padding: 4px 8px; }
#spaghetti-levels button { font-size: 10px; border-width: 2px; }

/* ── the night theme: the few colours here that are not tokens ──────────── */
html[data-theme="dark"] #stage { background: #10151b; }
html[data-theme="dark"] #status.is-error { color: #ff9a8a; }
html[data-theme="dark"] .compare-handle { background: var(--card); color: var(--ink); }
html[data-theme="dark"] .pp-curdot { stroke: var(--card); }
html[data-theme="dark"] .fe-kbd { background: var(--paper); }

/* ── the keyboard card (mapchrome.js wireHelp) ─────────────────────────── */
.fe-help {
  border: 0; border-top: 4px solid var(--sign); border-radius: 8px; padding: 0;
  width: min(540px, 94vw); background: var(--card); color: var(--ink);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .45);
}
.fe-help::backdrop { background: rgba(10, 14, 20, .55); }
.fe-help-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 10px 14px; border-bottom: 1px solid var(--line2);
}
.fe-help-head span { font-size: 10.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--sign); }
.fe-help-head .btn { padding: 3px 8px; font-size: 11px; }
.fe-help-body { padding: 10px 14px 14px; max-height: 72vh; overflow: auto; }
.fe-help-row {
  display: grid; grid-template-columns: 138px minmax(0, 1fr); gap: 10px; align-items: baseline;
  padding: 4px 0; font-size: 12.5px; font-weight: 600; color: var(--ink2);
}
.fe-kbd {
  font-family: var(--mono-font); font-size: 11px; font-weight: 700; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line); border-bottom-width: 2px;
  border-radius: 3px; padding: 2px 6px; justify-self: start; white-space: nowrap;
}
.fe-help-note { font-size: 12px; font-weight: 600; color: var(--mut); margin: 10px 0 0; line-height: 1.5; }
.fe-help-note a { color: var(--navy); font-weight: 800; }
@media (max-width: 700px) { .fe-help-row { grid-template-columns: 96px minmax(0, 1fr); } }

/* ── saved and recent views (mapchrome.js wireViews) ───────────────────── */
.fe-views {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 60;
  width: min(400px, 92vw); text-align: left;
  background: var(--card); color: var(--ink); border: 1px solid var(--line);
  border-top: 4px solid var(--blue); border-radius: 8px; padding: 10px 12px 12px;
  box-shadow: 0 16px 44px rgba(0, 0, 0, .3);
}
.fe-views-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding-bottom: 6px; border-bottom: 1px solid var(--line2); margin-bottom: 8px;
}
.fe-views-head span { font-size: 10.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--blue); }
.fe-views-head .btn { padding: 3px 8px; font-size: 11px; }
.fe-views-save { display: flex; gap: 5px; align-items: center; }
.fe-views-save input { flex: 1 1 auto; min-width: 0; font-size: 12px; padding: 6px 8px; }
.fe-views-save .btn { font-size: 10.5px; padding: 6px 10px; white-space: nowrap; }
.fe-views-k { font-size: 10px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--mut); margin: 10px 0 3px; }
.fe-views-empty { font-size: 11px; font-weight: 600; color: var(--mut); line-height: 1.5; }
.fe-view-row { display: flex; align-items: center; gap: 4px; }
.fe-view-row a {
  flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px;
  padding: 5px 7px; border-radius: 3px; border-left: 3px solid transparent;
}
.fe-view-row a:hover { background: var(--line2); text-decoration: none; }
.fe-view-row.is-here a { border-left-color: var(--sign); }
.fe-view-row b { font-size: 12px; font-weight: 800; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fe-view-row span { font: 700 10px var(--mono-font); color: var(--mut); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fe-view-x {
  flex: none; background: none; border: 1px solid transparent; border-radius: 3px; cursor: pointer;
  color: var(--mut); font: 800 11px var(--font); padding: 4px 6px;
}
.fe-view-x:hover { color: var(--shield-red); border-color: var(--line); }

/* ── the loop's end, and NOW (maptimeline.js) ─────────────────────────── */
.tl-loop button { font-size: 10px; letter-spacing: .02em; }
.tl-dwell, .tl-now {
  font: 700 10px var(--mono-font); letter-spacing: .06em; padding: 4px 8px;
  white-space: nowrap;
}
.tl-dwell { align-self: flex-start; }
.tl-dwell.on, .tl-now.on { background: var(--sign); color: #fff; border-color: var(--sign); }
.tl-now { margin-left: 2px; }

/* ── fullscreen (maptools.js): the deck fills the screen, map first ─────── */
.deck-main:fullscreen, .deck-main:-webkit-full-screen {
  background: var(--paper); padding: 10px 14px; overflow: auto;
}
.deck-main:fullscreen #stage { height: calc(100vh - 196px); height: calc(100dvh - 196px); }
.deck-main:fullscreen .navbar, .deck-main:fullscreen .tl-hint { display: none; }
.deck-main:fullscreen .legend-row { padding: 8px 12px; margin-top: 8px; }

/* The phone's OPTIONS button over the map (see the 700px block: on a page that
   carries it the map comes first). It is a .btn; this is only its place. */

/* ── place search (mapsearch.js) ────────────────────────────
   The box is the page's own <input type="search">; the module wraps it and hangs the
   result list under it. Tokens only, so the dark theme needs nothing of its own. */
.fe-search { position: relative; display: inline-block; min-width: 0; max-width: 100%; }
.fe-search input[type="search"] { width: 100%; min-width: 150px; }
.fe-search-list {
  position: absolute; left: 0; top: calc(100% + 3px); z-index: 50;
  min-width: 100%; width: max-content; max-width: min(380px, 90vw);
  margin: 0; padding: 4px 0; list-style: none;
  background: var(--card); border: 1px solid var(--line); border-radius: 4px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .18);
  max-height: 320px; overflow: auto;
}
.fe-search-list[hidden] { display: none; }
.fe-search-item {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 6px 10px; cursor: pointer; white-space: nowrap;
  font: 700 12px var(--font); color: var(--ink);
}
.fe-search-item.is-active, .fe-search-item:hover { background: var(--blue-sub); color: var(--navy); }
.fe-search-sub {
  font: 700 10px var(--mono-font); color: var(--mut); letter-spacing: .04em;
  text-transform: uppercase; flex: none;
}
.fe-search-item.is-active .fe-search-sub { color: var(--navy); }
.fe-search-empty { padding: 6px 10px; font: 600 11.5px var(--font); color: var(--mut); }
@media (pointer: coarse) {
  .fe-search-item { min-height: 36px; padding: 9px 12px; font-size: 13px; }
  .fe-search-empty { min-height: 36px; padding: 9px 12px; }
}

/* ── the tools over the map (maptools.js): fullscreen · locate · measure · help ──
   A plate of square buttons in the top-right corner under the zoom control, in the
   same dark plate style as the valid-time and probe overlays, so the map's furniture
   reads as one set. Positioned by the stage, which is `position: relative`. */
.stage-tools {
  position: absolute; z-index: 6; right: 10px; top: 96px;
  display: flex; flex-direction: column; gap: 1px;
  background: rgba(10, 14, 20, .84); border: 1px solid var(--figure-line);
  border-radius: 4px; padding: 3px;
}
.stage-tool {
  width: 30px; height: 30px; display: grid; place-items: center; padding: 0;
  background: none; border: 0; border-radius: 3px; cursor: pointer;
  color: #e9e7e0; font: 900 14px var(--font); line-height: 1;
}
.stage-tool:hover { background: rgba(255, 255, 255, .16); }
.stage-tool.on, .stage-tool[aria-pressed="true"] { background: var(--sign); color: #fff; }
.stage-tool.busy { opacity: .55; cursor: progress; }
.stage-tool:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }

/* The measurement readout: total first, the leg and bearing under it. Bottom-right,
   above the attribution and the scale bar. Hidden until there is something to say. */
.stage-measure, .stage-note {
  position: absolute; z-index: 6; right: 10px; bottom: 34px; pointer-events: none;
  background: rgba(10, 14, 20, .84); border: 1px solid var(--figure-line);
  border-radius: 4px; padding: 6px 10px; color: #e9e7e0;
  font: 700 11px var(--mono-font); letter-spacing: .02em; max-width: 60%;
}
.stage-measure:empty, .stage-note:empty { display: none; }
.stage-measure b { display: block; font-size: 13px; color: #ffd479; font-weight: 900; }
.stage-measure .s { display: block; color: #b7c6d8; font-size: 10px; margin-top: 2px; }
/* The note is a passing word next to the tool that raised it. */
.stage-note { bottom: auto; top: 96px; right: 50px; font-family: var(--font); color: #ffd479; }
/* The map is read, not dragged, while a measurement is live. */
.stage-wrap.is-measuring .maplibregl-canvas-container,
.stage-wrap.is-measuring .maplibregl-canvas { cursor: crosshair !important; }

@media (max-width: 700px) {
  /* Clear of the floating OPTIONS button (bottom-right) and the compare label. */
  .stage-measure { bottom: 104px; max-width: 70%; }
}
@media (pointer: coarse) {
  .stage-tool { width: 36px; height: 36px; font-size: 16px; }
}

/* ── your own overlays (mapuser.js) ────────────────────────────────────────────
   The Boundaries group's last box: an ADD button, then one row per file the reader
   has dropped on the map. The box sits where `.drawer .group > div` lays a flex row,
   so it restates its own column layout at the same specificity, later in the file. */
.drawer .group > .user-ov-box, .user-ov-box {
  display: flex; flex-direction: column; align-items: stretch; gap: 5px; width: 100%; min-width: 0;
}
.user-ov-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.user-ov-add { font-size: 10.5px; letter-spacing: .04em; }
.user-ov-hint { font-size: 10px; font-weight: 600; color: var(--mut); }
.user-ov-list { display: flex; flex-direction: column; gap: 3px; }
.user-ov {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  padding: 4px 6px; border: 1px solid var(--line2); border-radius: 3px; background: var(--paper);
}
.user-ov-swatch {
  flex: none; width: 14px; height: 14px; border-radius: 3px; padding: 0; cursor: pointer;
  border: 1px solid rgba(0, 0, 0, .35); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .5);
}
.user-ov-name {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 11px; font-weight: 800; color: var(--ink);
}
.user-ov-n { flex: none; font: 700 9.5px var(--mono-font); color: var(--mut); white-space: nowrap; }
.user-ov .switch { flex: none; font-size: 10.5px; }
.user-ov-btn { flex: none; font-size: 9.5px; padding: 3px 6px; letter-spacing: .04em; }
.user-ov-note { font-size: 10.5px; font-weight: 700; color: var(--shield-red); }
.user-ov-note[hidden] { display: none; }

/* A file held over the map: the stage says it will take it. The outline is drawn
   inside the frame with a shadow so it needs no room of its own, and the message is a
   plate like the readouts. */
.stage-wrap.is-dropping { box-shadow: inset 0 0 0 3px var(--blue), 0 6px 22px rgba(0, 0, 0, .08); }
.stage-wrap.is-dropping::after {
  content: "DROP TO ADD OVERLAY"; position: absolute; left: 50%; top: 50%; z-index: 8;
  transform: translate(-50%, -50%); pointer-events: none;
  background: rgba(10, 14, 20, .84); border: 1px solid var(--figure-line); border-radius: 4px;
  padding: 9px 14px; color: #e9e7e0; font: 800 12px var(--mono-font); letter-spacing: .1em;
}

@media (pointer: coarse) {
  .user-ov-swatch { width: 22px; height: 22px; }
  .user-ov-btn { min-height: 36px; padding: 8px 10px; }
  .user-ov .switch { min-height: 36px; }
}

/* ── 4K desktops ────────────────────────────────────────────
   The fixed 1560px working column leaves most of a 3840px screen as paper.
   Wide screens open the column up; the drawer keeps its width, so all the
   new room goes to the map. forecasteagle.css widens .wrap-wide to match. */
@media (min-width: 2400px) {
  .explorer { max-width: 2340px; }
}

/* ── coarse pointers: the same controls, at thumb size ──────────────────────
   Sized here rather than by viewport: an iPad wide enough for the side drawer
   still taps. 36px boxes on the named controls only — desktop density is a
   feature, and none of this runs under a mouse. Each site's own stylesheet does
   the same for its .btn and .seg families. Last in the file on purpose:
   the component rules above (the statistic chips, the accumulation switch) set
   their own tighter padding, and at equal specificity the later rule wins. */
@media (pointer: coarse) {
  .chip, .crumb { padding: 8px 11px; font-size: 11.5px; min-height: 32px; }
  .field-btn, .element-btn, .domain-btn, .sector-btn, .region-btn, .polar-link {
    padding: 9px 12px; min-height: 36px;
  }
  /* Repeated selectors from the base rules, or their tighter padding wins here. */
  .cycle-nav .btn { padding: 8px 10px; min-width: 36px; min-height: 36px; }
  #fields .stat-btn { padding: 8px 11px; min-height: 34px; }
  .accum-toggle button { padding: 8px 9px; font-size: 10.5px; }
  .compass { grid-template-columns: repeat(3, 34px); grid-template-rows: repeat(3, 34px); }
  .compass-btn { font-size: 13px; }
  .drawer .btn, .drawer select, .domain-selects select,
  #cycle-select, #ramp { min-height: 36px; }
  .switch { min-height: 32px; }
  .switch input { width: 18px; height: 18px; }
  .tl-track input[type="range"] { height: 32px; }
  /* A horizontal drag that starts on the timeline card is a scrub, never a page scroll. */
  .timeline { touch-action: pan-y; }
}

/* ── the region frame (maplock.js) ─────────────────────────────────────────
   A sector locked into a fixed rectangle. On a "fit window" stage the frame is
   letterboxed: the veil dims the stage around it in the page's own paper, the frame
   edge is a hairline of ink, and the plates dock to the frame's corners rather than
   the stage's (the lock writes --fx/--fy/--fr/--fb, the frame's insets). With an
   output shape chosen the stage is the frame and none of this shows. */
.fe-veil { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 5; pointer-events: none; }
.fe-veil path { fill: var(--paper); fill-opacity: .9; }
.fe-veil rect { stroke: var(--ink); stroke-width: 1.5; }
.stage-wrap.is-letterboxed .ov-tl { top: calc(var(--fy, 0px) + 10px); left: calc(var(--fx, 0px) + 10px); }
.stage-wrap.is-letterboxed .ov-tr { top: calc(var(--fy, 0px) + 10px); right: calc(var(--fr, 0px) + 10px); }
.stage-wrap.is-letterboxed .ov-bl { bottom: calc(var(--fb, 0px) + 10px); left: calc(var(--fx, 0px) + 10px); }
.stage-wrap.is-letterboxed .compass { top: calc(var(--fy, 0px) + 64px); left: calc(var(--fx, 0px) + 10px); }
.stage-wrap.is-letterboxed .stage-tools { top: calc(var(--fy, 0px) + 96px); right: calc(var(--fr, 0px) + 10px); }
.stage-wrap.is-letterboxed .stage-measure { bottom: calc(var(--fb, 0px) + 34px); right: calc(var(--fr, 0px) + 10px); }
.stage-wrap.is-letterboxed #stage .maplibregl-ctrl-top-right { top: var(--fy, 0px); right: var(--fr, 0px); }
.stage-wrap.is-letterboxed #stage .maplibregl-ctrl-bottom-right { bottom: var(--fb, 0px); right: var(--fr, 0px); }
.stage-wrap.is-letterboxed #stage .maplibregl-ctrl-bottom-left { bottom: var(--fb, 0px); left: var(--fx, 0px); }
.stage-wrap.is-letterboxed .stage-options { bottom: calc(var(--fb, 0px) + 62px); right: calc(var(--fr, 0px) + 10px); }
/* The plate names the place; locked, it says so in the sign's green. */
.stage-wrap.is-locked #sector-name::before { content: "LOCKED · "; color: #9fd3bb; letter-spacing: .06em; font-size: 10px; }

/* The pill over a free map: SNAP TO the region the view overlaps most, BACK TO the one
   that was locked. Motorist-services blue — the colour of a way back on a guide sign. */
.fe-lockpill {
  position: absolute; z-index: 7; left: 50%; top: 10px; transform: translateX(-50%);
  display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; max-width: 92%;
}
.fe-lockpill[hidden] { display: none; }
.fe-lockpill button {
  height: 30px; padding: 0 12px; border-radius: 15px; cursor: pointer; white-space: nowrap;
  border: 1px solid var(--blue); background: var(--card); color: var(--blue);
  font: 800 10.5px var(--font); letter-spacing: .06em;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
}
.fe-lockpill button.primary { background: var(--blue); color: #fff; }
.fe-lockpill button:hover { filter: brightness(1.08); }
@media (pointer: coarse) { .fe-lockpill button { height: 36px; padding: 0 14px; font-size: 11.5px; } }
/* A phone's top-right valid-time plate is where the pill would land; give it the room. */
@media (max-width: 700px) { .fe-lockpill { top: auto; bottom: 10px; } }

/* The region-frame group at the top of the options panel: the locator and the switch. */
.drawer .group-frame { padding-top: 8px; }
.locator {
  display: block; width: 100%; aspect-ratio: 552 / 340; height: auto; cursor: pointer;
  border: 1px solid var(--line); border-radius: 5px; background: var(--loc-sea);
  --loc-sea: #d6e4ec; --loc-land: #f4f2eb; --loc-line: #9aa3ad;
}
html[data-theme="dark"] .locator { --loc-sea: #0f1a24; --loc-land: #1d242d; --loc-line: #4a5663; }
#lock-mode button { font-size: 10px; letter-spacing: .04em; }
.drawer .group-frame > div { margin-top: 6px; }

/* ── the hour strip (maptimeline.js) ─────────────────────────────────────
   One cell per frame between the scrubber and the tick axis: loaded frames green,
   held-back frames hatched, the frame on screen lit, the first frame of each UTC day
   opened with a rule. The thin buffer bar stands down where the strip exists. */
.tl-buffer.has-strip { display: none; }
.tl-strip {
  display: grid; height: 12px; margin: 3px 9px 0; border-radius: 3px; overflow: hidden;
  border: 1px solid var(--line); background: var(--line2); cursor: pointer; touch-action: none;
  user-select: none; -webkit-user-select: none;
}
.tl-strip i { display: block; min-width: 0; background: var(--line2); border-left: 1px solid var(--card); }
.tl-strip i:first-child { border-left: 0; }
.tl-strip.is-dense i { border-left: 0; }
.tl-strip i.ld { background: var(--sign-sub); }
.tl-strip i.held { background-image: repeating-linear-gradient(135deg, transparent 0 2px, var(--line) 2px 4px); }
.tl-strip i.day { border-left: 2px solid var(--ink2); }
.tl-strip i.past { background-image: repeating-linear-gradient(135deg, transparent 0 3px, rgba(0, 0, 0, .09) 3px 5px); }
.tl-strip i.on { background: var(--sign); background-image: none; }
html[data-theme="dark"] .tl-strip i.ld { background: #1f5c3d; }
@media (pointer: coarse) { .tl-strip { height: 18px; } }

/* ── field chips with their colours (rrfs.js fieldSwatch) ─────────────── */
.field-btn .sw {
  display: inline-block; width: 22px; height: 7px; border-radius: 2px; margin-right: 7px;
  vertical-align: 1px; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14);
}
.field-btn.on .sw, .field-btn[aria-pressed="true"] .sw { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55); }

/* ── the source menu in the title bar (mapchrome.js wireSourceMenu) ─────── */
.source-pick { display: inline-flex; align-items: center; gap: 6px; }
.source-pick span { font-size: 9.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--mut); }
#source-select { font-size: 11px; padding: 5px 7px; max-width: 220px; }
@media (max-width: 700px) { .source-pick span { display: none; } #source-select { max-width: 150px; } }
