
/* Instrument Serif, served from this domain rather than from Google.
   Copyright 2022 The Instrument Serif Project Authors, SIL Open Font License 1.1.
   The licence travels with it at /swim/instrument-serif-OFL.txt, as the OFL requires.

   Two files, with Google's own unicode-ranges kept: a visitor reading English
   pages downloads the 15KB latin file and never touches the 8KB extended one.
   font-display:swap so the page is readable in the system serif immediately. */
@font-face{font-family:"Instrument Serif";font-style:normal;font-weight:400;
  font-display:swap;src:url(/swim/instrument-serif-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:"Instrument Serif";font-style:normal;font-weight:400;
  font-display:swap;src:url(/swim/instrument-serif-latin-ext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,
    U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,
    U+2113,U+2C60-2C7F,U+A720-A7FF}

/* Can I Swim? — the whole visual system in one file.
   Tokens first, then structure, then components. Dark mode redefines only the
   tokens, so nothing below has to know which mode it is in. */

:root{
  /* paper and ink — warmed towards sand, so it reads coastal not clinical */
  --bg:#f8f6f1;
  --bg-sunk:#f0ece3;
  --card:#fff;
  --ink:#101a1c;
  --ink-soft:#3c4b4d;
  --dim:#5b6b6d;
  /* Small text on the coloured verdict backgrounds. --dim measures 4.49 on
     --avoid-bg in light and 3.96 on --caution-bg in dark, both under 4.5, and
     it is used at 11.5px. Measured, not guessed. */
  --dim-strong:#45585a;
  --line:#e5e1d7;
  --line-strong:#d5cfc1;

  /* the sea */
  --brand:#0d4650;
  --brand-bright:#11707d;
  --brand-ink:#f4fbfa;

  /* status. These are not picked by eye: each was searched for the widest
     separation still achievable under deuteranopia and protanopia while keeping
     the conventional hue and clearing AA on both white and its own tint. The
     worst pair improves from 0.172 to 0.259 against the set they replace, and
     every one got darker and richer in the process. */
  --ok:#0f5635;        --ok-bg:#def3ea;   --ok-line:#95d8bd;
  --caution:#9e5c00;   --caution-bg:#fdf2e0; --caution-line:#f8d49a;
  --avoid:#680a04;     --avoid-bg:#fae1e0; --avoid-line:#eea09a;
  --advised:#a03113;   --advised-bg:#fdece3; --advised-line:#f0b394;
  --unknown:#4c675e;   --unknown-bg:#d5e2e0; --unknown-line:#aec7c2;

  /* waterfalls are the other half of the site and get their own accent, so the
     two halves feel distinct without leaving the family */
  --fall:#1d5c8a;      --fall-bg:#e2eff8; --fall-line:#a1cdea;

  --focus:#0b5fd6;
  /* The masthead and footer are dark teal, where the blue ring above measures
     1.8:1 — WCAG asks 3:1 of a focus indicator. This one is 5.7:1 on both. */
  --focus-brand:#8cc4ff;

  /* elevation — two steps only, used consistently */
  --lift:0 1px 2px rgba(16,26,28,.05), 0 1px 1px rgba(16,26,28,.04);
  --lift-2:0 2px 4px rgba(16,26,28,.05), 0 12px 28px -12px rgba(16,26,28,.18);

  --r-s:10px; --r-m:14px; --r-l:20px;
  --wrap:1120px; --read:760px;
  --serif:"Instrument Serif", Georgia, "Times New Roman", serif;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}

@media (prefers-color-scheme:dark){
  :root{
    --bg:#0c1214;
    --bg-sunk:#080d0e;
    --card:#141d1f;
    --ink:#e9eeec;
    --ink-soft:#c2cdcb;
    --dim:#93a3a3;
    --dim-strong:#adbcbc;
    --line:#222e30;
    --line-strong:#2d3b3d;

    --brand:#0e3941;
    --brand-bright:#5ec8d3;
    --brand-ink:#eafcff;

    /* Dark mode is measured too, and the measurement says something worth
       recording: on a dark ground, status colour CANNOT carry this signal. Every
       one has to be light enough to read, which compresses exactly the
       differences colour blindness removes — the best natural set scores 0.110
       against light mode's 0.259, and chasing a higher number only produces pale
       mints and washed pinks that read as decoration rather than warning. So
       these are chosen to look right, and the map leans on size, outline and
       dash instead of hue. */
    --ok:#5fe0a4;        --ok-bg:#0e3f2e;   --ok-line:#106947;
    --caution:#f0b429;   --caution-bg:#503d17; --caution-line:#90641a;
    --avoid:#ff8f85;     --avoid-bg:#4a1a17; --avoid-line:#83211a;
    --advised:#ffa877;   --advised-bg:#4a2a17; --advised-line:#8a4d26;
    --unknown:#93a8a3;   --unknown-bg:#2a3b38; --unknown-line:#456159;

    --fall:#57a0d5;      --fall-bg:#153345; --fall-line:#205b81;

    --focus:#8cc4ff;
    --focus-brand:#8cc4ff;
    --lift:0 1px 2px rgba(0,0,0,.4);
    --lift-2:0 2px 4px rgba(0,0,0,.35), 0 16px 32px -14px rgba(0,0,0,.6);
  }
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}
  *{animation-duration:.01ms !important;transition-duration:.01ms !important}}

body{
  margin:0;background:var(--bg);color:var(--ink);
  font:400 16.5px/1.6 var(--sans);
  -webkit-font-smoothing:antialiased;
  padding-bottom:env(safe-area-inset-bottom);
}
img{max-width:100%}
a{color:var(--brand-bright);text-underline-offset:2px}
a:hover{color:var(--brand)}
@media (prefers-color-scheme:dark){a:hover{color:#8fe3ec}}
:focus-visible{outline:3px solid var(--focus);outline-offset:2px;border-radius:6px}
.masthead :focus-visible,.sitefoot :focus-visible{outline-color:var(--focus-brand)}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 20px}
.read{max-width:var(--read);margin:0 auto}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* The first tab stop on every page. Without it a keyboard or screen reader user
   walks the whole masthead before reaching the thing they came for. */
.skip{position:absolute;left:-9999px;top:0;z-index:1200;background:var(--card);color:var(--ink);
  border:1px solid var(--line-strong);border-radius:0 0 10px 0;padding:12px 18px;font-weight:650;
  text-decoration:none;box-shadow:var(--lift-2)}
.skip:focus{left:0}
#content:focus{outline:none}

/* ---------- header ------------------------------------------------------ */
/* The header carries the brand the way the footer does, so the page sits framed
   between two blocks of sea rather than fading off at the top. */
.masthead{
  position:sticky;top:0;z-index:1000;
  /* Solid first, translucent second. A browser too old for color-mix() drops
     that declaration and keeps this one; without it the background fell back to
     transparent while backdrop-filter — supported years earlier — kept working,
     so the header text sat unreadable over whatever scrolled beneath it. */
  background:var(--brand);
  background:color-mix(in srgb, var(--brand) 94%, transparent);
  backdrop-filter:saturate(1.4) blur(12px);
  -webkit-backdrop-filter:saturate(1.4) blur(12px);
  border-bottom:1px solid rgba(255,255,255,.14);
}
.masthead .inner{
  max-width:var(--wrap);margin:0 auto;padding:0 20px;
  display:flex;align-items:center;justify-content:space-between;gap:18px;min-height:62px;
}
.brand{
  display:inline-flex;align-items:center;gap:10px;text-decoration:none;color:#fff;
  font:400 22px/1 var(--serif);letter-spacing:.01em;white-space:nowrap;
}
.brand:hover{color:#fff}
.brand .mark{
  /* The wave on its own, no box behind it. Boxed, it read as an app icon parked
     in a bar; loose, it reads as a mark. The viewBox is cropped to the wave plus
     its stroke, so the glyph fills the space instead of floating in a square of
     nothing. The favicon keeps its box, because an icon needs a shape to sit in.
     Sized here, coloured by the header. */
  width:34px;height:16px;flex:none;display:block;overflow:visible}
.brand .mark path{stroke:#fff}
.masthead nav{display:flex;gap:4px;align-items:center;overflow-x:auto;scrollbar-width:none}
.masthead nav::-webkit-scrollbar{display:none}
.masthead nav a{
  color:#b9d3d5;text-decoration:none;font-size:14.5px;font-weight:500;
  padding:8px 11px;border-radius:999px;white-space:nowrap;
}
.masthead nav a:hover{color:#fff;background:rgba(255,255,255,.10)}

/* Under 600px the four links need 402px beside a 130px wordmark, so they were
   living in a 187px scroller with the scrollbar hidden: three of the site's four
   sections were invisible on every phone made. Give them their own row. The
   sticky search bar below follows via --headh rather than a fixed 62px. */
@media (max-width:599px){
  /* Two rows of links plus the wordmark is about 145px, and holding that at the
     top of an 812px phone for the whole scroll costs more than it gives. The
     header goes with the page and the search bar takes over the sticky job — so
     the sections are all there when you arrive, and the screen is yours after. */
  .masthead{position:static}
  .masthead .inner{
    flex-direction:column;align-items:stretch;justify-content:center;
    gap:0;min-height:0;padding:7px 16px 5px;
  }
  .masthead nav{overflow-x:visible;flex-wrap:wrap;gap:2px;justify-content:flex-start}
  .masthead nav a{padding:9px 10px;font-size:14px}
  .brand{font-size:20px;align-self:flex-start;padding:3px 0 5px}
}
.masthead nav a[aria-current=page]{color:#fff;background:rgba(255,255,255,.17);font-weight:650}
/* The live count beside "Warnings". Filled by core.js wherever the page has
   already loaded the snapshot; hidden otherwise, because a wrong number is
   worse than none. */
.navcount{
  display:inline-block;margin-left:6px;padding:1px 7px;border-radius:999px;
  background:var(--avoid);color:#fff;font-size:12px;font-weight:700;
  font-variant-numeric:tabular-nums;vertical-align:1px;
}
.navcount[hidden]{display:none}

/* Touch. Apple asks 44px, Android 48dp; the pills sat at 40 and the nav at 39.
   Scoped to coarse pointers so the desktop layout keeps its proportions. */
@media (pointer:coarse){
  .btn{min-height:44px}
  .pill{min-height:44px;padding-top:10px;padding-bottom:10px}
  .masthead nav a{min-height:44px;display:inline-flex;align-items:center}
  .brand{min-height:44px}
  /* Leaflet's own stylesheet is injected at runtime, so it lands after this one
     and wins any tie. Naming the control class takes the specificity to 0,3,1
     against its 0,2,1 — no !important needed. */
  .seenpick{min-height:44px}
  /* The footer is a list of links to the site's five sections — navigation, not
     a sentence, so the inline-link exemption does not cover it. */
  .sitefoot li a{display:inline-flex;align-items:center;min-height:44px}
  .leaflet-touch .leaflet-bar a.leaflet-control-zoom-in,
  .leaflet-touch .leaflet-bar a.leaflet-control-zoom-out{
    width:44px;height:44px;line-height:44px;font-size:20px;
  }
}

/* ---------- page furniture ---------------------------------------------- */
main{display:block}
.page{padding:26px 0 70px}
h1{font:400 clamp(30px,4.4vw,44px)/1.08 var(--serif);margin:0 0 8px;letter-spacing:-.005em}
h2{font:650 21px/1.25 var(--sans);margin:34px 0 12px;letter-spacing:-.015em}
h3{font:650 16px/1.3 var(--sans);margin:22px 0 8px}
.sub{color:var(--dim);font-size:16px;margin:0 0 4px;max-width:62ch}
.crumb{font-size:13px;color:var(--dim);margin:0 0 12px}
.crumb a{color:var(--dim);text-decoration:none}
.crumb a:hover{color:var(--brand-bright);text-decoration:underline}

.freshness{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--dim);
  margin-top:10px;background:var(--card);border:1px solid var(--line);
  padding:5px 11px;border-radius:999px;box-shadow:var(--lift)}
.dot{width:7px;height:7px;border-radius:50%;background:var(--ok);flex:none;
  box-shadow:0 0 0 3px color-mix(in srgb, var(--ok) 18%, transparent)}
.dot.stale{background:var(--caution);box-shadow:0 0 0 3px color-mix(in srgb, var(--caution) 18%, transparent)}
.dot.bad{background:var(--avoid);box-shadow:0 0 0 3px color-mix(in srgb, var(--avoid) 18%, transparent)}

/* ---------- controls ----------------------------------------------------- */
button{font:inherit;cursor:pointer}
.btn{
  border:1px solid var(--line-strong);background:var(--card);color:var(--ink);
  border-radius:999px;padding:8px 14px;box-shadow:var(--lift);white-space:nowrap;
  display:inline-flex;align-items:center;gap:8px;font-size:14.5px;font-weight:550;
  transition:border-color .15s, transform .15s, box-shadow .15s;
}
.btn:hover{border-color:var(--brand-bright);box-shadow:var(--lift-2)}
.btn:active{transform:translateY(1px)}
.btn[aria-pressed=true]{background:var(--brand);color:var(--brand-ink);border-color:var(--brand)}

.search{position:sticky;top:var(--headh,62px);z-index:900;background:var(--bg);padding:7px 0;
  box-shadow:0 10px 12px -12px rgba(16,26,28,.28)}
/* Must come after the rule above, not with the rest of the small-screen header:
   same specificity, so whichever is written last wins. On a phone the masthead
   scrolls away and this takes the top itself. */
@media (max-width:599px){.search{top:0}}
/* "Near me" beside the box leaves it 169px wide, and the placeholder needs 247,
   so it read "Search a beach, lake,". Stack them and the box gets the full
   width — the wording is right, so it should be the layout that gives. */
@media (max-width:479px){
  .searchrow{flex-wrap:nowrap;gap:7px}
  .field{flex:1 1 auto;min-width:0}
  .searchrow .btn{flex:0 0 auto;justify-content:center}
}
.searchrow{display:flex;gap:10px}
.field{position:relative;flex:1}
.field input{
  width:100%;padding:9px 14px 9px 38px;font-size:16px;
  border:1px solid var(--line-strong);border-radius:999px;
  background:var(--card);color:var(--ink);box-shadow:var(--lift);
}
.field input:focus{border-color:var(--brand-bright)}
.field svg{position:absolute;left:13px;top:50%;transform:translateY(-50%);opacity:.5}

.summary{display:flex;gap:8px;flex-wrap:wrap;margin:4px 0 16px}
.pill{
  display:inline-flex;align-items:center;gap:8px;padding:8px 14px;border-radius:999px;
  font-size:14px;font-weight:650;background:var(--card);box-shadow:var(--lift);
  border:1px solid var(--line);
}
.pill .n{font-variant-numeric:tabular-nums;font-weight:700}
.pill.avoid{color:var(--avoid);background:var(--avoid-bg);border-color:var(--avoid-line)}
.pill.advised{color:var(--advised);background:var(--advised-bg);border-color:var(--advised-line)}
.pill.caution{color:var(--caution);background:var(--caution-bg);border-color:var(--caution-line)}
.pill.ok{color:var(--ok);background:var(--ok-bg);border-color:var(--ok-line)}
.pill.unknown{color:var(--unknown);background:var(--unknown-bg);border-color:var(--unknown-line)}
.pill[aria-pressed=true]{outline:2px solid currentColor;outline-offset:1px}
/* ...but a keyboard ring must win over the "pressed" outline, on this row as
   well as the area row below. Same specificity trap, same fix. */
.pill[aria-pressed=true]:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
/* The area row sits under the status row and is quieter: status is what you came
   for, area is how you narrow it. */
.regions{margin:-6px 0 16px}
.regions .pill{background:var(--card);color:var(--ink-soft);border-color:var(--line);font-weight:550}
.regions .pill:hover{border-color:var(--brand-bright);color:var(--ink)}
.regions .pill[aria-pressed=true]{background:var(--brand);color:var(--brand-ink);
  border-color:var(--brand);outline:none}
/* ...but not while it has keyboard focus. The rule above outranks :focus-visible,
   and the list re-render deliberately returns focus to this button, so a keyboard
   user was left standing on a control with no ring at all. */
.regions .pill[aria-pressed=true]:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
.regions .pill[aria-pressed=true] .n{color:#fff}

.banner{
  border:1px solid var(--caution-line);border-left:4px solid var(--caution);
  background:var(--caution-bg);color:var(--caution);
  border-radius:var(--r-s);padding:12px 15px;font-size:14.5px;margin:0 0 12px;
}

/* ---------- lists and cards ---------------------------------------------- */
/* Two columns once there is room. A single column across 1,120px gives each card
   a line of text and about nine hundred pixels of nothing, and makes a list of
   seventy-nine warnings much longer to scroll than it needs to be. One column
   below 900px, where two would squeeze the reasons. minmax(0,...) so a long
   beach name cannot push a column wider than its share. */
.list{display:grid;gap:10px}
@media (min-width:900px){
  .list{grid-template-columns:repeat(2, minmax(0, 1fr));gap:12px}
}
/* Cards in a row are the same height, because one carrying a "Not checked" line
   and its neighbour not carrying one left a ragged gap down the middle of the
   page. The grid stretches them; the two rules below make the LINK fill that
   height too, so a taller card has no dead strip along the bottom that looks
   clickable and is not. */
.beach{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-m);
  box-shadow:var(--lift);transition:border-color .15s, box-shadow .15s, transform .15s;
  display:flex;flex-direction:column;
}
.beach>h3.bh{flex:1;display:flex}
a.beach{text-decoration:none;color:inherit}
.beach:hover{border-color:var(--line-strong);box-shadow:var(--lift-2)}
h3.bh{margin:0;font:inherit}
.beach a.head,.beach button.head{
  width:100%;flex:1;display:flex;gap:14px;align-items:flex-start;text-align:left;
  padding:16px;background:none;border:0;color:inherit;border-radius:var(--r-m);text-decoration:none;
}
/* The status mark on a list card. Small on purpose: it repeats twenty-five times
   down the page and the words beside it are what people actually read, so it is
   a marker rather than a headline. The one on a beach page is the answer to the
   question and stays big — see .verdictcard .mark below. */
.mark{
  flex:none;width:26px;height:26px;border-radius:8px;display:grid;place-items:center;
  font-weight:700;font-size:13px;border:1px solid transparent;
}
.mark.ok{background:var(--ok-bg);color:var(--ok);border-color:var(--ok-line)}
.mark.caution{background:var(--caution-bg);color:var(--caution);border-color:var(--caution-line)}
.mark.avoid{background:var(--avoid-bg);color:var(--avoid);border-color:var(--avoid-line)}
.mark.advised{background:var(--advised-bg);color:var(--advised);border-color:var(--advised-line)}
.mark.unknown{background:var(--unknown-bg);color:var(--unknown);border-color:var(--unknown-line)}
.bmain{flex:1;min-width:0}
.bname{font-weight:650;font-size:17.5px;letter-spacing:-.012em;display:block}
.bwhere{color:var(--dim);font-size:13px;margin-top:2px}
.bverdict{font-size:14.5px;margin-top:6px;font-weight:650}
.bverdict.ok{color:var(--ok)} .bverdict.caution{color:var(--caution)}
.bverdict.avoid{color:var(--avoid)} .bverdict.advised{color:var(--advised)}
.bverdict.unknown{color:var(--unknown)}
.breason{color:var(--ink-soft);font-size:14.5px;margin-top:3px}
.bgap{color:var(--caution);font-size:13px;margin-top:4px}
.bdist{flex:none;color:var(--dim);font-size:13px;font-variant-numeric:tabular-nums;padding-top:4px}

/* ---------- the verdict, on a single place -------------------------------- */
/* The heading this section never had. The conditions block below it says "Sea,
   wind and tide today" and reads as one thing; this one, which is the reason the
   page exists, simply started with a card and left two sentences loose under it. */
#conditions,.sect{background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-l);box-shadow:var(--lift-2);padding:20px 22px;margin:16px 0}
#conditions>h2,.sect>h2{margin-top:0}
.sect>.sub:first-of-type{margin-top:0}
/* A section that renders nothing must not leave an empty card behind. */
.sect:empty{display:none}
@media (max-width:520px){ #conditions,.sect{padding:14px 15px} }
.scopebox{margin:16px 0 0;padding:12px 14px;background:var(--bg-sunk);
  border:1px solid var(--line);border-radius:var(--r-m)}
.scopebox h3{margin:0 0 6px;font:650 12px/1.3 var(--sans);text-transform:uppercase;
  letter-spacing:.08em;color:var(--dim)}
.scopebox .verdictscope{margin:0;background:none;border:0;padding:0}
.scopebox .nextbest{margin:8px 0 0}
.verdictcard{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);
  box-shadow:var(--lift-2);padding:20px 22px;margin:16px 0;
}
.verdictcard .big{display:flex;gap:16px;align-items:center}
.verdictcard .mark{width:58px;height:58px;font-size:26px;border-radius:16px}
.verdictcard .word{font:400 clamp(24px,3.4vw,32px)/1.05 var(--serif);letter-spacing:-.01em}
.verdictcard .word.ok{color:var(--ok)} .verdictcard .word.caution{color:var(--caution)}
.verdictcard .word.avoid{color:var(--avoid)} .verdictcard .word.advised{color:var(--advised)}
.verdictcard .word.unknown{color:var(--unknown)}
.verdictcard .when{color:var(--dim);font-size:13.5px;margin-top:5px}

.why{list-style:none;margin:20px 0 0;padding:0;display:flex;flex-direction:column;gap:12px}
.why li{display:flex;gap:12px;align-items:flex-start}
.why .ic{flex:none;width:24px;height:24px;border-radius:8px;display:grid;place-items:center;
  font-size:12px;margin-top:1px;font-weight:700}
.why .txt{flex:1}
.why .src{display:block;color:var(--dim);font-size:12.5px;margin-top:2px}
.subhead{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;
  color:var(--dim);margin:22px 0 8px}
.checks{list-style:none;margin:0;padding:0;font-size:14.5px}
.checks li{display:flex;gap:10px;padding:4px 0}
.checks .t{color:var(--ok);font-weight:700;flex:none}
.checks .g{color:var(--caution);font-weight:700;flex:none}

.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));gap:10px;margin-top:16px}
.fact{background:var(--bg-sunk);border:1px solid var(--line);border-radius:var(--r-s);padding:11px 13px}
.fact dt{color:var(--dim);font-size:12.5px;margin:0 0 3px}
.fact dd{margin:0;font-weight:650;font-size:15.5px}

details.more{margin-top:16px;font-size:14.5px}
details.more summary{cursor:pointer;color:var(--brand-bright);font-weight:600}

/* The two things you can do with this page, side by side as pills rather than
   stacked as links. One was static markup and one is built by the script, which
   is why they looked like unrelated leftovers at the bottom of the section. */
/* Said where it happened. This used to go into the banner stack at the top of
   the page, next to notices about data feeds. */
.nearnote{margin:10px 0 0;padding:9px 12px;border-radius:var(--r-s);
  background:var(--caution-bg);border:1px solid var(--caution-line);
  color:var(--ink);font-size:13px;line-height:1.45}
.nearnote[hidden]{display:none!important}

.pillrow{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-start;margin-top:12px}
.pillrow > *{flex:1 1 240px;margin-top:0}
.pillrow details.more>summary{width:100%;justify-content:center}
.pillrow details.more>summary,.pillrow #reports details.more>summary{
  display:inline-flex;align-items:center;gap:8px;padding:10px 16px;min-height:44px;
  border-radius:999px;font-size:14px;font-weight:650;background:var(--card);
  box-shadow:var(--lift);border:1px solid var(--line);color:var(--ink-soft);
  list-style:none;box-sizing:border-box}
.pillrow summary::-webkit-details-marker{display:none}
.pillrow details.more>summary:hover{border-color:var(--brand-bright);color:var(--ink)}
.pillrow details.more>summary::before{content:"+";color:var(--dim);font-weight:700}
.pillrow details.more[open]>summary::before{content:"2"}
/* Opened, it needs the whole row: a form or an embed box does not belong in a
   column 220px wide beside a pill. */
.pillrow details.more[open]{flex-basis:100%}
.pillrow #reports{flex:1 1 240px}
.pillrow #reports>details.more{width:100%}

table{width:100%;border-collapse:collapse;margin-top:10px;font-size:13.5px}
th,td{text-align:left;padding:8px 10px;border-bottom:1px solid var(--line)}
th{color:var(--dim);font-weight:600;font-size:12.5px;text-transform:uppercase;letter-spacing:.05em}
td.st{white-space:nowrap;font-weight:650}
td.st.now{color:var(--avoid)} td.st.recent{color:var(--caution)}
td.st.off{color:var(--caution)} td.st.clear{color:var(--ok)}

/* ---------- media -------------------------------------------------------- */
figure.photo{margin:16px 0 6px}
figure.photo img{width:100%;height:auto;max-height:440px;object-fit:cover;
  border-radius:var(--r-m);border:1px solid var(--line);display:block;background:var(--bg-sunk)}
figure.photo figcaption{color:var(--dim);font-size:12.5px;margin-top:8px}

.beachmap{height:360px;border-radius:var(--r-m);border:1px solid var(--line);margin:12px 0 8px;
  background:var(--bg-sunk);display:grid;place-items:center;color:var(--dim);font-size:14px;
  position:relative;z-index:0;isolation:isolate}
.beachmap.failed{display:none}
.maphint{display:none;color:var(--dim);font-size:13px;margin:0 0 8px}
#map{height:clamp(460px, 78vh, 820px);border-radius:var(--r-m);border:1px solid var(--line);
  margin-bottom:10px;background:var(--bg-sunk);position:relative;z-index:0;isolation:isolate}
