/* AI Geo Navigators — catastrophe risk console.
 *
 * Colour, typography and elevation all come from web/brand.css, which this
 * view loads first. Nothing in this file states a colour. It used to state 265
 * of them across three theme blocks, and a further sixty-odd inside an
 * invented "AGN" skin whose blue was not an AGN colour; the same token names
 * carried different values here, in dash.css, in lab.css and in
 * validation.css, which is why the four views did not look like one product.
 *
 * What is left in :root below is geometry — radii, rail widths, the height of
 * the top bar. Those are this view's own layout, they carry no colour, and
 * tools/smoke_test.js allows exactly that and nothing more.
 */

:root{
  color-scheme: light dark;
  /* The header no longer has a height this file can predict: it holds one row
     while the width allows it and wraps to two when it does not, so the number
     is whatever the content came to. .shell and .atlas therefore take the
     space that is left as flex children of the body rather than subtracting a
     constant, which is both shorter and correct at every width.
     The sheet is position:fixed and cannot do that, so it still measures from
     a token. The value below is the single-row height — the company lockup is
     never rendered below 120px wide and the pre-plated dark variant is 1.56:1
     at that width, so 77px of image and a hairline — and app.js writes the
     measured height over it on load and on every resize. If the script never
     runs, the sheet opens against the common case rather than against a
     number that was wrong on both sides. */
  --topbar:120px;
  /* The rails were fixed at 264 and 272. On a 1390px window that is 41% of
     the screen spent on two panels, and the map -- which is the reason the
     page exists -- got 830px of it. They now scale with the window: full width
     on a large screen, and giving room back to the map on a small one. The
     floor is the point below which the peril list and the loss numbers stop
     being readable, not an arbitrary minimum. */
  --rail:clamp(200px, 14.5vw, 248px);
  --rrail:clamp(216px, 15.5vw, 264px);
  --gap-shell:6px;
  /* --r and --r-ctl come from masthead.css, which every view loads. */
}
/* The browser's [hidden] rule lives in the UA stylesheet, so any author
   `display` declaration beats it. .shell, .atlas, .sheet and .stackpop all set
   display, which silently made `el.hidden = true` a no-op. */
[hidden]{display:none !important}

*{box-sizing:border-box}
html,body{height:100%}
/* A flex column, so the header states its own height and everything under it
   takes what is left. Every other child of the body is position:fixed. */
body{margin:0; background:var(--plane); color:var(--ink); font-family:var(--sans);
  font-size:var(--t-sm); line-height:1.5; -webkit-font-smoothing:antialiased; overflow:hidden;
  display:flex; flex-direction:column}

/* Form elements do not inherit the page font. A <button> with no family of
   its own falls back to the browser's UI font -- which is how every peril
   name in the console rail rendered in Arial while the rest of the sheet was
   Manrope, on a sheet whose whole complaint was that it looked like four
   products stacked in one window. One line, and it was invisible until the
   families were counted. */
button, input, select, textarea, optgroup { font-family: inherit }
/* Unstyled headings take the browser's scale, not ours -- an <h3> is 1.17em
   and an <h1> 2em, and every child inherits it. That is where 17.55px came
   from: a span inside an h3 nobody had written a rule for. */
h1, h2, h3, h4, h5, h6 { font-size:var(--t-md); font-weight:600; margin:0 }
b, strong { font-weight: 600 }

svg{fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round}

/* masthead */
/* Two intentional rows — masthead, then tools. Accidental wrap used to leave
   a blank left half on the second line with every control jammed right. */
header.top{flex:none; display:flex; flex-direction:column; align-items:stretch;
  gap:0; padding:0; min-width:0; background:var(--surface);
  border-bottom:1px solid var(--line); box-shadow:0 1px 0 var(--line-2)}
.toprow{display:flex; align-items:center; gap:12px; min-width:0; padding:0 14px}
.toprow-mast{padding-top:4px; padding-bottom:4px; gap:14px}
.toprow-mast .mnav{flex:1 1 auto; min-width:0; justify-content:flex-start}
.toprow-tools{gap:10px; padding-top:8px; padding-bottom:8px;
  background:var(--sunk); border-top:1px solid var(--line)}
.toptools-end{display:flex; align-items:center; gap:10px; margin-left:auto;
  flex:0 1 auto; min-width:0}
/* Kept as .topacts for app.js (currency mount). It is a full-width tools row
   now, not a right-cluster that wraps under the nav. */
.topacts{flex:none; width:100%; box-sizing:border-box}
.mnav{flex:0 0 auto}
/* Place search — lives in the left rail under Area of interest. */
.searchwrap{position:relative; flex:1 1 auto; width:100%; max-width:none; min-width:0;
  margin:0 0 var(--sp-2)}
.searchwrap .si{position:absolute; left:10px; top:50%; transform:translateY(-50%);
  width:15px; height:15px; color:var(--muted); pointer-events:none; z-index:1}
#search{width:100%; height:34px; padding:0 10px 0 32px; font-family:var(--sans); font-size:var(--t-xs);
  color:var(--ink); background:var(--sunk); border:1px solid var(--line); border-radius:var(--r-ctl);
  line-height:1.2}
#search::placeholder{color:var(--ink-3)}
#search::-webkit-search-decoration,
#search::-webkit-search-cancel-button,
#search::-webkit-search-results-button,
#search::-webkit-search-results-decoration{display:none}
#search:focus{outline:none; border-color:var(--brand); background:var(--surface);
  box-shadow:0 0 0 2px var(--brand-soft)}
#search:hover{border-color:var(--brand)}
.sresults{position:absolute; top:calc(100% + 4px); left:0; right:0; width:100%;
  z-index:60; max-height:280px;
  overflow-y:auto; background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r-ctl); box-shadow:var(--sh-lg)}
.sr{display:flex; align-items:center; gap:9px; padding:7px 11px; cursor:pointer; font-size:var(--t-sm)}
.sr:hover{background:var(--brand-soft-2)}
/* Enter takes the highlighted result, and the arrow keys move the highlight.
   Before this the results were mouse-only: they appeared, and the key every
   reader presses next did nothing. */
.sr[aria-selected="true"]{background:var(--brand-soft)}
.sr .k{font-size:var(--t-micro); text-transform:uppercase; letter-spacing:.08em; color:var(--muted);
  background:var(--sunk); padding:2px 6px; border-radius:var(--r-sw); font-weight:700}
.sr .m{margin-left:auto; color:var(--muted); font-size:var(--t-xs)}
/* 34, not 36: the appearance pair shares its line with the four navigation
   names, which are 35px tall, so anything above that made the header taller
   for nothing. */
.ic{width:34px; height:34px; border-radius:var(--r-ctl); display:grid; place-items:center; cursor:pointer;
  background:var(--sunk); border:1px solid var(--line); color:var(--ink-2)}
.ic svg{width:18px; height:18px}
.ic:hover{color:var(--brand); border-color:var(--brand)}
.natstrip{display:flex; gap:14px; padding-left:10px; border-left:1px solid var(--line)}
.natstrip div{display:flex; flex-direction:column; line-height:1.25; min-width:0}
.natstrip .k{font-size:var(--t-micro); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); font-weight:700}
/* Brand rule: dashboard numerals are tabular figures, so a column of
   values lines up and a number that ticks does not shuffle the digits
   beside it. Every rule that reaches for the numeric stack gets it. */
.natstrip .v{font-family:var(--mono); font-size:var(--t-sm); font-weight:600; font-variant-numeric:tabular-nums}

/* shell */
/* The single implicit row must be minmax(0,1fr), not auto. An auto row grows to
   the tallest column, so the rails never overflow their own box, never produce a
   scrollbar, and the overflow is simply clipped — the page looks frozen. */
.shell{flex:1 1 auto; min-height:0; overflow:hidden; display:grid;
  grid-template-columns:var(--rail) minmax(0,1fr) var(--rrail);
  grid-template-rows:minmax(0,1fr); gap:var(--gap-shell); padding:var(--gap-shell)}
.shell.no-left{grid-template-columns:0 minmax(0,1fr) var(--rrail)}
.shell.no-right{grid-template-columns:var(--rail) minmax(0,1fr) 0}
.shell.no-left.no-right{grid-template-columns:0 minmax(0,1fr) 0}
.shell.no-left .rail,.shell.no-right .rrail{display:none}
/* Explicit column placement, not auto-placement. A collapsed rail is
   display:none, which takes it out of grid flow entirely — auto-placement then
   slid .centre into the 0px track and .rrail into the middle one, so the map
   measured 0px wide and the reconciliation sentence printed one word per line
   down the left edge. Naming the column each child belongs to makes the
   placement independent of how many siblings are currently rendered. */
.rail{grid-column:1}
.rrail{grid-column:3}
/* The centre column's own grid-column sits on its main rule further down, not
   here, so the contract test that requires min-height:0 on every scroll
   ancestor finds one block for it rather than two. */
.rail,.rrail{min-width:0; min-height:0; display:flex; flex-direction:column}
.railscroll{overflow-y:auto; flex:1; min-height:0; display:flex; flex-direction:column;
  gap:var(--sp-4); padding-right:2px; overscroll-behavior:contain}
/* The rails are ink on paper, not a stack of cards.
 *
 * Every group in a rail used to be a white card with a border, a radius and a
 * shadow: five raised objects down each side, each one a rectangle the eye has
 * to resolve before it reaches the group inside it. The information is the same
 * either way, so the card was pure overhead — and it cost the map width, since
 * a card needs padding on both sides of content the rail edge could have
 * bounded for free. Groups are separated by space and a small-caps label; the
 * only rule is the rail's own edge. */
.card{background:transparent; border:0; border-radius:0; box-shadow:none}
.chead{padding:0 0 var(--sp-2); font-size:var(--t-micro); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--muted); text-align:left;
  display:flex; justify-content:space-between; align-items:baseline; gap:var(--sp-2)}
/* The unit for the column of figures on the rows below, stated once. */
.chead em{font-style:normal; font-weight:700; text-transform:uppercase; color:var(--faint)}
.cbody{padding:0; display:flex; flex-direction:column; gap:var(--sp-2)}
.fl{font-size:var(--t-xs); font-weight:600; color:var(--muted); margin-top:var(--sp-1)}
/* A select is pressable, so it keeps a box — but a quiet one, on the rail's own
   ground rather than a raised surface. */
select{width:100%; height:32px; padding:0 var(--sp-2); font-family:var(--sans);
  font-size:var(--t-sm); color:var(--ink); background:transparent;
  border:0; border-bottom:1px solid var(--line); border-radius:0; cursor:pointer}
select:disabled{color:var(--muted); cursor:not-allowed}
select:focus-visible{outline:none; border-bottom-color:var(--brand);
  box-shadow:0 2px 0 -1px var(--brand)}
.aoiacts{display:grid; grid-template-columns:repeat(3,1fr); gap:var(--sp-2);
  margin-top:var(--sp-2)}
.ab{height:30px; border-radius:6px; display:grid; place-items:center; cursor:pointer;
  background:transparent; border:1px solid var(--line); color:var(--muted)}
.ab svg{width:16px; height:16px}
.ab:hover{color:var(--brand); border-color:var(--brand)}
.ab[aria-pressed="true"]{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
.oplabel{display:flex; justify-content:space-between; font-size:var(--t-micro);
  letter-spacing:.08em;
  font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--muted)}
.oplabel b{font-family:var(--mono); font-weight:700; text-transform:uppercase; color:var(--brand); font-variant-numeric:tabular-nums}
.slider{width:100%; accent-color:var(--brand); height:18px}
/* The peril picker was a two-column grid of tall cards: five rows, 480px of
   rail, and it pushed the map layers panel off the bottom of every screen
   under about 1100px tall. It is a list of ten things a reader picks one of --
   that is a list, not a gallery. One column of rows is 300px for the same ten,
   scans in one pass, and lets the rail be narrow enough to give the map its
   width back. */
.hazgrid{display:flex; flex-direction:column; gap:0; margin-top:var(--sp-1)}
/* A peril is a ROW, not a tile.
 *
 * Ten bordered, filled, rounded tiles in a 200px rail is ten boxes competing
 * with the map for the reader's attention, and the selected one announced
 * itself with a filled panel the width of the rail. A row states the name and
 * the figure that decides between rows, and selection is a 3px mark in the
 * margin plus weight -- the least ink that can carry it. */