.bigmap{height:clamp(520px, 82vh, 900px);border-radius:var(--r-m);border:1px solid var(--line);
  margin:14px 0 8px;background:var(--bg-sunk);display:grid;place-items:center;color:var(--dim);
  position:relative;z-index:0;isolation:isolate}
.legend{gap:14px;flex-wrap:wrap;font-size:12.5px;color:var(--dim);margin:0 0 16px;display:none}
.leaflet-container{border-radius:calc(var(--r-m) - 1px);font:inherit}
/* A map is worth most of a desktop screen and rather less of a phone's, where it
   also swallows the scroll: Leaflet takes the touch, so a finger landing inside
   pans the map instead of moving the page. Half the screen leaves room to get
   past it. */
@media (max-width:599px){
  #map{height:clamp(300px, 52vh, 520px)}
  .bigmap{height:clamp(340px, 58vh, 560px)}
  /* The outfall map on every beach and waterfall page. Leaflet claims the touch
     here too, so it gets the same treatment as the other two rather than being
     the one map left filling half a phone with no way past it. */
  .beachmap{height:clamp(220px, 34vh, 320px)}
}

/* ---------- tiles and prose ---------------------------------------------- */
.prose{max-width:66ch}
.prose p{margin:12px 0}
.prose ul{margin:12px 0;padding-left:22px}
.prose li{margin:6px 0}
/* 224px minimum put one waterfall per row on a phone, which for a list of 676
   is a great deal of scrolling to see very little. 150px fits two on the
   narrowest screen and four or five on a laptop. */