.hz{display:grid; grid-template-columns:18px minmax(0,1fr) auto; align-items:center;
  gap:var(--sp-2); padding:6px 0 6px var(--sp-2); border:0; border-radius:0;
  border-bottom:1px solid var(--line-2); background:transparent; cursor:pointer;
  color:var(--brand); text-align:left; position:relative}
.hz svg{width:16px; height:16px; opacity:.7}
/* Sentence case, not caps. Ten uppercase names in a column is a wall; caps are
   for the labels ABOVE values, which is where the scale puts them. */
.hz span{font-size:var(--t-sm); font-weight:400; letter-spacing:normal; text-transform:none;
  color:var(--ink-2); line-height:1.2; overflow-wrap:anywhere}
.hz:hover span{color:var(--ink)}
.hz[aria-selected="true"]{background:transparent}
.hz[aria-selected="true"] span{color:var(--ink); font-weight:600}
.hz[aria-selected="true"] svg{opacity:1}
.hz[aria-selected="true"]:before{content:""; position:absolute; left:-8px; top:7px;
  bottom:7px; width:3px; background:var(--brand); border-radius:2px}
/* The figure that decides the choice. Mono and tabular so ten of them form a
   column the eye can compare down, which is the whole point of putting it here. */
.hz .hzaal{font-family:var(--mono); font-variant-numeric:tabular-nums; font-style:normal;
  font-size:var(--t-xs); color:var(--muted); white-space:nowrap}
.hz[aria-selected="true"] .hzaal{color:var(--ink); font-weight:600}
.hz.off{opacity:.5}
/* A peril that is mapped but carries no annual probability cannot be read the
   same way as the nine that do, so it does not look the same. The mark says
   which one it is without a legend. */
.hz .hzmark{font-size:var(--t-micro); font-weight:700; letter-spacing:.08em; font-style:normal;
  text-transform:uppercase; color:var(--muted); padding:2px 5px; border-radius:var(--r-sw);
  border:1px dashed var(--line-2); white-space:nowrap}
.hz[aria-selected="true"] .hzmark{color:var(--brand); border-color:var(--brand)}
.lsearch{width:100%; height:32px; padding:0 10px; font-family:var(--sans); font-size:var(--t-xs);
  color:var(--ink); background:var(--sunk); border:1px solid var(--line); border-radius:8px}
.lsearch:focus{outline:none; border-color:var(--brand)}
.ovlist{max-height:250px; overflow-y:auto; display:flex; flex-direction:column; gap:2px}
.ovgrp{padding:7px 3px 2px; font-size:var(--t-micro); letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted); font-weight:700}
/* The row was a single flex line: dot, name, count. The count is free to be
   long — "66,548 features (9,507 drawn)" is 166px — and it took the space from
   the name, which got 35px of a 236px row and showed as "sch…". The name is
   what the row is for; the count qualifies it. So they stack, and neither has
   to win an argument with the other. */
.ov{display:grid; grid-template-columns:7px minmax(0,1fr); column-gap:7px; row-gap:1px;
  align-items:start; padding:5px 7px; border-radius:7px; cursor:pointer;
  font-size:var(--t-xs); color:var(--ink-2)}
.ov:hover{background:var(--sunk); color:var(--ink)}
.ov[aria-current="true"]{background:var(--brand-soft); color:var(--brand); font-weight:600}
.ov i{width:7px; height:7px; border-radius:2px; background:var(--brand);
  grid-column:1; grid-row:1; margin-top:5px}
/* "Annual precipitation · 1901-1930" needs 180px and the row gives 172, so
   every layer whose name carries its epoch ended in an ellipsis — and the
   epoch is the part that distinguishes it from the other five. Two lines.
   Then the rail was narrowed to give the map its width back, the row went to
   152px, and "Change in warmest month temperature · 2041–2070" needed a fourth
   line and lost its epoch to the clamp — the same failure one level down. Four
   is what the longest name in the catalogue takes at the narrowest rail. */
.ov span{grid-column:2; grid-row:1; min-width:0; overflow:hidden; display:-webkit-box;
  -webkit-line-clamp:4; -webkit-box-orient:vertical; overflow-wrap:anywhere}
.ov b{grid-column:2; grid-row:2; font-family:var(--mono); font-size:var(--t-micro); font-weight:400;
  color:var(--muted); font-variant-numeric:tabular-nums; overflow-wrap:anywhere}
.ov b:empty{display:none}
.lcount{font-size:var(--t-micro); color:var(--muted); font-family:var(--mono); font-variant-numeric:tabular-nums}
.btn{appearance:none; cursor:pointer; font-family:var(--sans); font-size:var(--t-xs); font-weight:600;
  padding:8px 13px; border-radius:9px; border:1px solid var(--line); background:var(--surface); color:var(--ink-2)}