.tiles{display:flex;flex-wrap:wrap;gap:10px;margin-top:14px;justify-content:center}
.tiles .tile{flex:1 1 300px}
[hidden]{display:none!important}
/* The flow, on the tile. A waterfall in spate is the one where people are hurt,
   because it is at its most impressive on exactly the day it is most dangerous,
   so it has to be visible in the list rather than three clicks in. The mark sits
   in the corner so the tile stays two lines and a phone still fits plenty. */
.tile{position:relative}
.fmark{position:absolute;top:9px;right:9px;width:19px;height:19px;border-radius:6px;
  display:flex;align-items:center;justify-content:center;font-size:11px;
  font-weight:700;line-height:1}
.fmark.ok{background:var(--ok-bg);color:var(--ok);border:1px solid var(--ok-line)}
.fmark.caution{background:var(--caution-bg);color:var(--caution);border:1px solid var(--caution-line)}
.fmark.avoid{background:var(--avoid-bg);color:var(--avoid);border:1px solid var(--avoid-line)}
.fmark.unknown{background:var(--bg-sunk);color:var(--dim);border:1px solid var(--line)}
.tile>b{padding-right:24px;display:block}
.fflow{display:block;font-size:11.5px;margin-top:2px;font-weight:650;color:var(--dim)}
.fflow.avoid{color:var(--avoid)} .fflow.caution{color:var(--caution)}
.fflow.ok{color:var(--ok)} .fflow.unknown{color:var(--dim);font-weight:400}
.fdist{display:block;font-size:11.5px;margin-top:3px;color:var(--brand-bright);
  font-weight:650;font-variant-numeric:tabular-nums}