.btn:hover{border-color:var(--brand); color:var(--brand)}
.btn.primary{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
.btn.wide{width:100%; display:flex; align-items:center; justify-content:center; gap:7px}
.btn.wide svg{width:15px; height:15px}
.btn[aria-pressed="true"]{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
.link{appearance:none; background:none; border:0; color:var(--brand); cursor:pointer; font:inherit; text-decoration:underline}
.sitelist{display:flex; flex-direction:column; gap:3px; max-height:170px; overflow-y:auto; margin-top:6px}
.site{display:flex; align-items:center; gap:7px; padding:6px 8px; border-radius:8px;
  background:var(--sunk); font-size:var(--t-xs); cursor:pointer}
.site:hover{background:var(--brand-soft-2)}
.site[aria-current="true"]{background:var(--brand-soft); box-shadow:inset 0 0 0 1px var(--brand)}
.site .pin{width:17px; height:17px; border-radius:50%; display:grid; place-items:center; flex:none;
  background:var(--brand); color:var(--brand-ink); font-size:var(--t-micro); font-weight:600}
.site .snm{flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.site .sval{font-family:var(--mono); font-size:var(--t-micro); color:var(--muted); font-variant-numeric:tabular-nums}
.site .sx{appearance:none; border:0; background:none; cursor:pointer; color:var(--muted); font-size:var(--t-sm)}
.site .sx:hover{color:var(--crit)}
.siterow{display:grid; grid-template-columns:repeat(3,1fr); gap:5px; margin-top:6px}
.siterow .btn{padding:6px 3px; font-size:var(--t-micro)}
.sitetotal{margin-top:7px; font-size:var(--t-micro); color:var(--ink-2); line-height:1.6}
.sitetotal b{font-family:var(--mono); color:var(--ink); font-variant-numeric:tabular-nums}

/* centre */
.centre{grid-column:2; display:flex; flex-direction:column; gap:6px; min-width:0; min-height:0;
  /* The strip below sizes itself against this column, not the window — the
     column is 724px at 1300 with both rails open and 1900px at 1920 with both
     shut, and no viewport breakpoint can tell those two apart. */
  container-type:inline-size; container-name:centre}
/* A zero-width track still contributes its gap, so collapsing a rail left a
   dead 10px margin where the panel used to be. Pull it back. */
.shell.no-left .centre{margin-left:calc(var(--gap-shell) * -1)}
.shell.no-right .centre{margin-right:calc(var(--gap-shell) * -1)}
/* A column of two things, not a block with a paragraph loose in it. The
   reconciliation line under the strip was a <p>, so it carried a browser
   margin above and below of its own font size and cost 21px before it printed
   a word; between that and a three-line wrap in a 435px column the sentence
   was taking 67 of the strip's 110px. It is one line now and the gap is the
   layout's. */
.statwrap{position:relative; flex:none; min-height:0; display:flex;
  flex-direction:column; gap:0;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--sh); overflow:hidden}
/* Header for the strip — in flow, not floating over the first cell. */
.statlabel{position:relative; isolation:isolate; align-self:stretch;
  display:flex; align-items:baseline; flex-wrap:wrap; gap:6px 10px;
  width:100%; margin:0; padding:8px 14px;
  background:var(--surface-2); border:0; border-bottom:1px solid var(--line-2);
  font-size:var(--t-micro); color:var(--ink-2); font-weight:700; z-index:2;
  letter-spacing:.08em; text-transform:uppercase; text-align:left;
  cursor:pointer; font-family:var(--sans)}
.statlabel:hover{color:var(--brand); background:var(--brand-soft)}
/* The qualifier on the strip label. Same line, lighter and not shouted, so
   it reads as a note on the label rather than a second label. */
.statlabel em{font-style:normal; font-weight:600; text-transform:none;
  letter-spacing:normal; color:var(--muted); margin-left:0}
.statlabel em::before{content:"· "; color:var(--faint)}
/* Collapsing sheds the seven figures and keeps the sentence: the sentence is
   the one thing on this view that says why its national loss is not the
   dashboard's, and a reader who folds the strip away has not asked to stop
   being told that. It used to be pinned to 8px with the paragraph still in
   flow, which printed it over the top of the map. */
.statwrap.collapsed .stats{display:none}
.statwrap.collapsed .statbreak{display:none}
/* With the figures gone the sentence is the only thing left, and the toggle —
   which sits over the strip's top border when there is a strip — would print
   on top of it. Collapsed, the two sit side by side instead. */
.statwrap.collapsed{flex-direction:row; align-items:center; flex-wrap:wrap}
.statwrap.collapsed .statlabel{flex:0 0 auto; border-bottom:0; background:transparent;
  padding:6px 12px}
.statwrap.collapsed #reconConsole{flex:1 1 200px; border-top:0}
/* Seven metrics at a 132px floor need 924px. The centre column is 862px at
   1440 wide and 724px at 1300, so the strip scrolled sideways and simply hid
   roads and population behind an edge — figures you cannot see are worse than
   figures on a second line. It wraps now.
   The separators are the grid gap showing the container's colour through,
   which is the only way to get them right on a wrapped row: a border-right
   would draw a stray line at the end of every row but the last. */
/* Seven tiles into four columns leaves a bordered blank cell where the eighth
   would be. auto-fit collapses the empty track instead of drawing it. */
/* Seven tiles, one line, and no stranded cell when there is genuinely no room.
   A counted grid put six across and left the seventh alone under a bordered
   blank the width of four tiles. auto-fit removed the blank but packed to six
   and stranded the seventh anyway. Neither works because seven is prime: any
   grid that wraps it leaves a ragged row. Flex does -- the tiles shrink to fit
   one line, and on the rare width where they cannot, the wrapped ones grow to
   fill their row instead of leaving a hole. */
.stats{display:flex; flex-wrap:wrap;
  gap:1px; padding:0; overflow:hidden;
  background:var(--line); border:0; border-radius:0; box-shadow:none}
.stats > .stat{flex:1 1 96px; min-width:0}
/* Counted, not auto-fit. auto-fit packs as many as will go and leaves the
   remainder stranded — six across and a lonely seventh underneath — so the
   column count is chosen to divide seven into rows that look deliberate. */
@container centre (max-width:940px){ .stats > .stat{flex-basis:96px} }
@container centre (max-width:660px){ .stats > .stat{flex-basis:118px} }
@container centre (max-width:470px){ .stats > .stat{flex-basis:136px} }
.stat{min-width:0; padding:10px 14px 11px; display:flex; align-items:flex-start;
  gap:10px; background:var(--surface); box-shadow:none}
.stat .stxt{display:flex; flex-direction:column; min-width:0; gap:3px; flex:1; line-height:1.2}
.stat .sh{display:contents}
/* nowrap + ellipsis truncated "AVERAGE ANNUAL LOSS" to "AVERAGE ANNUAL …" at
   any centre width below about 1200px, which is most of them once a rail is
   open. Two lines cost nothing here — the value beside it is the tall part of
   the row — and a clipped label is worse than a wrapped one. */
.stat .sk{font-size:var(--t-micro); line-height:1.2; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted); overflow:hidden;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical}
.stat svg{width:16px; height:16px; color:var(--brand); flex:none; opacity:.9; margin-top:2px}
.stat .sv{font-family:var(--mono); font-size:var(--t-lg); font-weight:600; letter-spacing:-.02em;
  white-space:nowrap; font-variant-numeric:tabular-nums; color:var(--ink); line-height:1.15}
.stat .sn{display:none}
/* Whether a figure is what is inside the footprint at the step on the bar,
   or an area total that does not move with it. Without this line the two
   sit side by side looking like the same kind of number, which is how the
   strip came to be read as frozen. */
.stat .sf{font-size:var(--t-micro); line-height:1.25; color:var(--muted); font-weight:500;
  letter-spacing:normal; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.stat.infoot .sv{color:var(--accent-ink)}
.stat.infoot .sf{color:var(--accent-ink); opacity:.9}
.stat.na .sv{color:var(--faint)}
.mapcard{position:relative; flex:1; min-height:0; background:var(--sunk); border:1px solid var(--line);
  border-radius:var(--r); box-shadow:var(--sh); overflow:hidden;
  /* The floating controls size themselves against the map, not the window: the
     map is 724px wide with both rails open at 1300 and 1900px with both shut,
     and a viewport media query cannot tell those apart. */
  container-type:inline-size; container-name:map}
.canvaswrap{position:absolute; inset:0}
#map{display:block; width:100%; height:100%; cursor:grab; background:var(--land)}
#map.drag{cursor:grabbing}
/* The return-period selector, and the two things it never used to say: where
   the source's own grid ends, and that the steps past it are the model's fit
   rather than the source's figures. Both sit over the map, so neither costs
   the map a pixel of height. */
/* Below the display-mode segment rather than level with it. The selector grew
   when the fitted steps were added to it, and a centred bar that is free to
   run the full width of the map runs under the mode segment on the right and
   the control cluster on the left — at 1280 the 1-in-200 pill, the last one
   the source actually publishes, was behind the word "Hazard". The width is
   bounded to the band between the two clusters, and the row below theirs is
   the only one wide enough to hold it at every width. It is an overlay, so
   none of this costs the map a pixel. */
/* left:50% plus a -50% transform centres the box but hands it only half the
   map to lay out in: an absolutely positioned element sized to fit gets
   `containing block width - left`, so on a 724px map the bar was solving for
   362px and wrapping to two rows no matter how small its chips were made.
   Anchoring both edges and letting the margins centre it gives the bar the
   width it is allowed to use. */
/* The return-period bar shares the top line with the mode tabs.
   It used to sit on its own row below them, with its label stacked above it
   again -- three bands of chrome across the top of the map before any of the
   map was visible. Label and bar are one line now, left-aligned, with the note
   under them; the mode segment holds the right end of the same line. */
/* One strip, not a pill floating over a bar.
   The label was a separate dark capsule sitting on the bar's corner, and the
   bar was a second rounded box behind it -- two containers for one control.
   The wrapper IS the control now: it carries the surface, the border and the
   radius, the label is its first item, and the chips follow. */
/* Return period docks just above the map foot, beside the depth legend —
   same baseline as the foot rule, clear of Hazard/Loss chrome at the top.
   One chip row only: the modelled/fitted note rides in the title attribute. */
.rpwrap{position:absolute; top:auto; bottom:44px; left:10px; z-index:6;
  display:flex; flex-wrap:nowrap; align-items:stretch; gap:0;
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r-ctl); box-shadow:var(--sh); padding:0;
  max-width:min(540px, calc(100% - 96px)); min-width:0; overflow:hidden}
.rpwrap .rpnote{display:none}
.rplabel{display:inline-flex; align-items:center; flex:0 0 auto;
  background:var(--surface-2); color:var(--muted); font-size:var(--t-micro); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; padding:0 10px;
  margin:0; border-right:1px solid var(--line); border-radius:0;
  white-space:nowrap; align-self:stretch}
/* It cannot wrap. Width thresholds were tuned against this machine's font
   metrics and still wrapped on the owner's, because the chips are as wide as
   whatever font actually resolves -- a threshold cannot know that. So the row
   is nowrap and the chips SHRINK: their labels are one to four digits and the
   padding absorbs it. The bar now fits its container on one line whatever the
   font does. */
.rpbar{display:flex; gap:1px; padding:3px; background:transparent; border:0;
  border-radius:0; box-shadow:none; flex-wrap:nowrap; justify-content:flex-start;
  min-width:0; overflow:hidden; flex:1 1 auto; align-items:center}
/* Thirteen steps do not fit on one line, and letting them wrap wherever they
   ran out of room split the row mid-sentence — "975 1000" alone underneath,
   which reads as an accident. The break is placed instead: what the source
   publishes on the first line, what the model fits on the second. The two
   groups already mean different things and the note below says so. */
.rpbrk{flex-basis:100%; height:0; margin:0}
/* A scale that cannot be clicked. The nine modelled perils put return periods
   in this bar and every one of them is a choice; the depth classes of a
   footprint are not -- they are all on the map at once. So they read as a key,
   not as buttons: no border, no hover, a swatch instead of a hit target. */
.rpbar .rpfix{display:inline-flex; align-items:center; gap:6px; padding:4px 9px;
  font-size:var(--t-micro); font-weight:600; color:var(--ink-2); font-family:var(--sans)}
.rpbar .rpfix i{width:11px; height:11px; border-radius:var(--r-sw);
  border:1px solid var(--line-2); flex:0 0 auto}
/* Compact is the default, roomy is the exception.
   The control used to be 151px of a 473px map — a third of the product hidden
   under its own chrome — and a width threshold only moved the problem: a map
   can be 1064px wide and 594px tall, wide enough to miss a max-width rule and
   short enough that two rows of chips matter. So the bar is sized to fit on
   one line everywhere, and the full-width treatment is switched on only where
   one line of it demonstrably fits.
   Compact drops the word from each fitted step and keeps the dashed outline.
   Nothing is left to a hover: the note directly beneath already reads "steps
   past it are fitted", and the word stays in the accessibility tree. */
.rpbar button.fitted i{position:absolute; width:1px; height:1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap; margin:0; padding:0}
.rpbar button.fitted{border-style:dashed; position:relative; padding:4px 8px}
.rpbar button.fitted .rpv{font-size:var(--t-xs)}
.rpbar button{padding:5px 9px; font-size:var(--t-xs)}
.rpbar{padding:3px; gap:1px}
.rpbrk{display:none}
.rplabel{font-size:var(--t-micro); padding:0 10px}

@container map (max-width:900px){
  .rpbar{padding:2px; gap:0}
  .rpbar button{padding:4px 6px; font-size:var(--t-xs)}
  .rpbar button.fitted{padding:3px 5px}
  .rpbar button.fitted .rpv{font-size:var(--t-xs)}
  .rplabel{font-size:var(--t-micro); padding:0 7px}
  .rpwrap{max-width:min(400px, calc(100% - 72px)); bottom:42px}
}

/* Wide map: room for the EXTRAP word on fitted steps; still bottom-docked. */
@container map (min-width:1420px){
  .rpwrap{bottom:46px; max-width:min(680px, calc(100% - 100px))}
  .rpbar{padding:4px; gap:2px}
  .rpbar button{padding:6px 12px; font-size:var(--t-sm)}
  .rpbar button.fitted{padding:4px 8px 4px 10px; border-style:solid}
  .rpbar button.fitted .rpv{font-size:var(--t-sm)}
  .rpbar button.fitted i{position:static; width:auto; height:auto; clip-path:none}
  .rplabel{font-size:var(--t-micro); padding:0 12px}
}
/* An orphaned copy of the compact rules used to sit here, after the container
   query and closed by a stray brace. Being last it always won, so the query
   above never took effect at any width: the EXTRAP marker on a fitted step was
   permanently clipped to one pixel and existed only in the accessibility tree,
   and the deliberate two-line break in the bar never applied. The compact rules
   it duplicated are already declared above, before the query. */
.rpbar button{appearance:none; border:0; cursor:pointer; background:transparent; color:var(--brand);
  font-family:var(--sans); font-size:var(--t-xs); font-weight:600; padding:5px 10px; border-radius:calc(var(--r-ctl) - 3px);
  display:inline-flex; align-items:center; justify-content:center; gap:0;
  flex:0 1 auto; min-width:0; white-space:nowrap;
  transition:background-color .12s ease, color .12s ease}
.rpbar button:hover{background:var(--brand-soft)}
.rpbar button[aria-selected="true"]{background:var(--brand); color:var(--brand-ink)}
.rpbar .none{color:var(--muted); font-size:var(--t-xs); font-weight:600; padding:6px 10px}
.rpbar button.fitted{color:var(--ink-2); padding:4px 8px;
  border:1px dashed var(--line); background:var(--surface-2)}
.rpbar button.fitted:hover{background:var(--brand-soft); border-color:var(--brand)}
.rpbar button.fitted[aria-selected="true"]{background:var(--brand); color:var(--brand-ink);
  border-style:solid; border-color:var(--brand)}
.rpbar button.fitted .rpv{font-size:var(--t-xs); font-weight:600}
.rpbar button.fitted .bmark{margin-left:4px; font-size:var(--t-micro); letter-spacing:.06em;
  text-transform:uppercase; opacity:.85}
.rpbar button.fitted[aria-selected="true"] .bmark{background:transparent;
  color:var(--brand-ink); opacity:1}
.rpnote{margin:0; max-width:none; display:flex; flex-direction:column;
  gap:0; align-items:stretch; padding:0; background:var(--surface-2)}
.rpnote .rplim, .rpnote .rpfitnote{display:block; padding:6px 12px;
  background:transparent; border:0; border-radius:0; box-shadow:none;
  font-size:var(--t-micro); line-height:1.4; color:var(--ink-2)}
.rpnote .rpfitnote{color:var(--ink-2)}
.rpnote .rplim + .rpfitnote{border-radius:0; border-top:1px solid var(--line-2)}
.rpnote .rplim + .rpfitnote:last-child,
.rpnote .rpfitnote:last-child{border-radius:0}
.rpnote:empty{display:none}
.rpnote .rpgone{color:var(--m-flag); border-color:var(--m-flag);
  max-width:none; white-space:normal}
.rpnote .bmark{margin-left:0; margin-right:5px}
/* One column, on the right, under the mode tabs. It was a two-wide cluster on
   the LEFT, which cost the map ninety pixels of width down its whole height
   for twelve buttons. Stacked single-file on the right it costs forty, beside
   chrome that is already there. */
/* One instrument strip, not twelve floating pills.
 *
 * Twelve filled navy circles with individual shadows ran down the right edge of
 * every map: twelve separate objects, each with its own drop shadow, each
 * competing with the sheet for attention, and together an 40px-wide column of
 * the darkest colour on the page sitting on top of the data. Nobody designed
 * that; it accumulated one control at a time.
 *
 * The strip is one object. One surface, one border, one shadow, and the cells
 * inside it are separated by a hairline the way the keys of an instrument are.
 * The ink is quiet until a control is pressed, which is when a control has
 * something to say. */
.mapctl{position:absolute; right:12px; top:52px; z-index:6;
  display:flex; flex-direction:column; gap:0; align-items:stretch;
  width:36px; background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r-ctl); box-shadow:var(--sh); overflow:hidden}
.mc{width:100%; height:32px; border-radius:0; display:grid; place-items:center;
  cursor:pointer; background:transparent; color:var(--muted); border:0;
  border-bottom:1px solid var(--line-2); box-shadow:none;
  transition:background-color .12s ease, color .12s ease}
.mapctl > .mc:last-child{border-bottom:0}
.mc svg{width:16px; height:16px}
.mc.mcword span[aria-hidden]{font-family:var(--mono); font-size:var(--t-xs); font-weight:600;
  letter-spacing:normal; line-height:1}
.mc.sm{width:100%; height:28px}
.mc.sm svg{width:14px; height:14px}
.mc:hover{filter:none; background:var(--brand-soft); color:var(--brand)}
.mc[aria-pressed="true"],.mc[aria-expanded="true"]{background:var(--brand);
  color:var(--brand-ink)}
.nlabel{font-size:var(--t-micro); font-weight:600; line-height:1; display:flex; flex-direction:column; align-items:center}
.nlabel i{font-style:normal; font-size:var(--t-micro); margin-top:1px}
.modewrap{position:absolute; right:12px; top:10px; z-index:6; display:flex; flex-direction:column;
  gap:6px; align-items:flex-end}
.modeseg{display:flex; gap:2px; padding:3px; background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r-ctl); box-shadow:var(--sh)}
.modeseg button{appearance:none; border:0; cursor:pointer; background:transparent; color:var(--ink-2);
  font-family:var(--sans); font-size:var(--t-xs); font-weight:600; padding:6px 11px;
  border-radius:calc(var(--r-ctl) - 3px);
  transition:background-color .12s ease, color .12s ease}
.modeseg button:hover{color:var(--brand); background:var(--brand-soft)}
.modeseg button[aria-pressed="true"]{background:var(--brand); color:var(--brand-ink)}
.confbadge{font-size:var(--t-micro); font-weight:600; padding:5px 10px; border-radius:var(--r-ctl);
  box-shadow:var(--sh); border:1px solid var(--line); background:var(--surface); color:var(--ink-2)}
.popcard{background:transparent; border:0; border-radius:0;
  box-shadow:none; padding:0}
/* A caption, not a card. It sits in the map's foot rule now, so it needs no
   surface of its own — the foot already has one. */
.rampcard{background:transparent; border:0; border-radius:0;
  box-shadow:none; padding:0; display:flex; align-items:center; gap:var(--sp-3);
  min-width:0; flex:0 1 auto; overflow:hidden}
/* .rt and .rk were each declared twice here, left over from when this was a
   vertical card in the rail. The later rule won, so every key carried a 4px
   top margin and `justify-content:space-between` -- which in a two-child flex
   item pushes the swatch away from its own label by whatever room is going,
   and made "Very High" 72px beside "Low" at 36px. One rule each, written for
   the strip it now is. */
.rampcard .rt{font-family:var(--sans); font-size:var(--t-micro); font-weight:600; color:var(--ink-2); margin:0;
  white-space:nowrap; min-width:0; overflow:hidden; text-overflow:ellipsis}
.rampcard .rampwrap{flex:1; min-width:110px}
/* The keys never shrink. The title is the one thing on this row that can be
   read from what is beside it, so the title is what gives way -- a clipped
   legend key is a colour with no name. */
.rampcard .rk{display:flex; align-items:center; gap:5px; flex:0 0 auto;
  font-size:var(--t-micro); color:var(--muted); white-space:nowrap; margin:0}
.rampbar{display:flex; height:8px; border-radius:4px; overflow:hidden}
.rampbar i{flex:1}
.rampends{display:flex; justify-content:space-between; font-family:var(--mono); font-size:var(--t-micro);
  color:var(--muted); margin-top:2px; font-variant-numeric:tabular-nums}
.rampcard .rk b{font-family:var(--mono); color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums}
.rampcard .swatch{display:inline-block; width:8px; height:8px; border-radius:2px; flex:0 0 auto}
.rampcard .exag{margin-top:6px; padding-top:6px; border-top:1px solid var(--line-2)}
.rampcard .exag label{display:block; font-size:var(--t-micro); text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); font-weight:700; margin-bottom:3px}
.rampcard .exag input{width:100%; accent-color:var(--brand)}
.popcard .pt{font-size:var(--t-micro); font-weight:700; color:var(--muted);
  letter-spacing:.08em; text-transform:uppercase; margin-bottom:var(--sp-2)}
.prow{display:flex; align-items:center; gap:var(--sp-2); margin-bottom:var(--sp-1);
  font-size:var(--t-xs)}
.prow svg{width:13px; height:13px; flex:none}
.prow .pv{font-family:var(--mono); font-weight:600; color:var(--ink); font-variant-numeric:tabular-nums}
.prow .pp{margin-left:auto; font-family:var(--mono); color:var(--muted); font-size:var(--t-micro); font-variant-numeric:tabular-nums}
.pbar{height:4px; border-radius:2px; background:var(--sunk); overflow:hidden; margin:2px 0 7px}
.pbar i{display:block; height:100%}
.ptotal{display:flex; justify-content:space-between; padding-top:7px; border-top:1px solid var(--line-2);
  font-size:var(--t-xs); color:var(--ink-2)}
.ptotal b{font-family:var(--mono); color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums}
/* Back to the frame edge. The dock was inset to clear a button column that
   used to sit under it on the left; the column is on the right now, so the
   inset was costing the legend fifty pixels for nothing. The right edge keeps
   its clearance, because that is where the column is. */
.mapdock{position:absolute; left:auto; right:12px; bottom:36px; z-index:6; display:flex;
  align-items:flex-end; justify-content:flex-end; gap:var(--sp-2); pointer-events:none;
  flex-wrap:nowrap}
.mapdock > *{pointer-events:auto}
.explayers{display:flex; gap:0; padding:0; background:var(--surface);
  border:1px solid var(--line); border-radius:var(--r-ctl); box-shadow:var(--sh); flex:none;
  overflow:hidden}
.el{width:32px; height:30px; border-radius:0; display:grid; place-items:center;
  cursor:pointer; background:transparent; border:0; border-right:1px solid var(--line-2);
  color:var(--muted); transition:background-color .12s ease, color .12s ease}
.explayers > .el:last-child{border-right:0}
.el svg{width:16px; height:16px}
.el:hover{background:var(--brand-soft); color:var(--brand)}
.el[aria-pressed="true"]{background:var(--brand); color:var(--brand-ink)}
.el:disabled{opacity:.3; cursor:not-allowed}
.basepop,.stackpop{position:absolute; right:56px; z-index:8; background:var(--surface);
  border:1px solid var(--line); border-radius:var(--r-ctl); box-shadow:var(--sh-lg); width:225px; overflow:hidden}
.basepop{top:140px} .stackpop{top:190px; max-height:46%; display:flex; flex-direction:column}
.threepop{top:240px; width:252px}
/* The vertical scale, inside the 2.5D popover. A relief map has always printed
   its exaggeration; here the reader sets it, so the value has to stay on
   screen beside the control that changes it. */
.threepop .exag{display:grid; grid-template-columns:1fr auto; align-items:center;
  gap:var(--sp-1) var(--sp-2); margin:var(--sp-2) 0 0; padding-top:var(--sp-2);
  border-top:1px solid var(--line-2)}
.threepop .exag label{grid-column:1 / -1; font-size:var(--t-micro); font-weight:700;
  text-transform:uppercase; letter-spacing:.08em; color:var(--muted)}
.threepop .exag input{width:100%; accent-color:var(--brand); min-height:24px}
.threepop .exag b{font-family:var(--mono); font-size:var(--t-xs); color:var(--ink);
  font-variant-numeric:tabular-nums}
.bpnote{padding:8px 11px; border-top:1px solid var(--line); font-size:var(--t-micro);
  line-height:1.45; color:var(--muted)}
.bp{display:flex; align-items:center; gap:8px; padding:8px 11px; cursor:pointer; font-size:var(--t-xs); color:var(--ink-2)}
.bp:hover{background:var(--sunk)}
.bp[aria-pressed="true"]{background:var(--brand-soft); color:var(--brand); font-weight:600}
.bp em{font-style:normal; margin-left:auto; font-size:var(--t-micro); color:var(--muted)}
.sphead{padding:8px 11px; border-bottom:1px solid var(--line); font-size:var(--t-micro); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--muted); display:flex; justify-content:space-between}
.splist{overflow-y:auto; padding:3px 0}
.slrow{padding:6px 11px; border-bottom:1px solid var(--line-2)}
.slrow:last-child{border-bottom:0}
.sltop{display:flex; align-items:center; gap:7px}
.slnm{flex:1; font-size:var(--t-xs); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--ink-2)}
.slx{appearance:none; border:0; background:none; cursor:pointer; color:var(--muted); font-size:var(--t-md)}
.slx:hover{color:var(--crit)}
.slrow input[type=range]{width:100%; margin-top:3px; accent-color:var(--brand); height:13px}
.stackempty{padding:11px; font-size:var(--t-xs); color:var(--muted)}
.measurebox{position:absolute; right:56px; bottom:86px; z-index:8; background:var(--surface);
  border:1px solid var(--line); border-radius:11px; box-shadow:var(--sh-lg); padding:9px 12px; width:200px}
.measurebox .mh{font-size:var(--t-micro); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); font-weight:700}
.measurebox .mv{font-family:var(--mono); font-size:var(--t-md); font-weight:600; color:var(--brand); margin:2px 0; font-variant-numeric:tabular-nums}
.measurebox .mt{font-size:var(--t-micro); color:var(--muted)}
.mapfoot{position:absolute; left:0; right:0; bottom:0; z-index:5; display:flex; align-items:center;
  gap:var(--sp-4); padding:var(--sp-2) var(--sp-3);
  background:color-mix(in srgb, var(--surface) 94%, transparent);
  border-top:1px solid var(--line); font-family:var(--mono); font-size:var(--t-xs);
  color:var(--ink-2); font-variant-numeric:tabular-nums}
.mapfoot .scalebar{margin-left:auto}
.scalebar{display:flex; align-items:center; gap:5px}
.scalebar i{display:block; height:5px; border:1px solid var(--ink-2); border-top:0}
.coords{color:var(--muted)}
.attrib{margin-left:auto; color:var(--muted); font-family:var(--sans); font-size:var(--t-micro); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap}

/* right rail */
/* The clip moved inward. overflow:hidden here was rounding the tab strip's
   corners, but it also cut the rail's own collapse handle in half — the handle
   hangs 8px into the gutter by design, and this was the box that clipped it.
   The panels inside round their corners themselves. */
.rrail{background:var(--surface); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--sh); overflow:visible; min-height:0}
#lossPanel,#sitePanel{flex:1; min-height:0; display:flex; flex-direction:column;
  overflow:hidden; border-radius:inherit}
.rrtabs{display:flex; gap:var(--sp-5); padding:var(--sp-3) var(--sp-4) 0;
  background:transparent; border-bottom:1px solid var(--line)}
.rrt{flex:0 0 auto; appearance:none; border:0; cursor:pointer; background:transparent;
  color:var(--muted); font-family:var(--sans); font-size:var(--t-sm); font-weight:600;
  padding:var(--sp-2) 0 var(--sp-3); border-radius:0}
.rrt[aria-selected="true"]{background:transparent; color:var(--ink); box-shadow:inset 0 -2px 0 var(--brand)}
/* The peril's name headed a gradient bar in the brand navy — the single
   loudest object in the right rail, spent on a word the reader already chose.
   It is a heading now: the name at the panel-title size, over the tier that
   qualifies it, on the rail's own ground. */
.losshead{padding:var(--sp-4) var(--sp-4) var(--sp-2); font-size:var(--t-lg);
  font-weight:600; letter-spacing:-.02em; color:var(--ink); background:transparent}
.rrailscroll{padding:0 var(--sp-4) var(--sp-4); display:flex; flex-direction:column;
  gap:var(--sp-5); overflow-y:auto; flex:1; min-height:0}
/* Three columns of 1fr floor at min-content, so in a 244px rail the three
   tracks measured 335px and "PML 250" was cut off past the rail's edge. A
   currency string is not a width you can plan around, so the tiles are rows
   now: label left, figure right, nothing to clip. */
.lossnums{display:grid; grid-template-columns:minmax(0,1fr); gap:0}
#popcard{flex:none}
/* Three figures in three filled, rounded boxes is three objects for three
   numbers. A hairline between rows says the same thing with none of the ink,
   and it lets the figure carry the weight instead of the container. */
.lossnums div{background:transparent; border-radius:0; padding:7px 0;
  border-bottom:1px solid var(--line-2);
  display:flex; align-items:baseline; justify-content:space-between; gap:var(--sp-3)}
.lossnums .k{font-size:var(--t-micro); letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted); font-weight:700}
/* The fitted mark on a step past the source's range, inline with the label. */
.lossnums .k i{margin-left:6px}
.lossnums .v{font-family:var(--mono); font-size:var(--t-md); font-weight:600;
  font-variant-numeric:tabular-nums; white-space:nowrap}
.donutwrap{display:flex; flex-direction:column; align-items:center; gap:9px; flex:none}
#donut{width:100%; max-width:190px; height:auto; overflow:visible}
.donutlegend{display:flex; flex-direction:column; gap:0; width:100%}
.dlhead{display:flex; justify-content:space-between; align-items:baseline;
  font-size:var(--t-micro); font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted); padding-bottom:var(--sp-2)}