.fwx{display:block;font-size:11px;margin-top:3px;color:var(--ink);
  background:var(--caution-bg);border:1px solid var(--caution-line);
  border-radius:var(--r-s);padding:2px 6px}
.tile{background:var(--card);border:1px solid var(--line);border-radius:var(--r-m);
  padding:11px 12px;text-decoration:none;color:inherit;box-shadow:var(--lift);display:block;
  transition:border-color .15s, box-shadow .15s}
@media (min-width:700px){.tile{padding:14px 15px}}
.tile:hover{border-color:var(--brand-bright);box-shadow:var(--lift-2)}

/* The waterfall filter.
   674 waterfalls listed under five country headings and nothing else was not a
   list anyone could use: seven of them are called High Force, and the only way
   to reach one in Kerry was to scroll past everything in England and Scotland.
   Each waterfall now carries its county, which both tells the seven apart and
   gives the list something to filter on.

   Progressive enhancement: the panel is hidden in the markup and shown by
   script, so without JavaScript the full list is still there, just unfiltered. */
/* ONE FILTER PANEL, on all three list pages.
   The swimming and surfing pages had a bordered search row in the static HTML
   and the waterfalls page built its own bordered card in JavaScript, with its
   own class family, its own input styling and no magnifier. Same job, two
   appearances, because they were written months apart. Now one. */