.dlhead em{font-style:normal; color:var(--faint)}
.dl{display:flex; align-items:center; gap:var(--sp-2); font-size:var(--t-xs);
  color:var(--ink-2); padding:4px 0; border-bottom:1px solid var(--line-2)}
.dl i{width:8px; height:8px; border-radius:2px; flex:none}
.dl b{margin-left:auto; font-family:var(--mono); color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums}
.metricseg{display:flex; gap:var(--sp-4); padding:0; background:transparent;
  border-bottom:1px solid var(--line)}
.metricseg button{flex:0 0 auto; appearance:none; border:0; cursor:pointer;
  background:transparent; color:var(--muted); font-family:var(--sans);
  font-size:var(--t-xs); font-weight:600; padding:var(--sp-2) 0 var(--sp-2); border-radius:0}
.metricseg button[aria-pressed="true"]{background:transparent; color:var(--ink);
  box-shadow:inset 0 -2px 0 var(--brand)}
#epchart{width:100%; height:auto; overflow:visible}
.epwrap{min-height:150px; padding-bottom:6px}
.lossnote{font-size:var(--t-xs); color:var(--muted); line-height:1.55}
.siteReport{padding:13px; overflow-y:auto; flex:1; min-height:0}
.srhead{font-size:var(--t-md); font-weight:600}
.srsub{font-size:var(--t-xs); color:var(--muted); margin-bottom:11px; font-family:var(--mono); font-variant-numeric:tabular-nums}
.srsec{font-size:var(--t-micro); letter-spacing:.08em; text-transform:uppercase; color:var(--muted);
  font-weight:700; margin:13px 0 5px}
.srkv{display:flex; justify-content:space-between; gap:9px; padding:4px 0;
  border-bottom:1px solid var(--line-2); font-size:var(--t-xs)}
.srkv span{color:var(--ink-2)} .srkv b{font-family:var(--mono); font-weight:600; font-variant-numeric:tabular-nums}
.srperil{display:grid; grid-template-columns:1fr auto auto; gap:7px; align-items:center;
  padding:5px 0; border-bottom:1px solid var(--line-2); font-size:var(--t-xs)}
.srperil .pb{font-size:var(--t-micro); font-weight:600; padding:2px 5px; border-radius:4px}
.srperil b{font-family:var(--mono); font-weight:600; font-variant-numeric:tabular-nums}
.srlayer{display:flex; justify-content:space-between; gap:7px; padding:3px 0; font-size:var(--t-xs);
  border-bottom:1px solid var(--line-2)}
.srlayer span{color:var(--ink-2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.srlayer b{font-family:var(--mono); font-weight:600; flex:none; font-variant-numeric:tabular-nums}
.srempty{color:var(--muted); font-size:var(--t-xs); padding:18px 0; text-align:center}

/* sheet */
/* Sheet fills the plane under the header. A short dimmed strip of map at the
   top is the backdrop (click to close). The exposure cards used to poke through
   that gap half-cut — they are hidden while the sheet is open. */
.sheet{position:fixed; top:var(--topbar); left:0; right:0; bottom:0; z-index:70;
  display:flex; flex-direction:column; justify-content:flex-end;
  padding-top:20px; box-sizing:border-box;
  background:color-mix(in srgb, var(--ink) 22%, transparent)}
.sheetpanel{flex:1 1 auto; min-height:0; display:flex; flex-direction:column;
  background:var(--plane); border-top:1px solid var(--line); box-shadow:var(--sh-lg);
  max-height:none; border-radius:var(--r) var(--r) 0 0}
body.sheet-open .statwrap{display:none}
body.sheet-open .mapctl{opacity:.35; pointer-events:none}
.sheetbar{flex:none; height:52px; display:flex; align-items:center; gap:11px; padding:0 15px;
  background:var(--surface); border-bottom:1px solid var(--line)}
.sheettitle{margin:0; font-family:var(--sans); font-size:var(--t-md); font-weight:600;
  letter-spacing:-.01em; color:var(--ink); white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; min-width:0}
/* Says the exit out loud. Every overlay on this page now does. */
.sheethint{margin-left:auto; font-size:var(--t-micro); color:var(--muted); white-space:nowrap}
.sheetbar .sheethint + .ic{margin-left:0}
@media (max-width:860px){ .sheethint{display:none} }
.sheetbody{flex:1; min-height:0; overflow-y:auto; padding:20px;
  overscroll-behavior:contain; -webkit-overflow-scrolling:touch}
.view{max-width:1180px; margin:0 auto}
.sheetsub{margin:0 0 12px; font-size:var(--t-xs); color:var(--muted)}
.h2{display:flex; align-items:baseline; gap:11px; margin:0 0 4px; flex-wrap:wrap}
.h2 h2{font-size:var(--t-lg); font-weight:600; margin:0; letter-spacing:-.02em}
.h2 .note{font-size:var(--t-xs); color:var(--muted)}
.lede{color:var(--ink-2); font-size:var(--t-xs); margin:0 0 15px; max-width:84ch}
.pgrid{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:11px}
.pcard{background:var(--surface); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--sh); min-width:0; display:flex; flex-direction:column; overflow:hidden}
.pchead{display:flex; align-items:center; justify-content:space-between; gap:11px; padding:11px 14px;
  border-bottom:1px solid var(--line); flex-wrap:wrap}
.pchead h3{margin:0; font-size:var(--t-xs); font-weight:600}
.pchead .meta{font-family:var(--mono); font-size:var(--t-micro); color:var(--muted); font-variant-numeric:tabular-nums}
.pcbody{padding:13px 14px}
.dim{color:var(--muted); font-size:var(--t-xs)}
code{font-family:var(--mono); font-size:var(--t-micro); background:var(--sunk); padding:1px 4px; border-radius:3px; font-variant-numeric:tabular-nums}
.statrow{display:grid; grid-template-columns:repeat(5,1fr); gap:9px; margin-bottom:11px}
.statrow .st{background:var(--surface); border:1px solid var(--line); border-radius:var(--r);
  padding:11px 13px; display:flex; flex-direction:column; gap:3px; box-shadow:var(--sh); min-width:0}
.statrow .k{font-size:var(--t-micro); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); font-weight:700}
.statrow .v{font-family:var(--mono); font-size:var(--t-lg); font-weight:600; letter-spacing:-.02em; font-variant-numeric:tabular-nums}
.statrow .n{font-size:var(--t-micro); color:var(--ink-2)}
.hazbar{display:flex; gap:5px; flex-wrap:wrap; margin-bottom:11px}
.hazbar button{appearance:none; cursor:pointer; font-family:var(--sans); font-size:var(--t-xs); font-weight:600;
  padding:6px 12px; border:1px solid var(--line); border-radius:9px; background:var(--surface); color:var(--ink-2)}
.hazbar button[aria-selected="true"]{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
.keys{display:flex; gap:14px; flex-wrap:wrap; padding:0 14px 11px}
.key{display:flex; align-items:center; gap:5px; font-size:var(--t-xs); color:var(--ink-2)}
.key i{width:13px; height:2.5px; display:block; border-radius:2px}
.key i.sq{width:9px; height:9px; border-radius:2px}
.cov{display:flex; flex-direction:column; gap:7px}
.covrow{display:grid; grid-template-columns:92px 1fr 80px; align-items:center; gap:9px}
.covrow .nm{font-size:var(--t-xs); color:var(--ink-2)}
.covrow .bar{height:11px; border-radius:5px; background:var(--sunk); display:flex; gap:2px; overflow:hidden}
.covrow .bar i{display:block; height:100%}
.covrow .fig{font-family:var(--mono); font-size:var(--t-micro); color:var(--muted); text-align:right; font-variant-numeric:tabular-nums}
.ql{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:9px}
.qi{background:var(--surface); border:1px solid var(--line); border-radius:10px; padding:12px 14px;
  display:flex; gap:11px; align-items:flex-start; box-shadow:var(--sh)}
.qi .n{font-family:var(--mono); font-size:var(--t-sm); font-weight:600; color:var(--brand); flex:none; min-width:58px; font-variant-numeric:tabular-nums}
.qi .t{font-size:var(--t-xs); color:var(--ink-2); line-height:1.55}
.drop{border:1.5px dashed var(--line); border-radius:11px; padding:20px 15px; text-align:center}
.drop.over{border-color:var(--brand); background:var(--brand-soft-2)}
.drop p{margin:0 0 5px}
.row{display:flex; gap:7px; margin-top:11px; flex-wrap:wrap}
.filemeta{margin-top:9px; font-family:var(--mono); font-size:var(--t-micro); color:var(--muted); font-variant-numeric:tabular-nums}
.sectormap{display:flex; flex-direction:column; gap:6px; max-height:360px; overflow-y:auto;
  padding-right:4px}
.smrow{display:grid; grid-template-columns:1fr auto; gap:9px; align-items:center; font-size:var(--t-xs)}
.smrow .seg{display:flex; gap:3px}
.smrow .seg button{appearance:none; cursor:pointer; font-family:var(--sans); font-size:var(--t-micro); font-weight:600;
  padding:4px 9px; border:1px solid var(--line); background:var(--surface); color:var(--ink-2); border-radius:7px}
.smrow .seg button[aria-pressed="true"]{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
.conf{display:grid; grid-template-columns:120px 90px 1fr; gap:10px; align-items:start; padding:8px 0;
  border-bottom:1px solid var(--line-2); font-size:var(--t-xs)}
.conf .cb{font-size:var(--t-micro); font-weight:600; padding:3px 7px; border-radius:5px; text-align:center}
.conf .cn{color:var(--ink-2); line-height:1.5}
.tablewrap{overflow:auto; max-height:440px}
table{border-collapse:collapse; width:100%; font-size:var(--t-xs)}
thead th{position:sticky; top:0; background:var(--surface); z-index:2; text-align:right; font-size:var(--t-micro);
  letter-spacing:.08em; text-transform:uppercase; color:var(--muted); font-weight:700; padding:8px 11px;
  border-bottom:1px solid var(--line); white-space:nowrap}
thead th:first-child, tbody td:first-child{text-align:left}
thead th.s{cursor:pointer; user-select:none}
thead th.s:hover{color:var(--brand)}
thead th[aria-sort]{color:var(--brand)}
tbody td{padding:6px 11px; border-bottom:1px solid var(--line-2); text-align:right;
  font-family:var(--mono); font-variant-numeric:tabular-nums; white-space:nowrap}
tbody td:first-child{font-family:var(--sans); font-weight:600}
tbody tr:hover{background:var(--brand-soft-2)}
tbody tr.click{cursor:pointer}
.chart{display:block; width:100%; height:auto; overflow:visible}
.gl{stroke:var(--line); stroke-width:1}
.ax{stroke:var(--faint); stroke-width:1}
.tick{fill:var(--muted); font-family:var(--mono); font-size:var(--t-micro); stroke:none; font-variant-numeric:tabular-nums}
.dlab{font-family:var(--sans); font-size:var(--t-micro); font-weight:600; fill:var(--ink-2); stroke:none}
.main{fill:none; stroke:var(--brand); stroke-width:2.2; stroke-linejoin:round}
.ctx{fill:none; stroke:var(--faint); stroke-width:1.2; opacity:.55; stroke-linejoin:round}
#tt{position:fixed; pointer-events:none; z-index:90; opacity:0; transition:opacity .09s;
  background:var(--surface); border:1px solid var(--line); border-radius:9px; padding:8px 11px;
  max-width:260px; box-shadow:var(--sh-lg)}
#tt .tn{font-size:var(--t-xs); font-weight:600; margin-bottom:3px}
#tt .tr{display:flex; justify-content:space-between; gap:13px; font-size:var(--t-micro); color:var(--ink-2);
  font-family:var(--mono); font-variant-numeric:tabular-nums}
#tt .tr b{color:var(--ink); font-weight:600}
/* A note under the rows, for a peril that cannot answer what the other nine
   answer. It wraps, unlike a .tr, because it is a sentence and not a figure. */
#tt .trn{margin-top:4px; padding-top:4px; border-top:1px solid var(--line);
  font-size:var(--t-micro); line-height:1.35; color:var(--muted); max-width:230px}
/* A figure the bundle does not hold, told apart from a figure that is zero. */
#tt .tgap{color:var(--muted); font-weight:600; font-style:normal}
#boot{position:fixed; inset:0; display:flex; align-items:center; justify-content:center; gap:11px;
  background:var(--plane); color:var(--muted); font-size:var(--t-sm); z-index:99}
.spin{width:16px; height:16px; border:2px solid var(--line); border-top-color:var(--brand);
  border-radius:50%; animation:sp .7s linear infinite}
@keyframes sp{to{transform:rotate(360deg)}}
@media (max-width:1250px){
  .shell,.shell.no-right{grid-template-columns:270px minmax(0,1fr);
    grid-template-rows:minmax(0,1fr)}
  .shell.no-left,.shell.no-left.no-right{grid-template-columns:0 minmax(0,1fr);
    grid-template-rows:minmax(0,1fr)}
  .rrail{display:none}
  .shell.no-right .centre{margin-right:0}
  .statrow,.pgrid,.ql{grid-template-columns:minmax(0,1fr)}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important; animation:none!important}}

.epwrap{min-height:150px}

/* ------------------------------------------------------------------ atlas */
.viewseg{display:flex; gap:2px; padding:3px; background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r-ctl)}
/* The tallest control in the working group, so it is what the group's line
   height comes to. 6px of vertical padding puts it at 42, level with the
   search box beside it, and the labels stay. */
.viewseg button{appearance:none; border:0; cursor:pointer; background:transparent; color:var(--ink-2);
  font-family:var(--sans); font-size:var(--t-sm); font-weight:600; line-height:1.2;
  padding:6px 14px; border-radius:calc(var(--r-ctl) - 3px);
  display:flex; align-items:center; gap:7px; white-space:nowrap;
  transition:color .12s ease, background-color .12s ease}
.viewseg button svg{width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round; flex:none}
.viewseg button:hover{color:var(--brand); background:var(--brand-soft)}
.viewseg button[aria-pressed="true"]{background:var(--brand); color:var(--brand-ink);
  box-shadow:none}
.viewseg button[aria-pressed="true"]:hover{background:var(--brand); color:var(--brand-ink)}
/* Kill the browser's black focus ring — it was painting a thick outline on
   Analytics after click and fighting the pressed fill. */
.viewseg button:focus{outline:none}
.viewseg button:focus-visible{box-shadow:0 0 0 2px var(--surface), 0 0 0 4px var(--brand)}
.viewseg button[aria-pressed="true"]:focus-visible{
  box-shadow:0 0 0 2px var(--brand), 0 0 0 4px var(--brand-soft)}
/* Panels share the Map/Atlas segment look so the header is two controls, not
   a map switch plus three loose icon-buttons plus another tab strip inside
   the sheet. Slightly tighter padding so four labels still fit. */
.panelseg button{padding:6px 12px}
.toprow-tools .viewseg{background:var(--surface)}
@media (max-width:1280px){
  .panelseg button span{display:none}
  .panelseg button{padding:6px 11px}
}

/* Currency switch. It reuses the segmented control the view switch already
   uses — a reader who has learned one control in this header has learned this
   one — and carries the rate beside it, because a dollar figure with no rate
   attached is not a figure anyone can check. No new colour tokens: every value
   below is one the header already defines in each theme. */
.curwrap{display:flex; align-items:center; gap:9px}
.curseg button{padding:6px 13px; font-family:var(--mono); font-size:var(--t-xs); font-weight:600; letter-spacing:normal; font-variant-numeric:tabular-nums}
.fxnote{font-family:var(--mono); font-size:var(--t-micro); line-height:1.25; color:var(--ink-2);
  max-width:130px; font-variant-numeric:tabular-nums}
@media (max-width:900px){ .fxnote{display:none} }

/* Said out loud when the rate in money.js and the rate the API reports have
   come apart. Text takes the theme's ink so it stays readable on both. */
.fxwarn{
  position:relative; z-index:9999; padding:9px 16px; background:var(--surface);
  border-bottom:1px solid var(--line); border-left:4px solid var(--crit);
  color:var(--ink); font-size:var(--t-sm); line-height:1.45;
}

.atlas{flex:1 1 auto; min-height:0; display:flex; flex-direction:column; background:var(--plane)}
.atlasbar{flex:none; display:flex; align-items:center; gap:14px; padding:12px 16px;
  background:var(--surface); border-bottom:1px solid var(--line); flex-wrap:wrap}
.atlastitle{font-size:var(--t-md); font-weight:600}
.atlastitle em{font-style:normal; font-weight:400; color:var(--muted); margin-left:8px; font-size:var(--t-xs)}
.atlasbar .lsearch{max-width:280px; height:34px}
.atlasfilters{display:flex; gap:5px; flex-wrap:wrap; margin-left:auto}
.af{appearance:none; cursor:pointer; font-family:var(--sans); font-size:var(--t-xs); font-weight:600;
  padding:5px 11px; border:1px solid var(--line); border-radius:999px; background:var(--surface);
  color:var(--ink-2)}
.af[aria-pressed="true"]{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
/* Bands, so 29 families read as three questions rather than one wall. The
   label is set small and quiet: it is a signpost, not a control, and nothing
   in the row should compete with the chips a reader is actually aiming at. */
.afband{display:inline-flex; align-items:center; gap:5px; flex-wrap:wrap;
  padding-left:9px; margin-left:4px; border-left:1px solid var(--line-2)}
.afbl{font-size:var(--t-micro); font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-3); white-space:nowrap;
  margin-right:1px}
.atlasbody{flex:1; min-height:0; overflow-y:auto; padding:16px; overscroll-behavior:contain}

/* ------------------------------------------------------- the atlas viewer --
   One layer, its legend and its cartography. Nothing else: no return-period
   bar, no peril rail, no mode segment, no side rails. The card is a picture
   of a layer, so pressing it shows that picture at full size rather than
   rebuilding the whole console around it. */
.atlasview{flex:1; min-height:0; display:flex; flex-direction:column;
  background:var(--plane)}
/* Search, 25 filter chips and the close control belong to the GRID. With a map
   open they were 300px of controls that did nothing to it, above a map that
   wanted the height. The viewer's own bar carries the way back. */
.atlas:has(> .atlasview:not([hidden])) .atlasbar{display:none}
.avbar{display:flex; align-items:center; gap:var(--sp-3);
  padding:var(--sp-2) var(--sp-4); border-bottom:1px solid var(--line);
  background:var(--surface); flex:0 0 auto}
.avback{display:inline-flex; align-items:center; gap:5px; height:30px;
  padding:0 11px 0 7px; border:1px solid var(--line); border-radius:var(--r-ctl);
  background:var(--sunk); color:var(--ink-2); cursor:pointer;
  font-family:var(--sans); font-size:var(--t-xs); font-weight:600;
  white-space:nowrap; flex:0 0 auto}
.avback svg{width:15px; height:15px; fill:none; stroke:currentColor;
  stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round}