.filters{margin:14px 0 4px;padding:12px;background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-m);box-shadow:var(--lift)}
.filters .search{position:static;padding:0;background:none;z-index:auto}
.filters .summary{margin:10px 0 0}
.filters .areawrap{margin-top:10px}
.filters .ffbar{margin-top:10px}
.ffpills{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.ffpill{font:inherit;font-size:13px;padding:5px 11px;border-radius:999px;cursor:pointer;
  border:1px solid var(--line);background:var(--bg);color:var(--ink)}
.ffpill[aria-pressed=true]{background:var(--brand);border-color:var(--brand);color:#fff}
.ffpill:focus-visible{outline:2px solid var(--brand-bright);outline-offset:2px}
.ffareas{margin-top:10px}
.ffareas>summary{cursor:pointer;font-size:13.5px;font-weight:600;padding:4px 0;
  list-style:none}
.ffareas>summary::-webkit-details-marker{display:none}
.ffareas>summary::before{content:"▸ ";color:var(--dim)}
.ffareas[open]>summary::before{content:"▾ "}
.ffalist{max-height:238px;overflow-y:auto;margin-top:8px;padding:2px;
  display:grid;grid-template-columns:1fr 1fr;gap:2px 10px}
@media (min-width:700px){.ffalist{grid-template-columns:repeat(3,1fr)}}
.ffalist label{display:flex;align-items:center;gap:7px;font-size:13px;padding:4px 2px;
  cursor:pointer;line-height:1.25}
.ffalist input{margin:0;flex:none}
.ffalist .n{color:var(--dim);font-size:11.5px;margin-left:auto;padding-left:6px}
.ffbar{display:flex;align-items:center;gap:12px;margin-top:10px;flex-wrap:wrap}
.ffcount{font-size:13px;color:var(--dim);margin:0}
.ffclear{font:inherit;font-size:13px;background:none;border:0;padding:0;cursor:pointer;
  color:var(--brand-bright);text-decoration:underline}
.ffclear[hidden]{display:none}
.ffnote{font-size:12px;color:var(--dim);margin:7px 0 0}
.ffnone{margin:18px 0;padding:14px;border:1px dashed var(--line);border-radius:var(--r-m);
  color:var(--dim);font-size:14px}
.tile .area{display:block;font-size:11.5px;color:var(--dim);margin-top:2px}

/* The week ahead, and how cold the water is.
   Seven columns that scroll sideways on a narrow phone rather than being
   squeezed to nothing. */
.week{display:grid;grid-template-columns:repeat(7,minmax(64px,1fr));gap:6px;
  margin:12px 0 0;overflow-x:auto;padding-bottom:4px}
.wday{background:var(--card);border:1px solid var(--line);border-radius:var(--r-s);
  padding:9px 4px;text-align:center;min-width:0}
.wday.today{border-color:var(--brand-bright);box-shadow:inset 0 0 0 1px var(--brand-bright)}
.wday .wsym{color:var(--dim)}
.wday.k-sun .wsym,.wday.k-part .wsym{color:#e08c00}
.wday.k-rain .wsym{color:#1f78b4}
.wday.k-snow .wsym{color:#3f9ad1}
.wday.k-storm .wsym{color:#c2410c}
.wday.k-sun{background:linear-gradient(180deg,#ffeec2,#fffaf0 70%);border-color:#f0d089}
.wday.k-part{background:linear-gradient(180deg,#fff0d4,#fffbf3 70%);border-color:#f2d9a8}
.wday.k-rain{background:linear-gradient(180deg,#d4e9f7,#f2f9fd 70%);border-color:#a8cfe8}
.wday.k-snow{background:linear-gradient(180deg,#dcecf8,#f4fafd 70%);border-color:#b3d6ea}
.wday.k-storm{background:linear-gradient(180deg,#fbdcc8,#fef6f1 70%);border-color:#f0b795}
.wday .whi{color:var(--ink);font-weight:650}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .wday.k-sun{background:linear-gradient(180deg,#54401a,var(--card) 70%);border-color:#7a5d24}
  :root:not([data-theme="light"]) .wday.k-part{background:linear-gradient(180deg,#4a3f22,var(--card) 70%);border-color:#6d5c33}
  :root:not([data-theme="light"]) .wday.k-rain{background:linear-gradient(180deg,#1b3d52,var(--card) 70%);border-color:#2a5d7d}
  :root:not([data-theme="light"]) .wday.k-snow{background:linear-gradient(180deg,#204152,var(--card) 70%);border-color:#316179}
  :root:not([data-theme="light"]) .wday.k-storm{background:linear-gradient(180deg,#4d2716,var(--card) 70%);border-color:#7a3c22}
  :root:not([data-theme="light"]) .wday.k-sun .wsym,
  :root:not([data-theme="light"]) .wday.k-part .wsym{color:#e8b45c}
  :root:not([data-theme="light"]) .wday.k-rain .wsym{color:#7fb6d6}
  :root:not([data-theme="light"]) .wday.k-snow .wsym{color:#9cc4dc}
  :root:not([data-theme="light"]) .wday.k-storm .wsym{color:#e08a69}
}
:root[data-theme="dark"] .wday.k-sun{background:linear-gradient(180deg,#54401a,var(--card) 70%);border-color:#7a5d24}
:root[data-theme="dark"] .wday.k-part{background:linear-gradient(180deg,#4a3f22,var(--card) 70%);border-color:#6d5c33}
:root[data-theme="dark"] .wday.k-rain{background:linear-gradient(180deg,#1b3d52,var(--card) 70%);border-color:#2a5d7d}
:root[data-theme="dark"] .wday.k-snow{background:linear-gradient(180deg,#204152,var(--card) 70%);border-color:#316179}
:root[data-theme="dark"] .wday.k-storm{background:linear-gradient(180deg,#4d2716,var(--card) 70%);border-color:#7a3c22}
:root[data-theme="dark"] .wday.k-sun .wsym,
:root[data-theme="dark"] .wday.k-part .wsym{color:#e8b45c}
:root[data-theme="dark"] .wday.k-rain .wsym{color:#7fb6d6}
:root[data-theme="dark"] .wday.k-snow .wsym{color:#9cc4dc}
:root[data-theme="dark"] .wday.k-storm .wsym{color:#e08a69}
.wday b{display:block;font-size:12px;font-weight:650;letter-spacing:.01em}
.wday .wsym{display:block;font-size:21px;line-height:1.25;margin:2px 0}
.wday .whi{display:block;font-size:14px;font-weight:600}
.wday .wlo{display:block;font-size:12px;color:var(--dim)}
.wday .wrain{display:block;font-size:11px;color:var(--dim);margin-top:3px}
.wday .wrain.wet{color:var(--advised);font-weight:600}
/* ---------- the conditions panel ----------------------------------------- */
/* Built from the SAME pill as the verdict card above it, .facts and .fact, so
   the two blocks read as one page. The old version was a flex container of
   full-width spans, which rendered as a flat list of bold-lead sentences that
   you had to read to navigate. */
.condgrid{margin-top:10px;
  grid-template-columns:repeat(auto-fit,minmax(146px,1fr))}
.fact.cond dd{font-size:19px;letter-spacing:-.01em}
.fact.cond .condsub{margin-top:3px;color:var(--dim);font-size:12px;line-height:1.35}

/* Warnings are not readings and must not look like one. Full width, under the
   pills, carrying the weight they had before this was rebuilt. */
.condwarn{margin-top:8px;padding:9px 11px;border-radius:var(--r-s);
  background:var(--caution-bg);border:1px solid var(--caution-line);
  color:var(--ink);font-size:12.5px;line-height:1.45}
.condwarn b{font-weight:700}
/* The offshore wind box stays the loudest thing in the section. It is the only
   warning here describing something a swimmer cannot see and would otherwise
   read as a good day, and it is why the beach-facing data was built at all. */
.condwarn.offshore{background:var(--advised-bg);border-color:var(--advised-line);
  font-size:13px;line-height:1.5;margin-top:10px}
.condwarn.offshore b{display:block;margin-bottom:2px}

/* Three days of tide in three lines. A row per day, turns inline, so twelve
   times cost about ninety pixels rather than twelve rows. */
.tidedays{margin-top:14px}
.tidedays .subhead{margin:0 0 6px}
.tideday{display:flex;gap:10px;align-items:baseline;padding:5px 0;
  border-top:1px solid var(--line)}
.tideday > b{flex:0 0 46px;font-weight:650;font-size:13px}
.tidetimes{display:flex;flex-wrap:wrap;gap:4px 12px;font-size:13px;
  font-variant-numeric:tabular-nums}
.tt i{font-style:normal;color:var(--dim-strong);font-size:11.5px;
  text-transform:uppercase;letter-spacing:.04em;margin-right:2px}
.tt.past{color:var(--dim)}
.tt.past i{opacity:.7}
.tidenote2{margin:8px 0 0;font-size:11.5px;line-height:1.4;color:var(--dim)}

/* Space kept for the live readings, so nothing below them moves when they
   arrive. This was the whole of the mobile CLS score: 0.313 on a beach page,
   because #conditions and #weekwrap are empty in the HTML and #verdict grows
   from 293px to over 600.

   Every number here is the SMALLEST filled height measured across a coastal
   beach, an estuary, an inland lake and one with no marine grid point nearby
   (Ainsdale, Crackington Haven, Blyth South, Coniston), at 375px and at
   1100px. Smallest, so the reservation can never leave a gap under a loaded
   page — it can only be too small, never too big. Re-measure if the panels
   gain a row. */
#verdict{min-height:460px}
#conditions{min-height:260px}
#weekwrap{min-height:246px}
@media (max-width:560px){
  #verdict{min-height:611px}
  #conditions{min-height:329px}
  #weekwrap{min-height:254px}
}
/* The caveats that will not fit in a 162px pill. Quiet, because they qualify a
   reading rather than warning about one, but never absent: both of these went
   missing when the readings became pills and the weekly facts check is what
   noticed. */
.condnote{margin:8px 0 0;font-size:11.5px;line-height:1.45;color:var(--dim)}

@media (max-width:560px){
  .condgrid .fact:last-child:nth-child(odd){grid-column:1 / -1}
}
@media (max-width:420px){
  .fact.cond dd{font-size:17.5px}
  .tideday > b{flex-basis:40px;font-size:12.5px}
  .tidetimes{gap:3px 9px;font-size:12.5px}
}

.bsurf{display:block;font-size:13px;color:var(--ink-soft);margin-top:3px;line-height:1.45}
.bsurf.none{color:var(--dim);font-style:normal}
.verdictscope{font-size:13px;color:var(--ink-soft);margin:10px 0 0;padding:9px 12px;
  background:var(--bg-sunk);border-radius:var(--r-s);line-height:1.45}
.prose.safety{background:var(--bg-sunk);border-radius:var(--r-m);padding:14px 16px;
  border:1px solid var(--line)}
.prose.safety p{margin:0 0 10px}
.prose.safety p:last-child{margin-bottom:0;font-size:13.5px;color:var(--dim)}
.leaflet-popup-content .ptide{color:var(--ink-soft);font-size:12.5px}
.weeknote{font-size:12.5px;color:var(--dim);margin:10px 0 0}

/* The classification year by year, oldest on the left. Colour follows the four
   classes rather than the daily verdict palette, because a classification is a
   different thing from today's answer and must not be mistaken for it. */
.clshist{display:flex;gap:6px;margin:12px 0 0;flex-wrap:wrap}
.cy{flex:1 1 84px;min-width:78px;padding:9px 8px;border-radius:var(--r-s);
  text-align:center;border:1px solid var(--line);background:var(--bg-sunk)}
.cy b{display:block;font-size:12px;color:var(--dim-strong);font-weight:600}
.cy span{display:block;font-size:13.5px;font-weight:650;margin-top:2px}
.cy-excellent{background:var(--ok-bg);border-color:var(--ok-line)}
.cy-good{background:var(--ok-bg);border-color:var(--ok-line);opacity:.82}
.cy-sufficient{background:var(--caution-bg);border-color:var(--caution-line)}
.cy-poor{background:var(--avoid-bg);border-color:var(--avoid-line)}

/* The embed offer on a beach page. */
.badgeprev{margin:10px 0}
.embedbox{width:100%;box-sizing:border-box;font:12.5px/1.5 ui-monospace,SFMono-Regular,
  Menlo,Consolas,monospace;padding:10px 11px;border:1px solid var(--line);
  border-radius:var(--r-s);background:var(--bg-sunk);color:var(--ink);resize:vertical}
.embedbox:focus-visible{outline:2px solid var(--brand-bright);outline-offset:1px}
.nextbest{margin:12px 0 0;padding:12px 14px;border-radius:var(--r-s);
  background:var(--ok-bg);border:1px solid var(--ok-line);font-size:14.5px}
.nextbest a{font-weight:650}

/* The fourteen area filters are 356px of the homepage, which on a phone pushed
   the first actual result to 1060px down an 812px screen: you had to scroll past
   the whole of the furniture to see a single beach. Folded away on narrow
   screens, left open where there is room for it. Marked open in the markup and
   closed by script, so with no JavaScript nothing is hidden. */
.areawrap{margin:0}
.areawrap>summary{cursor:pointer;font-size:13.5px;font-weight:600;padding:7px 0;
  color:var(--ink-soft);list-style:none;display:inline-flex;align-items:center;gap:6px}
.areawrap>summary::-webkit-details-marker{display:none}
.areawrap>summary::before{content:"▸";color:var(--dim);font-size:11px}
.areawrap[open]>summary::before{content:"▾"}
@media (min-width:700px){ .areawrap>summary{display:none} }
.btn.primary{background:var(--brand);border-color:var(--brand);color:#fff;
  font-weight:650}
.btn.primary svg{flex:none}
.btn.primary[aria-pressed=true]{background:var(--bg);color:var(--ink);
  border-color:var(--line-strong)}


/* Fourteen days of discharges, one cell a day.
   Three states, not two. A day the collector did not run is drawn hollow, not
   clear: nobody checked is not the same as nothing happened, and colouring it
   green would be inventing good news about sewage. */
.strip{display:flex;gap:3px;margin:10px 0 6px;max-width:520px}
.strip .d{flex:1 1 0;min-width:0;height:34px;border-radius:4px;position:relative;
  background:var(--ok-bg);border:1px solid var(--ok-line)}
.strip .d.spill{background:var(--avoid-bg);border-color:var(--avoid-line)}
.strip .d.none{background:transparent;border:1px dashed var(--line)}
.strip .d span{position:absolute;left:0;right:0;bottom:-16px;text-align:center;
  font-size:9.5px;color:var(--dim);line-height:1}
.stripnote{font-size:13px;color:var(--dim);margin:22px 0 0}
.striplegend{display:flex;gap:14px;flex-wrap:wrap;font-size:12px;color:var(--dim);
  margin:20px 0 0;align-items:center}
.striplegend i{display:inline-block;width:12px;height:12px;border-radius:3px;
  margin-right:5px;vertical-align:-2px}
.striplegend .k{display:inline-flex;align-items:center}
.tile b{display:block;font-size:14.5px;font-weight:650;letter-spacing:-.01em;line-height:1.25}
@media (min-width:700px){.tile b{font-size:15.5px}}
.tile span{color:var(--dim);font-size:13px}
.empty{text-align:center;color:var(--dim);padding:48px 10px;line-height:1.7}
/* A button that has to read as a link, because it belongs mid-sentence. */
.linkish{background:none;border:0;padding:0;font:inherit;color:var(--brand-bright);
  text-decoration:underline;cursor:pointer}
.linkish:hover{color:var(--brand)}
.more-btn{margin:18px auto 0;display:block}

/* The map beside what discharges near it, rather than a full width band with
   nothing next to it. Below 900px it stacks, text first and map second, which is
   the source order, so nothing has to be reordered for a phone. */
.mapsplit{display:grid;grid-template-columns:1fr;gap:14px;margin-top:10px}
.mapsplit .beachmap{margin-top:0}
.mapsplit #spillhist{margin-top:14px}
.mapsplit h3{font:650 15px/1.3 var(--sans);margin:0 0 4px}
@media (min-width:900px){
  .mapsplit{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:22px;align-items:start}
  .mapsplit .beachmap{height:100%;min-height:320px}
}

/* ---------- footer ------------------------------------------------------- */
.sitefoot{background:var(--brand);border-top:1px solid var(--brand);margin-top:56px;
  padding:48px 0 32px;color:#a9c6c9;font-size:14px}
.footgrid{max-width:var(--wrap);margin:0 auto;padding:0 20px;
  display:grid;grid-template-columns:1.5fr 1fr 1fr;gap:34px}
@media (max-width:720px){
  .footgrid{grid-template-columns:1fr 1fr;gap:22px 18px}
  .footgrid > :first-child{grid-column:1 / -1}
  .footnote{display:none}
  .sitefoot{padding:30px 0 22px}
  .sitefoot li{margin:2px 0}
  .footbar{margin-top:20px}
  .stat{gap:10px;font-size:12.5px}
}
.sitefoot h2{font:650 12px/1.3 var(--sans);text-transform:uppercase;letter-spacing:.08em;
  color:#e8f4f4;margin:0 0 10px}
.sitefoot ul{list-style:none;margin:0;padding:0}
.sitefoot li{margin:6px 0}
.sitefoot a{color:#d6e7e8;text-decoration:none}
.sitefoot a:hover{color:#fff;text-decoration:underline}
.footbrand{font:400 22px/1.2 var(--serif);color:#fff;margin:0 0 8px;
  display:inline-flex;align-items:center;gap:9px}
.footnote{max-width:44ch;margin:0 0 12px}
.footbar{max-width:var(--wrap);margin:28px auto 0;padding:20px 20px 0;
  border-top:1px solid rgba(255,255,255,.16);font-size:12.5px;line-height:1.6}
.footbar strong{color:#fff}
.footbar a{text-decoration:underline;text-underline-offset:2px}
.stat{display:flex;gap:18px;flex-wrap:wrap;margin:10px 0 0;font-size:13px}
.stat b{color:#fff;font-weight:650;font-variant-numeric:tabular-nums}