.avback:hover{color:var(--brand); border-color:var(--brand)}
.avtitle{min-width:0; flex:1 1 auto}
.avname{font-size:var(--t-md); font-weight:600; color:var(--ink);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.avsub{font-size:var(--t-xs); color:var(--muted);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.avacts{display:flex; align-items:center; gap:var(--sp-2); flex:0 0 auto}
.avbtn{width:30px; height:30px; display:grid; place-items:center; cursor:pointer;
  border:1px solid var(--line); border-radius:var(--r-ctl); background:var(--sunk);
  color:var(--ink-2); padding:0}
.avbtn svg{width:15px; height:15px; fill:none; stroke:currentColor;
  stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round}
.avbtn:hover{color:var(--brand); border-color:var(--brand)}
.avopen{height:30px; padding:0 13px; cursor:pointer; border:1px solid var(--brand);
  border-radius:var(--r-ctl); background:var(--brand); color:var(--brand-ink);
  font-family:var(--sans); font-size:var(--t-xs); font-weight:600; white-space:nowrap}
.avopen:hover{filter:brightness(1.06)}
.avmap{position:relative; flex:1; min-height:0; display:flex; flex-direction:column}
/* The canvas takes what is left after the legend, rather than running under
   it. Absolutely positioned, the legend covered the south coast on every map
   -- Karachi and the whole Indus delta sat behind it. */
.avcanvas{position:relative; flex:1; min-height:0}
.avmap canvas{position:absolute; inset:0; width:100%; height:100%; display:block}
/* The legend is the map's foot rule, the same shape the console's is, so a
   reader learns one place to look for what the colours mean. */
.avlegend{flex:0 0 auto; display:flex;
  align-items:center; gap:var(--sp-3); padding:7px var(--sp-4);
  background:var(--surface); border-top:1px solid var(--line-2);
  min-width:0; overflow:hidden}
.avlegend .rt{font-family:var(--sans); font-size:var(--t-micro); font-weight:600;
  color:var(--ink-2); margin:0; white-space:nowrap; min-width:0;
  overflow:hidden; text-overflow:ellipsis}
.avlegend .rk{display:flex; align-items:center; gap:5px; flex:0 0 auto;
  font-size:var(--t-micro); color:var(--muted); white-space:nowrap}
.avlegend .swatch{display:inline-block; width:8px; height:8px; border-radius:2px;
  flex:0 0 auto}
/* The ramp needs a width of its own. Inside a flex row it collapsed to its
   content and the two end labels -- justified apart inside it -- met in the
   middle and read as one string: "PKR 359PKR 58.8bn". */
.avlegend .rampwrap{flex:0 0 210px; width:210px}
.avcredit{position:absolute; right:var(--sp-3); bottom:var(--sp-2);
  font-size:var(--t-micro); color:var(--muted); background:var(--surface);
  padding:2px 7px; border-radius:4px; max-width:46%;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
@media (max-width:900px){
  .avsub{display:none}
  .avopen{padding:0 9px}
}
.atlasgrp{font-size:var(--t-micro); letter-spacing:.08em; text-transform:uppercase; color:var(--muted);
  font-weight:700; margin:18px 0 9px}
.atlasgrp:first-child{margin-top:0}
.atlasgrid{display:grid; grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); gap:12px}
.tile{background:var(--surface); border:1px solid var(--line); border-radius:var(--r); overflow:hidden;
  box-shadow:var(--sh); cursor:pointer; transition:border-color .12s, transform .12s}
.tile:hover{border-color:var(--brand); transform:translateY(-2px)}
.tile[aria-current="true"]{border-color:var(--brand); box-shadow:0 0 0 2px var(--brand-soft), var(--sh)}
.tilecanvas{position:relative; width:100%; aspect-ratio:5/4; background:var(--sea); display:block}
.tilecanvas canvas{width:100%; height:100%; display:block}
.tilebadge{position:absolute; top:7px; right:7px; font-size:var(--t-micro); font-weight:600; padding:2px 7px;
  border-radius:999px; background:color-mix(in srgb, var(--surface) 88%, transparent); color:var(--ink-2)}
/* The badge wears the rung colours every other tier mark in the platform
   wears. It used to restate them as six literals, which is how the atlas came
   to disagree with the chip printed beside it. */
.tilebadge.validated{color:var(--t-validated_pill)}
.tilebadge.unverified{color:var(--t-unverified_pill)}
.tilebadge.implausible{color:var(--t-implausible_pill)}
.tilebadge.calibrated{color:var(--t-calibrated_pill)}
.tilebadge.degenerate{color:var(--t-degenerate_pill)}
.tilebadge.scenario_only{color:var(--t-scenario_only_pill)}
.tilemeta{padding:9px 11px}
/* Two lines, not an ellipsis. 126 of these were cut at exactly the point that
   distinguishes them -- "Monsoon precipitation (JJAS) · 1..." is six different
   layers -- so the clip removed the only part that mattered. */
.tilename{font-size:var(--t-xs); font-weight:600; line-height:1.25; overflow:hidden;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical}
.tilesub{font-size:var(--t-micro); color:var(--muted); font-family:var(--mono); margin-top:2px;
  display:flex; justify-content:space-between; gap:8px; font-variant-numeric:tabular-nums}
.tilesub b{color:var(--ink-2); font-weight:600}

/* focus mode: rails collapse, map goes full-bleed */
body.focus .rail, body.focus .rrail, body.focus .statwrap{display:none}
body.focus .shell{grid-template-columns:minmax(0,1fr); padding:0; gap:0}
/* One column in focus mode, so the centre's explicit grid-column of 2 would
   create an implicit second track and push the map off-screen. */
body.focus .centre{grid-column:1; margin:0}
body.focus .mapcard{border-radius:0; border-left:0; border-right:0; border-bottom:0}

/* ------------------------------------------------------- collapsible rails */
.rail,.rrail{position:relative}
/* 16px wide was under every target-size floor there is, and it was the only
   way to reach the 25 to 30 points of map area that collapsing a rail gives
   back. Measured: the map holds 49-59% of the window with both rails out and
   78-84% with them in. A control worth that much cannot be a hairline.
   24px wide, and the label says what it buys rather than what it does. */
.railtab{position:absolute; top:50%; transform:translateY(-50%); z-index:9;
  width:24px; height:68px; padding:0; cursor:pointer; display:grid; place-items:center;
  background:var(--surface); border:1px solid var(--line); color:var(--muted)}
.railtab svg{width:13px; height:13px}
.railtab:hover{color:var(--brand); border-color:var(--brand)}
.railtab.left{right:-12px; border-radius:0 7px 7px 0}
.railtab.right{left:-12px; border-radius:7px 0 0 7px}
.railpeek{position:fixed; top:50%; transform:translateY(-50%); z-index:40;
  width:24px; height:72px; padding:0; cursor:pointer; display:grid; place-items:center;
  background:var(--surface); border:1px solid var(--line); color:var(--brand);
  box-shadow:var(--sh)}
.railpeek svg{width:14px; height:14px}
.railpeek.left{left:0; border-radius:0 9px 9px 0; border-left:0}
.railpeek.right{right:0; border-radius:9px 0 0 9px; border-right:0}
.railpeek:hover{background:var(--brand-soft)}

/* denser rail internals so a narrower column still reads clearly */
.chead{padding:10px 12px 0}
.cbody{padding:9px 12px 12px; gap:6px}
select{height:33px; font-size:var(--t-xs)}
.fl{font-size:var(--t-micro)}
.hz{padding:5px 0 5px var(--sp-2); gap:var(--sp-2)}
.hz svg{width:17px; height:17px}
.hz span{font-size:var(--t-micro)}
.ab{height:31px}
.ovlist{max-height:210px}
.sitelist{max-height:150px}

/* ══════════════════════════════════════════════════════════════════════════
   There is one identity, so there is no switch.

   This block used to be reached with data-brand="agn" and was already down to
   its last job: set --r to 6px and tighten two title rules. That is not an
   identity — the platform IS the AI Geo Navigators platform and its colours
   come from brand.css in every state, as the old comment here said. What is
   left is unconditional now, --r is a shared token from masthead.css, and the
   toggle is gone: it lived on the console alone, had no effect on the other
   three views, and its only remaining effect was a corner radius.
   ══════════════════════════════════════════════════════════════════════════ */
/* Family only. This block used to add `letter-spacing:normal`, which reached
   .chead (a caps label, which must be tracked out) and .losshead (a figure
   size, which is tracked in) and overrode both -- so those two roles were
   wrong no matter how their own rules were written. A blanket reset that
   spans two roles is not a reset, it is a third role. */
.mprod,
.h2 h2,
.losshead,
.atlastitle,
.srhead,
.chead{font-family:var(--sans)}
.mprod{font-size:var(--t-md); font-weight:600}

/* The identity switch is labelled, not another anonymous glyph — six identical
   icons in a row is how the Atlas tab went unfound. */

/* --------------------------------------------------------------- water --- */
.mc.wide{width:auto; padding:0 9px; gap:6px; display:inline-flex; align-items:center;
  font-family:var(--sans); font-size:var(--t-micro); font-weight:600; line-height:1; letter-spacing:.08em; text-transform:uppercase}
.mc.wide span{white-space:nowrap}
/* The hydrology panel used to float over the map and cover a quarter of it
   while you chose what to put on it. It is a rail card now: the map keeps its
   full width, and the panel scrolls with the rest of the controls. */
/* The rail is a flex column, so the card has to refuse to be squeezed; the
   list inside it carries its own scroll instead of borrowing the parent's. */
.waterpop{display:flex; flex-direction:column; flex:0 0 auto; overflow:hidden}
.wphead{display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:9px 11px; border-bottom:1px solid var(--line);
  font-family:var(--sans); font-size:var(--t-micro); font-weight:700; line-height:1; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-2)}
.wpall{border:1px solid var(--line); background:var(--sunk); color:var(--ink-2);
  border-radius:999px; padding:3px 8px; font-family:var(--sans); font-size:var(--t-micro); font-weight:600; line-height:1; cursor:pointer}
.wpall:hover{color:var(--ink); border-color:var(--faint)}
.wplist{overflow-y:auto; min-height:0; max-height:min(46vh, 380px); padding:4px 0}
.wppresets{display:flex; flex-wrap:wrap; gap:5px; padding:9px 11px;
  border-bottom:1px solid var(--line-2)}
.wpre{border:1px solid var(--line); background:var(--sunk); color:var(--ink-2);
  border-radius:999px; padding:4px 10px; font-family:var(--sans); font-size:var(--t-micro); font-weight:600; line-height:1; cursor:pointer}
.wpre:hover{color:var(--brand); border-color:var(--brand)}
.wpre[aria-pressed="true"]{background:var(--brand); border-color:var(--brand);
  color:var(--brand-ink)}
.wpre:disabled{opacity:.5; cursor:default}
.wpgrp{padding:8px 11px 3px; font-family:var(--sans); font-size:var(--t-micro); font-weight:700; line-height:1; letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted)}
.wl{display:flex; align-items:center; gap:8px; padding:5px 11px; cursor:pointer;
  font-size:var(--t-xs); color:var(--ink)}
.wl:hover{background:var(--sunk)}
.wl input{margin:0; flex:none; accent-color:var(--brand)}
/* Two swatch shapes, because the panel now shows two kinds of mark: a filled
   block for an area layer and the stroke itself for a line layer. */
.wl i.wsw{width:22px; height:9px; border-radius:2px; flex:none;
  border:1px solid transparent}
.wl svg.wsw{flex:none; overflow:visible}
.wl .wn{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.wl .wc{font-family:var(--mono); font-size:var(--t-micro); color:var(--muted); flex:none; font-variant-numeric:tabular-nums}
.wl .wc.samp{color:var(--s2)}
.wl.busy{opacity:.5}
.wpfoot{border-top:1px solid var(--line); padding:7px 11px; font-size:var(--t-micro);
  color:var(--muted); line-height:1.45}

/* ----------------------------------------------------- layout contract --- */
/* Mast row holds brand + platform nav; tools row is a deliberate full-width
   bar. Controls do not wrap into a right-jammed second line. */
.top{min-width:0}
.top > .brand, .toprow-mast > .brand{min-width:0; flex:0 0 auto; overflow:hidden;
  display:flex; align-items:center; gap:10px}
.mprod{font-size:var(--t-md)}
.mtitle{min-width:0; overflow:hidden}
.mnav{flex:0 1 auto}
.searchwrap{flex:1 1 auto; min-width:0; max-width:none; width:100%}
.topacts{display:flex; align-items:center}
.topacts > .viewseg,
.topacts > .toptools-end{flex:none}
.toptools-end > *{flex:none}
.viewseg{flex:none}
.viewseg button{flex:none}
.ic{flex:none}
.natstrip{flex:none}

/* Shed the least load-bearing things first: the national strip, then panel
   labels, then map labels, then the product title. Platform view names stay. */
@media (max-width:1500px){ .natstrip{display:none} }
@media (max-width:1180px){
  .panelseg button span,
  .toprow-tools .viewseg:not(.panelseg):not(.curseg) button span{display:none}
  .viewseg button{padding:6px 11px}
  .toprow{gap:8px; padding-left:10px; padding-right:10px}
}
@media (max-width:1040px){ .mview{display:none} }
@media (max-width:940px){ .mtitle{display:none} }
@media (max-width:860px){
  .toprow-mast{gap:8px}
  .toprow-tools{overflow-x:auto; overflow-y:hidden; scrollbar-width:thin;
    padding-bottom:6px}
}

/* The control strip is a two-column cluster, not a twelve-button tower. One
   column ran 556px from the top of the map and collided with the legend dock
   on any laptop-height window. */
/* One column. `flex-wrap:wrap-reverse` with a max-height was meant to be a
   safety valve, and it fired at every laptop height: twelve buttons at 34px
   need 462px, the valve opened, and the strip came back as the two-column
   cluster it was supposed to stop being. There is no wrap now -- the buttons
   get smaller on a short window instead, which is the trade that keeps it one
   column at every size. */
.mapctl{display:flex; flex-direction:column; gap:0; align-items:stretch;
  flex-wrap:nowrap;
  /* On a short window twelve buttons in one column cannot fit above the
     legend at any button size -- at 647px tall the strip overran it by 81px.
     It scrolls rather than wrapping: the column stays a column, and the
     legend stays uncovered. The scrollbar is hidden because the strip is
     34px wide and a visible one would take a third of it. */
  max-height:calc(100% - 168px); overflow-y:auto; overflow-x:hidden;
  scrollbar-width:none}
.mapctl::-webkit-scrollbar{display:none}
.mc{width:34px; height:34px}
.mc svg{width:16px; height:16px}
.mc.wide{width:34px; padding:0; border-radius:50%}
/* The one labelled control loses its word in the narrow column. The icon and
   the title carry it; a 90px pill would set the width of the whole strip. */
.mc.wide span{display:none}
.mc.sm{width:30px; height:30px}
.mc.sm svg{width:14px; height:14px}

/* Popovers clear the cluster, which is on the right now. */
/* Anchored to the right with the cluster; nothing to override here now. */

@media (max-height:900px){
  /* Twelve buttons in one column need 462px at 34px each. A 900px window
     leaves the map about 630px and the legend wants 60 of them, so the column
     has to come down to 30px to stay clear of it. */
  .mc{height:30px}
  .mc{width:30px; height:30px}
  .mc svg{width:15px; height:15px}
  .mc.wide{width:30px}
  .mc.sm{width:27px; height:27px}
  .mc.sm svg{width:13px; height:13px}
}
@media (max-height:760px){
  .mc{height:28px}
  .mc{width:28px; height:28px}
  .mc svg{width:14px; height:14px}
  .mc.wide{width:28px}
  .mc.sm{width:25px; height:25px}
  .mc{height:28px}
}

/* ------------------------------------------------------------ identify --- */
.identbox{position:absolute; right:12px; bottom:86px; z-index:9; width:246px;
  background:var(--surface); border:1px solid var(--line); border-radius:11px;
  box-shadow:var(--sh-lg), var(--sh); padding:10px 12px 9px;
  max-height:calc(100% - 190px); overflow-y:auto}
.ihead{display:flex; align-items:center; justify-content:space-between; gap:8px}
.ilay{font-family:var(--sans); font-size:var(--t-micro); font-weight:700; line-height:1.3; letter-spacing:.08em; text-transform:uppercase;
  color:var(--brand); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.ix{border:0; background:none; color:var(--muted); font-size:var(--t-lg); line-height:1;
  cursor:pointer; padding:0 2px; flex:none}
.ix:hover{color:var(--ink)}
.ititle{font-size:var(--t-sm); font-weight:600; letter-spacing:normal; margin:2px 0 7px;
  line-height:1.25}
.ir{display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  padding:3px 0; border-top:1px solid var(--line-2); font-size:var(--t-xs)}
.ir span{color:var(--muted); flex:none}
.ir b{font-family:var(--mono); font-size:var(--t-micro); text-align:right; min-width:0;
  overflow:hidden; text-overflow:ellipsis; font-variant-numeric:tabular-nums}
.idim{font-size:var(--t-micro); color:var(--muted); padding:3px 0}
.ifoot{margin-top:7px; padding-top:6px; border-top:1px solid var(--line);
  font-family:var(--mono); font-size:var(--t-micro); color:var(--muted); font-variant-numeric:tabular-nums}

/* ==================================================== exits and grouping ===
 *
 * Everything below was added answering one complaint — "have many tabs but
 * open one and the no back". Every rule here is either a way out of an overlay
 * that had none, or the visible difference between three kinds of control that
 * used to look identical.
 */

/* ------------------------------------------------- header control grouping */
/* Eleven identical 36px circles in one strip, mixing controls that change the
   map, controls that cover it, and links that leave the page. The links are in
   the masthead now; the two kinds that remain are grouped, and a hairline says
   where one kind stops and the next begins. A separator, not a gap: at 9px of
   flex gap the three groups were indistinguishable from the eleven circles. */
.navgrp{display:flex; align-items:center; gap:9px; flex:none}
.navsep{flex:none; width:1px; align-self:stretch; margin:7px 2px;
  background:var(--line); border-radius:1px}
@media (max-width:1460px){ .navgrp{gap:7px} .navsep{margin:6px 0} }

/* ------------------------------------------------------------ atlas exit -- */
/* The atlas had no close control at all. */
.atlasclose{display:inline-flex; align-items:center; gap:7px; flex:none; cursor:pointer;
  height:34px; padding:0 12px; border-radius:9px; border:1px solid var(--line);
  background:var(--sunk); color:var(--ink-2);
  font-family:var(--sans); font-size:var(--t-xs); font-weight:600; line-height:1; white-space:nowrap}
.atlasclose:hover{color:var(--brand); border-color:var(--brand); background:var(--brand-soft)}
.atlasclose svg{width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round}
.atlasclose kbd{font-family:var(--mono); font-size:var(--t-micro); font-weight:600; line-height:1; letter-spacing:normal; padding:3px 5px;
  border-radius:4px; background:var(--surface); border:1px solid var(--line-2);
  color:var(--muted)}

/* ------------------------------------------------------ back to the atlas - */
/* Clicking one of the atlas's 346 cards armed that layer and dropped the
   reader on the map with no route back. This is that route, and it persists —
   it is not a toast — because the reader may spend a while on the layer before
   wanting the next one. It sits over the map rather than in the header so it
   is next to the thing it is about. */
/* Top-left of the map, above the control cluster — which is moved down out of
   its way for as long as the bar is on screen, rather than being covered by
   it. The two both want the same corner and only one of them is temporary. */
.mapcard:has(> .backatlas:not([hidden])) .mapctl{top:54px; max-height:calc(100% - 146px)}
.backatlas{position:absolute; left:12px; top:12px; z-index:11;
  display:inline-flex; align-items:center; gap:6px; cursor:pointer;
  height:32px; padding:0 13px 0 9px; border-radius:999px;
  background:var(--surface); border:1px solid var(--brand); color:var(--brand);
  box-shadow:var(--sh-lg), var(--sh); font-family:var(--sans); font-size:var(--t-xs); font-weight:600; line-height:1; white-space:nowrap}
.backatlas:hover{background:var(--brand); color:var(--brand-ink)}
.backatlas svg{width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:2.2;
  stroke-linecap:round; stroke-linejoin:round}

/* ------------------------------------------------------------ focus exit -- */
/* Focus mode hid the rails and the stat strip and announced itself by changing
   the border colour of one 36px icon. It is a mode with no visible way out,
   which is the definition of a trap. */
/* Bottom centre. The right-hand end of the map dock carries the exposure-layer
   bar and the left-hand end the scale, and both stay in focus mode; the middle
   of that row is the one part of a full-bleed map that is reliably empty. */
.focusexit{position:fixed; z-index:80; left:50%; transform:translateX(-50%);
  bottom:16px; display:none;
  align-items:center; gap:8px; cursor:pointer; height:36px; padding:0 14px;
  border-radius:999px; background:var(--surface); border:1px solid var(--brand);
  color:var(--brand); box-shadow:var(--sh-lg), var(--sh);
  font-family:var(--sans); font-size:var(--t-xs); font-weight:600; line-height:1; white-space:nowrap}
body.focus .focusexit{display:inline-flex}
/* The transform is what centres it, so the hover state must not drop it. */
.focusexit:hover{transform:translateX(-50%)}
.focusexit:hover{background:var(--brand); color:var(--brand-ink)}
.focusexit svg{width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round}
.focusexit kbd{font-family:var(--mono); font-size:var(--t-micro); font-weight:600; line-height:1; letter-spacing:normal; padding:3px 5px;
  border-radius:4px; background:var(--sunk); border:1px solid var(--line-2);
  color:var(--muted)}
.focusexit:hover kbd{background:var(--surface); color:var(--ink-2)}

/* --------------------------------------------------- reconciliation line -- */
/* Four views showed four different national average annual losses, each right
   on its own basis and none of them saying which. The line goes wherever a
   headline figure does, in the reader's eye-line under the number rather than
   in a footnote nobody reaches. */
.reconline{font-size:var(--t-micro); line-height:1.45; color:var(--muted); max-width:66ch}
.reconline b{color:var(--ink-2); font-weight:600}
.stat .reconline{margin-top:3px}
/* On the console it sits directly under the seven figures it qualifies, so it
   is the strip's own footnote and not a paragraph the page happens to carry.
   No margin, the strip's full width rather than 66ch, and worded short enough
   to hold one line down to a 900px window — see the compact form in
   web/reconcile.js. It is never hidden: it is the only place this view says
   why its national loss is not the dashboard's. */
#reconConsole{margin:0; max-width:none; padding:9px 14px;
  background:var(--surface-2); border-top:1px solid var(--line-2);
  font-size:var(--t-xs); line-height:1.45; color:var(--ink-2)}
#stepnote{margin:0; max-width:none; padding:6px 14px;
  background:var(--sunk); border-top:1px solid var(--line-2);
  font-size:var(--t-xs); line-height:1.4; color:var(--ink-2)}

/* ---------------------------------------------------------- atlas gaps ---- */
/* This bundle ships no raster PNGs, so 126 of the atlas's tiles have no image
   to draw. Saying so on the tile is the honest answer; the alternative was 126
   requests the server was always going to answer with a 404. */
.tilegap{position:absolute; inset:0; display:grid; place-items:center; padding:10px;
  text-align:center; font-family:var(--sans); font-size:var(--t-micro); font-weight:600; line-height:1.35; letter-spacing:normal;
  color:var(--muted); background:var(--sunk)}

/* ---------------------------------------------------- text alternatives --- */
/* Present to a screen reader, absent to the eye. Not `display:none` and not
   `visibility:hidden` -- both remove the node from the accessibility tree,
   which is the opposite of what this is for. */
.visually-hidden{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
  border:0;
}

/* --------------------------------------------------------- target sizes --- */
/* WCAG 2.2 puts the floor at 24 CSS pixels on the short axis, and the
   inventory found 31 controls under it: sliders at 18px, the peril
   checkboxes at 15px, a section toggle at 13px. Inline links inside a
   sentence are exempt by the rule itself and are left alone -- padding a
   link out to 24px breaks the line it sits in, which is a worse outcome for
   the same reader.
   A slider keeps its 4px track; it is the HIT AREA that grows, which is what
   the rule is about. */

.slider{height:26px}
.slrow input[type=range]{height:26px}
/* The section toggle sat 13px tall on the strip's edge. Growing the padding
   moved it 3px above the shell and the layout audit caught it. The ink stays
   exactly where it was; an invisible pseudo-element carries the target, which
   is what the rule is about -- a finger lands on an area, not on a glyph. */
/* Hit area for the strip toggle — ink stays where it is; the invisible
   pseudo expands the finger target to 24px. */
.statlabel::after{
  content:""; position:absolute; left:0; right:0; top:50%;
  height:24px; transform:translateY(-50%);
}

/* ------------------------------------------------- controls on the scale --- */
/* Five console controls carried no font-size at all, so they inherited the
   browser's 13.3333px -- a value nowhere on the platform's type scale and,
   because it is fractional, its own visual signature in the control audit.
   Nothing here changes how they look to within half a pixel; it puts them on
   the scale the rest of the platform is held to. */
.ic, .mc, .el, .hz, .slider, .ab, .railtab, .railpeek{font-size:var(--t-sm)}

/* --------------------------------------------------- the breakdown panel --
 *
 * A figure in the stat strip opens into what it is made of. The panel sits
 * under the strip rather than over the map, because it is a caption on the
 * figure above it and a reader comparing the two should not have to hold one
 * of them in memory.
 *
 * The bar is drawn in the administrative grey, not in a data ramp. A ramp step
 * carries magnitude on this platform; a share of a register is a proportion of
 * a whole and borrowing the ramp would say the largest class is the worst one.
 */
.statbreak{margin:0; padding:10px 14px;
  background:var(--surface); border:0; border-top:1px solid var(--line-2);
  border-radius:0; box-shadow:none; font-size:var(--t-xs); max-height:230px; overflow:auto}
.statbreak[hidden]{display:none}
.sbtop{display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
  padding-bottom:5px; border-bottom:1px solid var(--line-2)}
.sbtop b{font-size:var(--t-xs)}
.sbscope{color:var(--muted); font-family:var(--mono); font-size:var(--t-micro)}
.sbcross{margin:6px 0 2px; padding:4px 7px; border-radius:calc(var(--r) - 2px);
  background:var(--line-2); font-size:var(--t-xs)}
.sbcross b{font-family:var(--mono); font-variant-numeric:tabular-nums}
.sbwho{margin:7px 0 3px; font-size:var(--t-micro); font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted)}
.sblist{list-style:none; margin:0; padding:0}
.sblist li{display:grid; grid-template-columns:minmax(74px,1.35fr) minmax(40px,1fr) auto auto;
  align-items:center; gap:8px; padding:1.5px 0}
.sbl{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.sbbar{height:6px; border-radius:3px; background:var(--line-2); overflow:hidden}
.sbbar i{display:block; height:100%; background:var(--muted); opacity:.55}
.sbv,.sbp{font-family:var(--mono); font-variant-numeric:tabular-nums; text-align:right}
.sbv{font-weight:600}
.sbp{color:var(--muted); font-size:var(--t-micro); min-width:44px}
.sbwhy{margin:7px 0 0; color:var(--muted); line-height:1.45; font-size:var(--t-micro)}
.sbcount{margin:4px 0 0; color:var(--faint); font-size:var(--t-micro); line-height:1.4}
/* The affordance. A figure that opens gets a pointer and a marker; one that
   does not is left alone, so the two kinds are told apart before a click. */
.stat.sopen{cursor:pointer}
.stat.sopen:hover,.stat.sopen:focus-visible{background:var(--line-2)}
.stat.sopen .sk::after{content:"›"; margin-left:4px; opacity:.6;
  display:inline-block; transition:transform .12s}
.stat.sopen.on .sk::after{transform:rotate(90deg)}
.stat.sopen.on{background:var(--line-2)}
/* A column the ingest believes is wrong. Not an error state -- the figures
   above are the source's and are shown as the source wrote them -- so it wears
   the warning ink on a wash rather than the red reserved for a flag. */
.sbsus{margin:7px 0 0; padding:5px 8px; border-radius:calc(var(--r) - 2px);
  background:var(--accent-soft); color:var(--accent-ink);
  font-size:var(--t-micro); line-height:1.45}
.sbsus b{font-weight:600}
/* Why a thumbnail is empty, on the thumbnail.
   A peril with no district series has nothing to colour and renders the plain
   country, which is the right picture and reads as a broken one. The mark sits
   over the canvas rather than under it, because the question a reader asks is
   about the picture. Neutral grey: this is an absence of data, not a warning,
   and the colour roles reserve red for a flag. */
.tileblank{position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  padding:3px 8px; border-radius:calc(var(--r) - 3px);
  background:var(--surface); border:1px solid var(--line);
  color:var(--muted); font-size:var(--t-micro); font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; white-space:nowrap; pointer-events:none;
  box-shadow:var(--sh)}
/* The ensemble spread under a climate layer in the stack. Muted: it is a
   caveat on the layer above it, not a second figure competing with it. */
.slspread{margin-top:3px; font-size:var(--t-micro); line-height:1.35; color:var(--muted);
  font-variant-numeric:tabular-nums; cursor:help}
