
:root{
  /* Every colour, light: the kit's palette and what is derived from it, in
     web/brand.js. The dials' scale ends are named there by what they mean
     rather than by hue, so the dark theme re-picks them without touching
     panel.js. */
  
  --bg:#F5F2E9; --surface:#FDFBF6; --wash:#ECE8DD; --sage:#DCE5DA;
  --ink:#202722; --muted:#586059; --rule:#D4D6CE; --rule-strong:#BFC5BB; --rule-ink:#202722;
  --accent:#34594B; --accent-ink:#F5F2E9; --focus:#875A20;
  --happy:#34594B; --happy-soft:#DCE5DA; --warn:#9A4630;
  --codebg:#E9E6DB; --track:#E4E0D4;
  --forest:#34594B; --ochre:#D7B575; --clay:#B77861;
  --hl-desc:#F0DEB4; --hl-class:#D5E2DD; --hl-quote:#E7E2D5;
  --grief:#C6D4D9; --neutralc:#E9E5DA; --joy:#EBDBAE;
  --grief-ink:#3F5F6B; --joy-ink:#7A5A1C;
  --mood-low:#B77861; --mood-mid:#E4DFCF; --mood-high:#6F9A83;
  --ok:#D0DCCF; --mid:#E8D8B0; --hot:#E0BDAD;
  --pole-cold:#A9BFC8; --pole-warm:#D7B575; --pole-left:#9DB6C2;
  --pole-right:#D9A48E; --pole-hot:#B77861;
  --lift:0 1px 2px rgba(32,39,34,.05);
  --lift-hover:0 2px 10px rgba(32,39,34,.09);
  --maxw:44rem; --maxw-wide:78rem; --maxw-article:64rem; --maxw-band:104rem;
  /* The page's side gutter. A phone gives up a fifth of a 375px screen to
     margins if this stays at desktop width, and the measure is already short. */
  --gutter:1.25rem;
}
/* Dark values are written once and applied twice: under the media query for
   readers on the system setting, and under an explicit [data-theme="dark"] for
   readers who chose it in the header. Keeping one copy is the only way the two
   cannot drift. */
@media (prefers-color-scheme: dark){ :root[data-theme="auto"]{ 
  --bg:#141916; --surface:#1B211D; --wash:#1F2622; --sage:#233029;
  --ink:#ECE8DE; --muted:#A3AAA2; --rule:#313A34; --rule-strong:#46514A; --rule-ink:#6B766E;
  --accent:#9CC3AD; --accent-ink:#141916; --focus:#D7B575;
  --happy:#9CC3AD; --happy-soft:#233029; --warn:#E6A48C;
  --codebg:#222A25; --track:#28302B;
  --forest:#34594B; --ochre:#D7B575; --clay:#B77861;
  --hl-desc:#5E4A26; --hl-class:#2B4540; --hl-quote:#353B35;
  --grief:#2E4550; --neutralc:#28302B; --joy:#56481F;
  --grief-ink:#9CC0CE; --joy-ink:#D7B575;
  --lead-wash:.4;
  --mood-low:#8E4B35; --mood-mid:#2C332E; --mood-high:#4F7563;
  --ok:#34453B; --mid:#4B4330; --hot:#5A4236;
  --pole-cold:#3E5A66; --pole-warm:#6E5A2B; --pole-left:#39535F;
  --pole-right:#6B4A3A; --pole-hot:#8E5A46;
  --lift:none;
  --lift-hover:0 2px 10px rgba(0,0,0,.4); } }
:root[data-theme="dark"]{ 
  --bg:#141916; --surface:#1B211D; --wash:#1F2622; --sage:#233029;
  --ink:#ECE8DE; --muted:#A3AAA2; --rule:#313A34; --rule-strong:#46514A; --rule-ink:#6B766E;
  --accent:#9CC3AD; --accent-ink:#141916; --focus:#D7B575;
  --happy:#9CC3AD; --happy-soft:#233029; --warn:#E6A48C;
  --codebg:#222A25; --track:#28302B;
  --forest:#34594B; --ochre:#D7B575; --clay:#B77861;
  --hl-desc:#5E4A26; --hl-class:#2B4540; --hl-quote:#353B35;
  --grief:#2E4550; --neutralc:#28302B; --joy:#56481F;
  --grief-ink:#9CC0CE; --joy-ink:#D7B575;
  --lead-wash:.4;
  --mood-low:#8E4B35; --mood-mid:#2C332E; --mood-high:#4F7563;
  --ok:#34453B; --mid:#4B4330; --hot:#5A4236;
  --pole-cold:#3E5A66; --pole-warm:#6E5A2B; --pole-left:#39535F;
  --pole-right:#6B4A3A; --pole-hot:#8E5A46;
  --lift:none;
  --lift-hover:0 2px 10px rgba(0,0,0,.4); }
/**
 * What the browser paints for itself — radios, checkboxes, number spinners,
 * scrollbars, the caret — follows the theme the reader chose here, not the one
 * their operating system is in.
 *
 * The two were allowed to disagree, because the only declaration was the meta
 * tag's "light dark": a reader whose laptop is in dark mode and who pressed
 * Light got a light page with dark form controls painted on it, and on the
 * chip-in form that made an unchecked radio a solid dark disc — it read as the
 * selected one. Light is the default, so a reader with no script gets light
 * controls on a light page; Auto is the only setting that hands the decision
 * back to the device.
 */
:root{color-scheme:light}
:root[data-theme="dark"]{color-scheme:dark}
:root[data-theme="auto"]{color-scheme:light dark}
*{box-sizing:border-box}
/* Source Serif 4 (SIL Open Font Licence), served from our own domain so no
   third party sees a reader's visit. One variable file per script covers every
   weight from 400 to 900 and the optical sizes. */
@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:400 900;font-display:swap;
  src:url(/fonts/source-serif-4-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:"Source Serif 4";font-style:normal;font-weight:400 900;font-display:swap;
  src:url(/fonts/source-serif-4-latin-ext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,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}
@font-face{font-family:"Source Serif 4";font-style:italic;font-weight:400 700;font-display:swap;
  src:url(/fonts/source-serif-4-italic-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:"Source Serif 4";font-style:italic;font-weight:400 700;font-display:swap;
  src:url(/fonts/source-serif-4-italic-latin-ext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,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}
/* Source Serif 4: a sturdy news serif with a heavy weight for headlines. The
   size is 18px, not 16: the site is for reading, and 16px serif on a laptop
   screen is the size that makes people lean in. */
body{margin:0;background:var(--bg);color:var(--ink);
  font:18px/1.7 "Source Serif 4",Charter,"Iowan Old Style",Georgia,serif;font-optical-sizing:auto;
  -webkit-font-smoothing:antialiased}
a{color:inherit}
/* One gutter for the whole page. It used to be a fixed 1.25rem here while the
   phone rules set --gutter:1rem and pulled the feed out to the screen edge by
   that amount, so the feed sat 4px in from both edges instead of bleeding. */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
/* ── masthead ─────────────────────────────────────────────────────────────
   The name is the kit's lockup — an armchair whose back is an open book, the
   wordmark and "News, no dramas." — drawn from /brand/lockup.svg; its sizing
   is in the identity layer. */
/* The masthead is a band, edge to edge, the way a front page runs it: the
   background and the rule reach both sides of the screen and the name and
   navigation sit near the edges, while the reading measure below stays narrow.
   The band is a shade deeper than the page so it reads as a masthead rather
   than as the first thing in the story list. */
header.site{margin-bottom:2rem;background:var(--bg)}
header.site .wrap-band{max-width:var(--maxw-band);padding-inline:clamp(1rem,4vw,3rem)}
/* the thin strip: date and time, the weather where the reader is, the way in */
.topbar{border-bottom:1px solid var(--rule);background:color-mix(in srgb,var(--wash) 85%,var(--bg))}
.topbar .wrap{display:flex;align-items:center;gap:.9rem;min-height:2.3rem;
  font:.76rem/1.3 system-ui,sans-serif;color:var(--muted)}
.tb-date{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tb-weather{display:inline-flex;align-items:center;gap:.35rem;color:inherit;text-decoration:none;
  padding:.1rem .45rem;border:1px solid var(--rule);border-radius:999px}
.tb-weather{background:none;cursor:pointer;font:inherit}
.tb-weather[hidden]{display:none}
.wx-pop{position:absolute;z-index:40;margin-top:.4rem;background:var(--bg);border:1px solid var(--rule);
  border-radius:10px;padding:.7rem;width:min(21rem,calc(100vw - 2rem));box-shadow:0 10px 30px rgba(0,0,0,.12)}
.wx-pop[hidden]{display:none}
.wx-pop-label{display:block;font:.78rem system-ui,sans-serif;color:var(--muted);margin-bottom:.3rem}
.wx-pop input{width:100%;font:inherit;font-size:1rem;padding:.5rem .6rem;border:1px solid var(--rule);
  border-radius:8px;background:var(--bg);color:var(--ink)}
.wx-pop-results{list-style:none;margin:.4rem 0 0;padding:0;max-height:13rem;overflow:auto}
.wx-pop-results li{padding:.45rem .5rem;font:.9rem system-ui,sans-serif;cursor:pointer;border-radius:6px}
/* The arrow-key highlight and the mouse hover look the same, and a focused
   option keeps a real outline: the old rule removed it and left a wash of
   off-white as the only sign of where the keyboard was. */
.wx-pop-results li:hover,.wx-pop-results li.is-active{background:var(--wash)}
.wx-pop-results li:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.wx-pop-note{margin:.45rem 0 0;font:.8rem/1.45 system-ui,sans-serif;color:var(--muted)}
.wx-pop-note:empty{display:none}
.wx-pop-foot{display:flex;justify-content:space-between;gap:.6rem;margin:.6rem 0 0;font:.8rem system-ui,sans-serif}
.wx-pop-foot button{font:inherit;background:none;border:0;padding:0;color:inherit;text-decoration:underline;cursor:pointer}
.tb-weather:hover{color:var(--ink)}
.tb-wx-temp{font-weight:700;color:var(--ink)}
.tb-actions{margin-left:auto;display:flex;align-items:center;gap:.6rem;white-space:nowrap}
.tb-actions a{white-space:nowrap}
@media (max-width:40rem){
  /* A thumb needs somewhere to land. The strip's controls keep their small
     type and gain the height, rather than being 20 pixels of target. */
  .topbar .wrap{min-height:2.9rem}
  .tb-weather,.tb-sub,.tb-actions a{min-height:38px;display:inline-flex;align-items:center}
  .tb-sub{padding:.3rem .7rem}
  /* Laid out inline to keep the footer short on a phone, these had no space
     between them at all: the four News links rendered as "TodayLatestDaily
     briefGood news", one run of words, and two links a thumb apart with no
     gap is a mis-tap. The padding is on the right only, so the column's left
     edge still lines up. */
  footer.site nav a{display:inline-block;padding:.35rem .9rem .35rem 0;min-height:34px}
}
@media (max-width:30rem){.tb-date{display:none}}
.tb-sub{color:var(--ink);font-weight:600;text-decoration:none;border:1px solid var(--ink);
  padding:.22rem .7rem;border-radius:999px}
.tb-sub:hover{background:var(--ink);color:var(--bg)}
/* the name, across the page */
.masthead{border-bottom:1px solid var(--rule);background:var(--bg)}
.masthead .wrap{display:flex;flex-direction:column;align-items:center;gap:.1rem;padding-block:.85rem .7rem;text-align:center}
.masthead .brand{font-size:clamp(1.6rem,4.4vw,2.6rem);gap:.6rem}
.masthead .brand-mark{width:1.5em;height:1.5em}
/* the sections */
/**
 * The section band stays at the top of the window, so anything scrolled to by
 * an anchor has to stop below it.
 *
 * Without this, every in-page jump put its target at the very top of the
 * viewport and the band covered it: the skip link, which is the first thing a
 * keyboard reader presses, sent them to a heading hidden under the navigation.
 * The band is 53px at every width it appears at; the rest is air. It is hidden
 * on a phone, so the padding is only wanted above that breakpoint.
 */
@media (min-width:40.0625rem){ html{scroll-padding-top:4.25rem} }
.navband{border-bottom:1px solid var(--rule);background:var(--bg);position:sticky;top:0;z-index:20;
  backdrop-filter:saturate(1.2) blur(8px);-webkit-backdrop-filter:saturate(1.2) blur(8px)}
.navband .wrap{display:flex;align-items:center;justify-content:center;gap:.4rem 1.1rem;flex-wrap:wrap;padding-block:.5rem}
.brand-lockup{display:flex;align-items:center;gap:.8rem;min-width:0;flex-wrap:wrap}
.brand{display:inline-flex;align-items:center;gap:.55rem;text-decoration:none;
  font:800 1.3rem/1 "Source Serif 4",Charter,Georgia,serif;letter-spacing:-.015em}
.brand-mark{width:1.6rem;height:1.6rem;flex:none;color:var(--ink);display:block}
.brand b{font-weight:800}
/* No rule between the wordmark and the promise. A 1px border-left here read
   as a stray pipe — "| News, no dramas." — rather than as the considered
   separator it was meant to be, and being a border rather than a character it
   was invisible to every check either review ran: it has no text, so nothing
   measured its contrast, nothing found it in the accessibility tree, and
   nothing turned it up in a search for "|". Space does the same job. */
.tagline{font:.78rem/1.2 system-ui,sans-serif;color:var(--muted);padding-left:.9rem}
nav.site{display:flex;align-items:center;flex-wrap:wrap;gap:.2rem 1rem}
nav.site a{font:500 .8rem/1 system-ui,sans-serif;color:var(--muted);text-decoration:none}
nav.site a:hover{color:var(--ink)}
nav.site a.acct-link{color:var(--bg);background:var(--ink);padding:.42rem .8rem;border-radius:999px;font-weight:600}
nav.site a.acct-link:hover{color:var(--bg);opacity:.88}
@media (max-width:40rem){
  header.site{position:static}
  .tagline{padding-left:0;flex-basis:100%}
  .theme{margin-left:0}
}
h1{font-size:2rem;line-height:var(--lh-display);letter-spacing:-.018em;margin:0 0 .7rem;font-weight:800}
/* A section heading has to be plainly louder than the headlines under it or it
   reads as one more story. It used to be 1.2rem — about a point above a card
   headline — and it inherited the body's 1.7 leading, which is prose leading on
   a two-word heading. The ABC runs its section heads at half again the size of
   the headlines beneath them, and this is that step. */
h2{font-size:clamp(1.3rem,1.15rem + .6vw,1.55rem);line-height:1.22;margin:2.4rem 0 .8rem;font-weight:700;
  letter-spacing:-.012em}
/* ── reading an article ──────────────────────────────────────────────────
   Headline heavy and large, byline small and plain, then the summary, then
   the article at a size you can read without leaning in. */
/* One rule, not two. The design sheet used to set this headline again with a
   different clamp, so which curve the size followed between 375px and a laptop
   depended on which of the two sheets you happened to read. */
.article-main h1{font-size:clamp(2rem,1.3rem + 2.4vw,2.9rem);line-height:var(--lh-display);font-weight:900;
  letter-spacing:-.022em;margin:0 0 .9rem;text-wrap:balance}
.section-label{font:700 .72rem/1 system-ui,sans-serif;text-transform:uppercase;letter-spacing:.12em;
  color:var(--muted);margin:1.8rem 0 .7rem;display:flex;align-items:center;gap:.6rem}
.section-label::after{content:"";flex:1;height:1px;background:var(--rule)}
.summary-block{margin:0 0 1.6rem}
.summary-text{font-size:1.28rem;line-height:1.6;margin:0}
.summary-how{font-size:.85rem;color:var(--muted);margin:.5rem 0 0}
.summary-block .body{font-size:1.28rem}
/* Wrapping rows of small facts, so the gaps do the separating. A middle dot
   printed before each item starts a line as soon as the row wraps, which at
   phone width it always does. */
.meta{font:var(--t-meta)/1.5 system-ui,sans-serif;color:var(--muted);
  display:flex;column-gap:.9rem;row-gap:.1rem;flex-wrap:wrap;align-items:baseline;margin:0}
.meta a{color:inherit}
/* The attribution is the half a reader looks for, so it is a step up in size
   and sits in the text colour rather than the grey. */
.meta-by{font-size:.92rem;color:var(--ink);margin-bottom:.15rem}
/* The way to the outlet's own report, and the one target in this line worth
   hitting. It was 22px tall; a little padding takes it past 24 without moving
   the text, because the row is baseline-aligned. */
.meta-by .outlet{font-weight:600;padding-block:.15rem}
.meta-by .byline{color:var(--muted)}
.meta-when{margin-bottom:.2rem}
/* ── news cards ──────────────────────────────────────────────────────────
   The picture is the card's backdrop, not a thumbnail beside it. A scrim runs
   from transparent at the top to the page colour at the bottom, so the type
   sits on solid ground and the site keeps its light typographic character
   instead of becoming a wall of photographs with white text on them. */
.wrap-wide{max-width:var(--maxw-wide)}
.wrap-article{max-width:var(--maxw-article)}

/* Every card carries a photograph. Where the source supplied none, the ingest
   attaches a freely licensed library picture of the article's subject and marks
   it as such — see findLibraryImage in src/ingest/images.js. A card with no
   picture at all is the remaining case and says so rather than showing a void. */
/* align-items:start lets each card be as tall as its own headline and summary
   need. Stretching them to a common row height is what forced the clamp, and
   the clamp is what put an ellipsis in the middle of a sentence. */
.feed{display:grid;grid-template-columns:repeat(auto-fill,minmax(17.5rem,1fr));
  gap:1.5rem 1.35rem;margin:1.5rem 0 2rem;align-items:start}
.card{position:relative;display:flex;flex-direction:column;border-radius:9px;
  overflow:hidden;text-decoration:none;color:inherit;background:var(--wash);
  box-shadow:var(--lift);transition:transform .16s ease,box-shadow .16s ease}
.card:hover{transform:translateY(-3px);
  box-shadow:0 2px 4px rgba(22,21,15,.06), 0 18px 34px -16px rgba(22,21,15,.3)}
.card:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
/**
 * The whole-card click, now that the card is not itself a link.
 *
 * The headline holds the href and this ::after stretches it over the card, so
 * a press anywhere still opens the story. Anything that has to stay pressable
 * — the share button — sits above it on z-index.
 */
.card-link{color:inherit;text-decoration:none}
.card-link::after{content:"";position:absolute;inset:0;z-index:1}
.card:has(.card-link:focus-visible){outline:2px solid var(--accent);outline-offset:3px}
/**
 * Share, in the top corner of the picture.
 *
 * Its own scrim rather than a bare glyph, because a card with no picture shows
 * a pale placeholder and a white icon would vanish into it. Copying the link
 * on a desktop swaps the glyph for the words "Link copied", so the width is a
 * minimum and not a fixed size.
 */
.card-share{position:absolute;top:.6rem;right:.6rem;z-index:3;
  display:inline-flex;align-items:center;justify-content:center;
  min-width:34px;height:34px;padding:0 .5rem;border:0;border-radius:999px;cursor:pointer;
  font:600 .68rem/1 system-ui,sans-serif;
  color:var(--bg);background:color-mix(in srgb,var(--ink) 55%,transparent);
  transition:background .16s ease}
.card-share:hover,.card-share.is-copied{background:color-mix(in srgb,var(--ink) 78%,transparent)}
.card-share:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.card-share svg{display:block}
/* The ink is 34px and on a list row 28px, which is under the 44px a thumb
   wants. This gives the button the missing millimetres without drawing them,
   the same trick the back-to-top button uses. */
.card-share::before{content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;
  transform:translate(-50%,-50%)}
/* The lead card's picture is the biggest surface on the page and the corner
   button is small against it, so it gets a little more room. */
.card-lead .card-share{top:.8rem;right:.8rem}
/* .card{display:flex} outranks the user agent's [hidden]{display:none}, so the
   happiness filter set the attribute and nothing moved. */
.card[hidden]{display:none}
.card-pic{display:block;position:relative;aspect-ratio:16/9;overflow:hidden;background:var(--track)}
.card-pic img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* A library picture is a real photograph of the subject that was not taken at
   this event. Saying so on the frame is the whole licence to use it. */
.pic-tag{position:absolute;left:.55rem;bottom:.55rem;z-index:2;pointer-events:none;
  font:500 .58rem/1 system-ui,sans-serif;letter-spacing:.05em;text-transform:uppercase;
  color:var(--bg);background:color-mix(in srgb,var(--ink) 55%,transparent);
  padding:.22rem .38rem;border-radius:2px}
.pic-none{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font:.64rem/1 system-ui,sans-serif;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
/* The lead card runs two columns wide and taller, so the feed has a front page
   rather than a uniform mosaic with no entry point. */
.card-lead{grid-column:span 2}
.card-lead .card-pic{aspect-ratio:2/1}
@media (max-width:52rem){ .card-lead{grid-column:span 1} .card-lead .card-pic{aspect-ratio:16/9} }
.card-body{padding:.95rem 1.05rem 1.1rem;display:flex;flex-direction:column;flex:1}
.card h3{margin:0 0 .4rem;font-size:var(--t-head);line-height:var(--lh-head);font-weight:800;
  letter-spacing:-.008em;text-wrap:balance}
.card-sum{margin:0 0 .75rem;font-size:var(--t-sub);line-height:1.5;color:var(--ink);opacity:.8}
.card-meta{font:var(--t-meta)/1.4 system-ui,sans-serif;color:var(--muted);
  display:flex;gap:.45rem;flex-wrap:wrap;align-items:center;margin-bottom:.45rem;
  text-transform:uppercase;letter-spacing:.06em}
.card-meta .src{font-weight:600;color:var(--ink);opacity:.72}
.card .strip{margin-top:auto;padding-top:.55rem}
/* A cluster badge only earns its place when there is actually a comparison to
   make, so it is rendered only for clusters with more than one outlet. */
.badge{display:inline-flex;align-items:center;gap:.28rem;border-radius:999px;
  padding:.16rem .5rem;background:var(--bg);border:1px solid var(--rule);
  font-weight:600;letter-spacing:.05em;color:var(--ink)}
@media (max-width:26rem){ .feed{grid-template-columns:1fr} }
/* ── phone: one story per screen ─────────────────────────────────────────
   On a phone the feed pages like a deck: each card fills the screen, a swipe
   moves a whole card, and scroll-snap-stop keeps a fast swipe from skipping
   stories. min-height rather than height, so a card with a long headline grows
   past the screen instead of cutting its text; the picture takes whatever room
   the words leave. svh is the screen with the browser's bars showing, so the
   bottom of a card is never under them. Only pages with a feed snap. */
/**
 * One story a screen, on a phone, for readers who want it.
 *
 * It is the Inshorts way of reading and some people prefer it, but forty
 * screens is no way to find out what happened this morning, so the list is
 * what a reader gets first and this is a toggle beside the filters. The
 * attribute is set before paint by the theme boot script.
 */
@media (max-width:40rem){
  html[data-feed="cards"]:has(#feed){scroll-snap-type:y mandatory}
  html[data-feed="cards"]:has(#feed) header.site,html[data-feed="cards"]:has(#feed) .controls{scroll-snap-align:start}
  html[data-feed="cards"]:has(#feed) footer.site,html[data-feed="cards"]:has(#feed) .sibs,html[data-feed="cards"]:has(#feed) main > h2{scroll-snap-align:start}
  html[data-feed="cards"] #feed{display:block;margin-inline:calc(var(--gutter) * -1)}
  /* dvh, not svh, and why it matters on a real phone.

     svh is the screen with the browser's bars SHOWING. The moment a reader
     scrolls, a phone browser retracts its address bar and the visible viewport
     becomes TALLER than 100svh — so a card sized in svh stops short of the
     bottom of the screen and the top of the next card appears beneath it.
     Which is exactly what it looked like: a card covering most of the screen
     with the next one starting at the bottom, reading as a broken card rather
     than as a deck.

     dvh is whatever the viewport is at this moment, which is the thing the card
     is meant to fill. svh stays underneath it as a fallback, and vh under that. */
  html[data-feed="cards"] #feed .card{min-height:100vh;min-height:100svh;min-height:100dvh;border-radius:0;box-shadow:none;margin:0;
    padding-inline:0;display:flex;background:none;
    scroll-snap-align:start;scroll-snap-stop:always;
    /* No side borders: the card is the screen, so a rule down each edge is a
       1px inset on a photograph that is meant to reach the glass. */
    border:0;border-bottom:1px solid var(--rule)}
  html[data-feed="cards"] #feed .card:hover{transform:none;box-shadow:none}
  html[data-feed="cards"] #feed .card-pic,html[data-feed="cards"] #feed .card-lead .card-pic{aspect-ratio:auto;flex:1 1 auto;min-height:34svh;width:auto;height:auto}
  /* The last line of a card was sitting under the tab bar, which is fixed over
     the bottom of every screen. The card fills the viewport; its words have to
     stop above the bar. */
  html[data-feed="cards"] #feed .card-body{flex:0 0 auto;padding:1.2rem var(--gutter) calc(1.5rem + var(--tabbar))}
  html[data-feed="cards"] #feed .card h3,html[data-feed="cards"] #feed .card-lead h3{font-size:1.7rem;line-height:1.18;-webkit-line-clamp:none;display:block}
  html[data-feed="cards"] #feed .card-sum{font-size:1.14rem;line-height:1.55;opacity:.88;display:block;-webkit-line-clamp:none}
  html[data-feed="cards"] #feed .card-meta{font-size:.75rem}
  /* Clear of the back-to-top button in the corner. */
  html[data-feed="cards"] #feed .card-foot{padding-right:3.8rem}
}
@media (max-width:40rem) and (prefers-reduced-motion:reduce){ html[data-feed="cards"]:has(#feed){scroll-snap-type:y proximity} }

/* ── article layout ───────────────────────────────────────────────────────
   Text column plus a sidebar that stays with the reader. The panel used to sit
   inline under the body, which meant the measurements were only visible after
   you had finished reading the thing they describe. */
.article-grid{display:grid;grid-template-columns:minmax(0,1fr) 15.5rem;
  gap:2.75rem;align-items:start}
.article-main{min-width:0}
/* The tail takes the second row of the first column, which is where grid puts
   it without being told; naming it keeps it off the sidebar's column if the
   sidebar is ever absent, and keeps the scoreboard at the report's measure
   rather than stretching it across both columns. */
.article-tail{min-width:0;grid-column:1}
/**
 * The indicators stay in view, and scroll inside themselves when they cannot.
 *
 * Sticky alone was not enough: eleven indicators are taller than most windows,
 * so the panel stuck to the top with its last rows below the fold, and the
 * only way to reach Mood was to scroll the whole article past them. Bounding
 * it to the window height and letting it scroll on its own means every
 * indicator is reachable from anywhere in the article.
 */
.article-aside{position:sticky;top:1.5rem;font-family:system-ui,sans-serif;
  max-height:calc(100vh - 3rem);overflow-y:auto;overscroll-behavior:contain;
  scrollbar-width:thin}
/* A scrollbar that only appears when there is something to scroll to. */
.article-aside::-webkit-scrollbar{width:7px}
.article-aside::-webkit-scrollbar-thumb{background:var(--rule);border-radius:4px}
.article-aside::-webkit-scrollbar-track{background:transparent}
.article-aside .panel{background:var(--wash);border-radius:9px;padding:1.1rem 1.15rem}
@media (max-width:60rem){
  .article-grid{grid-template-columns:1fr;gap:1.5rem}
  /* On one column the panel is in the flow and has the whole page to use. */
  .article-aside{position:static;top:auto;margin-top:1rem;max-height:none;overflow:visible}
}
/* ── same event elsewhere ─────────────────────────────────────────────── */
.sibs{display:grid;grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));gap:.75rem;
  margin:.9rem 0 0}
.sib{display:block;text-decoration:none;color:inherit;background:var(--wash);
  border-radius:7px;padding:.75rem .85rem;transition:transform .14s}
.sib:hover{transform:translateY(-2px)}
.sib-src{font:600 .64rem/1.3 system-ui,sans-serif;text-transform:uppercase;
  letter-spacing:.07em;color:var(--muted);display:block;margin-bottom:.3rem}
.sib-title{font-size:.9rem;line-height:1.35;display:block;margin-bottom:.4rem}
.sib-foot{font:.66rem/1 system-ui,sans-serif;color:var(--muted);
  display:flex;gap:.5rem;flex-wrap:wrap}
article.item{padding:1.35rem 0;border-bottom:1px solid var(--rule)}
article.item h3{margin:0 0 .35rem;font-size:var(--t-head);line-height:var(--lh-head);font-weight:650}
article.item h3 a{text-decoration:none}
article.item h3 a:hover{text-decoration:underline;text-underline-offset:3px}
/**
 * The reading measure and the rhythm of it.
 *
 * The body was set at 1.78 — looser than the 1.7 the rest of the page uses, and
 * looser than the Guardian, the ABC, the Herald or AP set their article text.
 * Below it each paragraph was separated by 1.3rem, which at that leading is a
 * gap smaller than the space between two lines of the same paragraph, so the
 * paragraph breaks did not read as breaks. Tightening the lines and opening the
 * breaks makes the step between them plain, and fits about a tenth more of the
 * report on a phone screen.
 */
.body{font-size:1.22rem;line-height:1.65;max-width:40rem}
.body p{margin:0 0 1.5rem}
.controls{padding:.7rem 0 .8rem;border-bottom:1px solid var(--rule);margin-bottom:.25rem;
  font-family:system-ui,sans-serif;font-size:.78rem;color:var(--muted);
  display:flex;flex-direction:column;gap:.55rem}
.filter-row{display:flex;gap:.6rem;align-items:center;flex-wrap:wrap}
.filter-label{font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;font-weight:600}
/* A range input is 16px of track by default, which is a thumb-sized control
   drawn at pencil size. The height gives the slider somewhere to be grabbed. */
.controls input[type=range]{accent-color:var(--accent);max-width:8rem;height:28px}
.controls select{font:inherit;color:var(--ink);background:var(--bg);
  border:1px solid var(--rule);border-radius:999px;padding:.3rem .55rem}
.chips{display:flex;gap:.35rem;flex-wrap:wrap}
.chip{font:inherit;color:var(--muted);background:transparent;cursor:pointer;
  border:1px solid var(--rule);border-radius:999px;padding:.28rem .7rem;
  transition:color .12s ease,border-color .12s ease,background .12s ease}
.chip:hover{color:var(--ink);border-color:var(--ink)}
.chip.is-on{color:var(--bg);background:var(--ink);border-color:var(--ink)}
.chip-reset{margin-left:auto}
.dateline{font-weight:600;letter-spacing:.04em;text-transform:uppercase;font-size:.66rem}
.filter-foot{margin:0;font-size:.74rem;line-height:1.5}
.prefs-banner{margin:0;font-size:.8rem;color:var(--ink)}
.prefs-banner button{font:inherit;color:var(--accent);background:none;border:0;padding:0;cursor:pointer;text-decoration:underline}
.prefs-banner a{color:var(--accent)}
.board-note{font-size:.76rem;line-height:1.5;color:var(--muted);margin:.6rem 0 0;
  font-family:system-ui,sans-serif}
/* A stacked label-above-input form. Deliberately not .signup, which is the
   older single-field row and sets display:flex — reusing it put every label
   beside its input instead of above it. */
.auth-form{display:block;margin:0}
/* .empty centres its text and is declared later in this sheet, so a plain
   .account-page rule lost to it; the compound selector wins on specificity. */
.empty.account-page{text-align:left;max-width:30rem;margin-left:auto;margin-right:auto}
.account-form{max-width:22rem;margin:1rem 0 1.4rem}
.account-form label{display:block;font:600 .7rem/1.6 system-ui,sans-serif;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em}
.account-form input:not([type=hidden]){width:100%;font:inherit;padding:.5rem .6rem;margin:0 0 .7rem;
  border:1px solid var(--rule);border-radius:4px;background:var(--bg);color:var(--ink);box-sizing:border-box}
.account-form button{font:600 .85rem system-ui,sans-serif;padding:.55rem 1rem;
  border:0;border-radius:4px;background:var(--ink);color:var(--bg);cursor:pointer}
.account-form button:hover{opacity:.88}
.account-form button.secondary{background:transparent;color:var(--ink);border:1px solid var(--rule)}
.prefs-form{margin:1rem 0 2rem;font-family:system-ui,sans-serif}
.pref-help{font-size:.85rem;color:var(--muted);margin:.2rem 0 .7rem}
.pref-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(11rem,1fr));gap:.4rem .8rem;margin-bottom:.5rem}
.pref-check{display:flex;align-items:center;gap:.5rem;font-size:.95rem;cursor:pointer}
.pref-check input{width:1.1rem;height:1.1rem;accent-color:var(--ink)}
.pref-range{display:block;font-size:.95rem;margin-top:.8rem}
.pref-range input{display:block;width:100%;max-width:26rem;accent-color:var(--ink);margin-top:.35rem}
.pref-actions{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center;margin-top:1.4rem}
/* Sticky rather than fixed: the bar belongs to the form, so it appears while
   the form is on screen and scrolls away with it. It clears the phone's tab
   bar, which is fixed over the same corner of the screen. */
.prefs-form[data-dirty] .pref-actions{position:sticky;bottom:0;z-index:25;margin-top:1.4rem;
  padding:.7rem 0;background:var(--bg);border-top:1px solid var(--rule)}
@media (max-width:40rem){.prefs-form[data-dirty] .pref-actions{padding-bottom:calc(.7rem + 60px + env(safe-area-inset-bottom))}}
.prefs-dirty{font:.82rem/1.3 system-ui,sans-serif;color:var(--muted)}
.prefs-dirty[hidden]{display:none}
.visually-hidden{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.search-inline{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center;margin:1rem 0}
.search-inline input{font:inherit;padding:.5rem .7rem;border:1px solid var(--rule);border-radius:8px;background:var(--bg);color:var(--ink)}
.search-inline button{font:600 .9rem system-ui,sans-serif;padding:.5rem .9rem;border:0;border-radius:8px;background:var(--ink);color:var(--bg)}
.spin{margin:2rem 0}
.spin-list{list-style:none;padding:0;margin:.8rem 0}
.spin-list li{display:grid;grid-template-columns:10rem 1fr auto;gap:.3rem 1rem;align-items:baseline;border-top:1px solid var(--rule);padding:.65rem 0}
.spin-outlet{font:600 .78rem/1.3 system-ui,sans-serif;color:var(--muted)}
.spin-head{font-size:1.05rem;line-height:1.45}
.spin-count{font:.72rem/1.2 system-ui,sans-serif;color:var(--muted);white-space:nowrap}
@media (max-width:40rem){.spin-list li{grid-template-columns:1fr auto}.spin-outlet{grid-column:1/-1}}
.skip-link{position:absolute;left:-9999px;top:0;z-index:100;background:var(--ink);color:var(--bg);padding:.6rem 1rem;border-radius:0 0 6px 0}
.skip-link:focus{left:0}
main:focus{outline:none}
.footer-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));gap:1.2rem 2rem;margin:1.6rem 0}
.footer-cols h2{font:600 .7rem/1.2 system-ui,sans-serif;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin:0 0 .6rem}
/* A short word makes a narrow target: "API" and "RSS" were 21px and 24px wide,
   at or under the 24px minimum, in a column of links a thumb has to pick from. */
.footer-cols a{display:block;font:.86rem/1.9 system-ui,sans-serif;color:var(--ink);text-decoration:none;
  min-width:3rem}
.footer-cols a:hover{text-decoration:underline}
.rel{color:var(--muted)}
@media print{
  header.site,footer.site,.to-top,.changes-bar,.article-aside,#mundane-indicators-host,.filters,.controls,.skip-link{display:none!important}
  body{background:#fff;color:#000;font-size:11pt}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:.8em;color:#555}
  .article-grid{display:block}
}
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:.8rem;margin:1rem 0 .6rem}
.plan{display:flex;flex-direction:column;gap:.2rem;border:1px solid var(--rule);border-radius:8px;padding:1rem}
.plan-name{font:600 .78rem/1.2 system-ui,sans-serif;text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
.plan-price{font-size:1.6rem;font-weight:700}
.plan-per{font:.8rem/1.3 system-ui,sans-serif;color:var(--muted);margin-bottom:.6rem}
.plan button,.plan .plan-cta{font:600 .9rem system-ui,sans-serif;padding:.6rem 1rem;border-radius:4px;border:0;background:var(--ink);color:var(--bg);cursor:pointer;margin-top:auto}
.plan .plan-cta{display:block;text-align:center;text-decoration:none}
.pref-actions button{font:600 .9rem system-ui,sans-serif;padding:.6rem 1.1rem;border-radius:4px;border:0;
  background:var(--ink);color:var(--bg);cursor:pointer}
.pref-actions button.secondary{background:transparent;color:var(--ink);border:1px solid var(--rule)}
.code-input{font:600 1.6rem/1 ui-monospace,SFMono-Regular,Menlo,monospace!important;letter-spacing:.35em;text-align:center}
.account-sub{font:600 .78rem/1.3 system-ui,sans-serif;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);margin:2rem 0 .5rem}
.auth-aside{margin:.7rem 0 0;font:.8rem system-ui,sans-serif;text-align:center}
.checkout-result h1{margin-bottom:1rem}
.checkout-result p{line-height:1.6}
.key-label{display:block;font:600 .7rem/1.6 system-ui,sans-serif;color:var(--muted);text-transform:uppercase;
  letter-spacing:.05em;margin-top:1.4rem}
.key-box{display:flex;gap:.5rem;margin:.3rem 0 .6rem}
.key-box input{flex:1;min-width:0;font:.85rem ui-monospace,SFMono-Regular,Menlo,monospace;padding:.55rem .6rem;
  border:1px solid var(--rule);border-radius:4px;background:var(--wash);color:var(--ink)}
.key-box button{font:600 .85rem system-ui,sans-serif;padding:.55rem 1rem;border:0;border-radius:4px;
  background:var(--ink);color:var(--bg);cursor:pointer}
.key-warning{font:.85rem/1.5 system-ui,sans-serif;background:var(--wash);border-left:3px solid var(--accent);
  padding:.6rem .8rem;border-radius:0 4px 4px 0}
.checkout-result pre.sample{white-space:pre-wrap;word-break:break-all;font:.78rem/1.5 ui-monospace,Menlo,monospace;
  background:var(--codebg);padding:.8rem;border-radius:5px;overflow-x:auto}
.auth-aside a{color:var(--muted)}
.auth-aside a:hover{color:var(--ink)}
.auth-pair{display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));
  gap:1.5rem;margin:1.5rem 0;text-align:left}
.auth-pair h2{font-size:.82rem;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);margin:0 0 .6rem;font-family:system-ui,sans-serif}
.auth-pair label{display:block;font:600 .7rem/1.6 system-ui,sans-serif;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em}
.auth-pair input{width:100%;font:inherit;padding:.5rem .6rem;margin:0 0 .7rem;
  border:1px solid var(--rule);border-radius:4px;background:var(--bg);color:var(--ink)}
.auth-pair button{width:100%;font:600 .85rem system-ui,sans-serif;padding:.55rem;
  border:0;border-radius:4px;background:var(--ink);color:var(--bg);cursor:pointer}
.auth-pair button:hover{opacity:.88}
.auth-error{color:var(--bg);background:var(--hot);padding:.6rem .8rem;border-radius:4px;
  font:500 .85rem system-ui,sans-serif;margin:1rem 0}
/* The foot sets its own type. Everything in it used to declare a font of its
   own except the timestamp, which therefore inherited the body's 18px serif and
   came out larger than the headline it belonged to. */
.card-foot{display:flex;align-items:center;gap:.6rem;margin-top:auto;padding-top:.7rem;
  flex-wrap:wrap;font:var(--t-meta)/1.4 system-ui,sans-serif;color:var(--muted)}
.stack{display:inline-flex;align-items:center}
.stack-mark{width:18px;height:18px;border-radius:50%;object-fit:contain;background:var(--bg);
  border:1px solid var(--rule);margin-right:-6px;position:relative;padding:1px}
.stack-mark:last-of-type{margin-right:0}
.stack-text{display:inline-flex;align-items:center;justify-content:center;
  font:600 9px/1 system-ui,sans-serif;color:var(--muted);text-transform:uppercase}
.stack-more{font:600 .62rem/1 system-ui,sans-serif;color:var(--muted);margin-left:.5rem}
.stack-count{font:500 .68rem/1 system-ui,sans-serif;color:var(--muted);margin-left:.6rem;
  letter-spacing:.03em}

/* A card with nothing behind it. Still a card, visibly not a doorway. */
.card-brief{cursor:pointer}
.brief-tag{margin-left:auto;font:600 .6rem/1 system-ui,sans-serif;text-transform:uppercase;
  letter-spacing:.06em;color:var(--muted);border:1px solid var(--rule);
  border-radius:999px;padding:.28rem .5rem;transition:color .15s ease,border-color .15s ease}
.card-brief.is-nudged .brief-tag{color:var(--bg);background:var(--ink);border-color:var(--ink)}
@keyframes briefNudge{
  0%,100%{transform:translateX(0)}
  20%{transform:translateX(-4px)} 40%{transform:translateX(4px)}
  60%{transform:translateX(-2px)} 80%{transform:translateX(2px)}
}
.card-brief.is-nudged{animation:briefNudge .42s ease}
@media (prefers-reduced-motion:reduce){
  .card-brief.is-nudged{animation:none}
}
.correction-form{max-width:38rem;margin:1.5rem 0 2rem}
.correction-form textarea,.correction-form select{width:100%;font:inherit;padding:.5rem .6rem;
  margin:0 0 .8rem;border:1px solid var(--rule);border-radius:4px;background:var(--bg);
  color:var(--ink);resize:vertical}
.correction-form button{width:auto;padding:.5rem 1.1rem}
.filed-note{background:var(--wash);border-left:3px solid var(--ok);padding:.8rem 1rem;
  border-radius:0 4px 4px 0;font:.85rem/1.55 system-ui,sans-serif;margin:1.2rem 0}
.report-link{font-size:.78rem;color:var(--muted);font-family:system-ui,sans-serif}
.panel-scope{font:.7rem/1.5 system-ui,sans-serif;color:var(--muted);margin:.8rem 0 0;
  padding-top:.7rem;border-top:1px solid var(--rule)}
.outlet{display:inline-flex;align-items:center;gap:.4rem}
a.outlet{color:inherit;text-decoration:underline;text-decoration-color:var(--rule, currentColor);text-underline-offset:3px}
a.outlet:hover{text-decoration-color:currentColor}
.outlet .ext{font-size:.8em;opacity:.7}
.also-list{list-style:none;padding:0;margin:.6rem 0}
.also-list li{padding:.45rem 0;border-top:1px solid var(--rule)}
.also-domain{display:block;font:.75rem/1.3 system-ui,sans-serif;color:var(--muted)}
.credit-line{font:.75rem/1.4 system-ui,sans-serif;color:var(--muted)}
.outlet-logo{width:16px;height:16px;border-radius:3px;object-fit:contain;flex:none}
@media (max-width:40rem){ .chip-reset{margin-left:0} }

/* Theme chooser. The three states are Auto / Light / Dark rather than one
   toggle, because a toggle cannot express "follow the system", which is what
   most readers already want and never have to touch. */
.theme{display:inline-flex;border:1px solid var(--rule);border-radius:999px;
  overflow:hidden;margin-left:1rem;vertical-align:middle}
.theme button{font:500 .68rem/1 system-ui,sans-serif;color:var(--muted);background:transparent;
  border:0;cursor:pointer;padding:.34rem .5rem;letter-spacing:.03em}
/* The header's copy is hidden on a phone, so the footer's is the only way a
   reader on a phone changes the theme — and its buttons were 22px tall, under
   the 24px a target has to be. Only the footer's copy grows, so the sticky
   band at the top of a desktop window keeps the height the scroll padding
   above is set against. */
.footer-theme .theme button{min-height:38px;padding-inline:.7rem}
.theme button:hover{color:var(--ink)}
.theme button[aria-pressed="true"]{color:var(--bg);background:var(--ink)}
.fulltext{font-size:.85rem;line-height:1.6;color:var(--muted);background:var(--wash);
  border:1px solid var(--rule);border-radius:4px;padding:.9rem 1rem;margin:0 0 1.6rem;
  font-family:system-ui,sans-serif}
.fulltext strong{color:var(--ink);font-weight:600}
.note{font-size:.82rem;color:var(--muted);background:var(--wash);padding:.85rem 1rem;
  border-left:2px solid var(--rule);border-radius:0 3px 3px 0;margin:1.5rem 0;line-height:1.55;
  font-family:system-ui,sans-serif}
.diff ins{background:var(--sage);text-decoration:none;padding:0 .12em;border-radius:2px}
.diff del{background:#EFD9CF;padding:0 .12em;border-radius:2px;opacity:.75}
@media (prefers-color-scheme: dark){ :root[data-theme="auto"]{ 
  .diff ins{background:#253A2E}
  .diff del{background:#3E2A24}
 } }
:root[data-theme="dark"]{ 
  .diff ins{background:#253A2E}
  .diff del{background:#3E2A24}
 }
table.cmp{width:100%;border-collapse:collapse;font-size:.84rem;font-family:system-ui,sans-serif}
/* The table scrolls sideways rather than squeezing a headline into one word a line. */
table.cmp{min-width:54rem}
table.cmp td:first-child,table.cmp th:first-child{min-width:8rem}
table.cmp td:nth-child(2),table.cmp th:nth-child(2){min-width:18rem}
table.cmp td.num,table.cmp th.num{white-space:nowrap}
.cmp-ours{display:block;font-size:.78em;color:var(--happy,#2f6b4f);font-weight:600}
table.cmp th,table.cmp td{text-align:left;padding:.5rem .6rem;border-bottom:1px solid var(--rule);
  vertical-align:top}
table.cmp th{font-weight:600;color:var(--muted);font-size:.74rem;text-transform:uppercase;
  letter-spacing:.06em}
table.cmp td.num{text-align:right;font-variant-numeric:tabular-nums}

/* ── scoreboard: this outlet against every other, and against ours ────────
   The comparison is the argument. A reader who can see that the same event
   was filed at opinion 3 by one masthead and 61 by another does not need to
   be told the scores mean something. */
.board{width:100%;border-collapse:collapse;font-family:system-ui,sans-serif;font-size:.82rem}
.board th{font:600 .64rem/1.3 system-ui,sans-serif;text-transform:uppercase;letter-spacing:.07em;
  color:var(--muted);text-align:left;padding:0 .55rem .5rem;white-space:nowrap}
.board th.num,.board td.num{text-align:right}
.board td{padding:.55rem;border-top:1px solid var(--rule);vertical-align:middle}
.board tr.is-self td{background:var(--wash)}
.board tr.is-mundane td{background:color-mix(in srgb,var(--accent) 9%,var(--bg));
  border-top:1px solid color-mix(in srgb,var(--accent) 35%,var(--rule))}
.board .who{display:flex;flex-direction:column;gap:.15rem;min-width:9rem}
.board .who b{font-weight:600;font-size:.84rem}
.board .who em{font-style:normal;font-size:.64rem;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted)}
/* Each outlet's name is the way to that outlet's version of the story, and the
   cell's padding is not the link's: the name itself was a 16px-tall target. */
.board .who a{text-decoration:none;display:inline-block;padding-block:.25rem}
.board .who a:hover{text-decoration:underline;text-underline-offset:2px}
.board .val{font-variant-numeric:tabular-nums;font-weight:600}
/* A number and a bar in the same cell: the bar is read at a glance across the
   column, the number is there when the glance is not enough. */
.gauge{display:flex;align-items:center;gap:.5rem;justify-content:flex-end}
.gauge .bar{position:relative;width:3.4rem;height:6px;border-radius:3px;background:var(--track);
  overflow:hidden;flex:none}
.gauge .bar i{position:absolute;top:0;bottom:0;border-radius:3px;
  background:var(--accent);opacity:.75;left:var(--l,0);width:var(--w,0)}
@media (max-width:44rem){ .gauge .bar{display:none} }
.scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.scroll:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.scroll-hint{font:.78rem/1.5 system-ui,sans-serif;color:var(--muted);margin:0 0 .35rem}
footer.site .wrap{max-width:var(--maxw-band);padding-inline:clamp(1.25rem,4vw,3rem)}
footer.site{border-top:1px solid var(--rule);margin-top:4rem;padding:2rem 0 3rem;
  background:color-mix(in srgb,var(--wash) 60%,var(--bg));
  font-size:.78rem;color:var(--muted);font-family:system-ui,sans-serif;line-height:1.7}
footer.site a{color:var(--muted)}
footer.site .legal-links{margin-top:1rem}
footer.site .operator{margin:.3rem 0 0}
/* Back to top: bottom right, clear of the phone's home bar. */
.to-top{position:fixed;right:max(1rem,env(safe-area-inset-right));bottom:max(1rem,env(safe-area-inset-bottom));
  z-index:30;width:2.9rem;height:2.9rem;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:var(--ink);color:var(--bg);text-decoration:none;box-shadow:0 4px 14px -4px rgba(22,21,15,.45);
  transition:transform .15s ease,opacity .15s ease,bottom .15s ease}
.to-top[hidden]{display:none}
.to-top:hover{transform:translateY(-2px)}
.to-top:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.legal h2{margin-top:2.2rem}
.legal table.grid{margin:.8rem 0 1.6rem}
.muted-note{color:var(--muted);font-size:.9em}
.legend-line{font-size:.8rem;color:var(--muted);font-family:system-ui,sans-serif;
  margin:0 0 1rem;line-height:1.5}
.empty{padding:3rem 0;color:var(--muted);text-align:center;font-family:system-ui,sans-serif}
.empty code{background:var(--codebg);padding:.15rem .4rem;border-radius:3px;font-size:.85em}
.standfirst{font-size:1.1rem;line-height:1.6;color:var(--muted);margin:.9rem 0 1.2rem;
  max-width:60ch}
figure.lead{margin:1.4rem 0 1.6rem}
/**
 * The picture is not cut off, it runs out.
 *
 * A 16:9 crop with a hard bottom edge reads as a panel dropped onto the page,
 * and the headline under it starts again from nothing. Masking the bottom
 * third away lets the photograph fade into the paper instead, so the picture
 * and the words it belongs to are one thing.
 *
 * The frame is taller than the crop it shows, because a mask makes the bottom
 * of the image disappear and a 16:9 frame would lose a sixth of the picture to
 * it. 3:2 gives that height back.
 */
.lead-frame{display:block;position:relative;aspect-ratio:3/2;overflow:hidden;
  /* Rounded where there is an edge, square where the picture has dissolved:
     a corner radius on the bottom would draw the line the mask just removed. */
  border-radius:7px 7px 0 0;
  /* The placeholder, for the moment before the picture arrives, faded on the
     same curve so it does not flash a grey block with a hard bottom edge. */
  background:linear-gradient(to bottom,var(--track) 45%,transparent 100%)}
.lead-frame img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* Sharp in front, masked so the last third of it is gone by the bottom edge. */
.lead-frame .lead-sharp{-webkit-mask-image:linear-gradient(to bottom,#000 58%,rgba(0,0,0,.55) 78%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 58%,rgba(0,0,0,.55) 78%,transparent 100%)}
/**
 * Behind it, the same picture blurred past recognition and pushed out beyond
 * the frame, so no edge of the blur is visible inside it. It carries the
 * photograph's own colour into the space the mask empties.
 */
.lead-frame .lead-wash{transform:scale(1.35);filter:blur(34px) saturate(1.25);
  /* The dark value lives in DARK_VARS with the rest of the theme, which is the
     one place that is applied twice — once for a chosen dark and once for a
     device preference under data-theme="auto". Writing the media query here
     instead would have painted dark for a reader who had chosen nothing, which
     is the one thing this stylesheet does not do. */
  opacity:var(--lead-wash,.55);
  -webkit-mask-image:linear-gradient(to bottom,#000 40%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 40%,transparent 100%)}
/* Motion, for anyone who has not asked for less of it. */
@media (prefers-reduced-motion:no-preference){
  .lead-frame .lead-sharp{animation:lead-in .5s ease both}
  @keyframes lead-in{from{opacity:0;transform:scale(1.015)}to{opacity:1;transform:none}}
}
figure.lead .credit{display:block;margin-top:.35rem;font-size:.72rem;opacity:.8}
figure.lead figcaption{font-size:.8rem;color:var(--muted);line-height:1.5;padding-top:.5rem;
  font-family:system-ui,sans-serif}
article.item.has-thumb{display:grid;grid-template-columns:7rem 1fr;gap:1rem;align-items:start}
article.item .thumb img{width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;
  border-radius:3px;display:block;background:var(--wash)}
@media (max-width:30rem){
  article.item.has-thumb{grid-template-columns:1fr}
  article.item .thumb{display:none}
}

/**
 * The indicators that read zero, folded into one line.
 *
 * Styled as a quiet sentence rather than a control, because what it says is a
 * finding — "no political coding, no age framing" is something worth knowing
 * about a report — and because four flat bars said the same thing in four
 * times the space and taught readers to skip the panel.
 */
.panel-zero{margin:.2rem 0 .1rem}
.panel-zero > summary{cursor:pointer;list-style:none;font:.74rem/1.5 system-ui,sans-serif;
  color:var(--muted);padding:.35rem 0}
.panel-zero > summary::-webkit-details-marker{display:none}
.panel-zero > summary::before{content:"+ "}
.panel-zero[open] > summary::before{content:"− "}
.panel-zero > summary:hover{color:var(--ink)}
.panel-zero .dial-zero{opacity:.7}
/**
 * A zero that is a finding. It keeps its bar so it still reads as a
 * measurement, and says what it found where the poles would be.
 */
.dial-said{justify-content:flex-start}
.dial-said span{color:var(--ink);opacity:.75;text-transform:none;letter-spacing:0}
/* A printed page has no press, so it prints them all. */
@media print{.panel-zero > summary{display:none}}

.panel{margin:0}
.panel-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.14em;color:var(--muted);
  margin:0 0 .9rem;font-weight:600;font-family:system-ui,sans-serif}
.panel-intro{font-size:.86rem;color:var(--muted);margin:0 0 1.4rem;max-width:56ch;line-height:1.55}
.panel-foot{font-size:.72rem;color:var(--muted);line-height:1.5;margin:1rem 0 0;
  font-family:system-ui,sans-serif;padding-top:.85rem;border-top:1px solid var(--rule)}
.panel-foot a{color:var(--accent)}

/* One dial: name, number, gradient scale, the two ends. Anything longer than
   that belongs on /method, which is what the whole block links to. */
/**
 * Confidence dims the scale, not the words on it.
 *
 * The opacity used to sit on the whole dial, from 1 down to 0.45. Faded that
 * far, the indicator's name measured 3.7:1 against the page and the number we
 * struck through measured 3.0:1 — under the 4.5:1 small text has to meet — and
 * because fading grey text toward the page colour moves both ends of the
 * contrast at once, no floor above 0.45 would have fixed it: --muted only
 * reaches 4.5:1 at about 95% opacity, which is not a dimming at all.
 *
 * So the fade moves to the gradient track and its marker, which is the part a
 * reader takes the reading from and where "we are less sure of this one"
 * belongs. The name, the number and the outlet's struck-through figure stay
 * legible. The dial still lifts to full strength on hover.
 */
.dial{display:block;text-decoration:none;color:inherit;padding:.7rem 0;border-radius:3px}
.dial .dial-track{opacity:var(--conf,1);transition:opacity .15s}
.dial:hover .dial-track{opacity:1}
.dial-notbias{border-top:1px solid var(--rule);margin-top:.5rem;padding-top:.9rem}
.dial-head{display:flex;justify-content:space-between;align-items:baseline;gap:.75rem}
.dial-name{font:600 .82rem/1.2 system-ui,sans-serif;letter-spacing:-.005em}
.dial-val{font-variant-numeric:tabular-nums;font:600 .92rem/1 system-ui,sans-serif}
/* Both numbers on one dial: ours, then what the outlet filed. */
.dial-was{display:inline-block;margin-left:.45em;font:500 .72rem/1 system-ui,sans-serif;color:var(--muted);
  text-decoration:line-through;text-decoration-thickness:1px}
.dial-headline .dial-was{font-size:.8rem;vertical-align:middle}
.dial-track{position:relative;display:block;height:8px;border-radius:4px;margin:.45rem 0 .35rem;
  background:linear-gradient(90deg,var(--grad));box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}
.dial-track i{position:absolute;left:var(--p);top:-3px;width:3px;height:14px;border-radius:2px;
  background:var(--ink);transform:translateX(-1.5px);
  box-shadow:0 0 0 2px var(--bg)}
.dial-poles{display:flex;justify-content:space-between;gap:.5rem;
  font:.62rem/1.3 system-ui,sans-serif;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
.dial-poles span:last-child{text-align:right}
.dial-headline{padding:.2rem 0 .95rem;margin-bottom:.35rem;border-bottom:1px solid var(--rule)}
.dial-headline .dial-name{font:600 .95rem/1.2 system-ui,sans-serif}
.dial-headline .dial-val{font:700 1.7rem/1 system-ui,sans-serif;letter-spacing:-.02em}
.dial-headline .dial-track{height:10px}

/* Counts: the dial is a button, and what it opens sits under it. */
.dial-count{padding:0}
.count-btn{display:block;width:100%;text-align:left;font:inherit;color:inherit;background:none;border:0;
  padding:.7rem 0;cursor:pointer;border-radius:3px}
.count-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.dial-count .dial-val::after{content:"";display:inline-block;width:.36em;height:.36em;margin-left:.45em;
  border-right:1.5px solid var(--muted);border-bottom:1.5px solid var(--muted);
  transform:translateY(-.22em) rotate(45deg);transition:transform .15s}
.dial-count.is-open .dial-val::after{transform:translateY(.05em) rotate(-135deg)}
.count-open{display:none;padding:0 0 .75rem}
.dial-count.is-open .count-open,.dial-adj:hover .count-open,.dial-adj:focus-within .count-open{display:block}
/* Repeated words reads as a link and opens only when clicked. */
.dial-rep .dial-name,.dial-rep .dial-val{color:var(--accent);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px}
.dial-rep .count-btn:hover .dial-name,.dial-rep .count-btn:hover .dial-val{text-decoration-thickness:2px}
.count-detail{display:block;font:.72rem/1.4 system-ui,sans-serif;color:var(--muted)}
.freq{display:block;max-height:15rem;overflow-y:auto;overscroll-behavior:contain;
  border:1px solid var(--rule);border-radius:6px;background:var(--wash);padding:.3rem .6rem}
.freq-row{display:flex;justify-content:space-between;gap:.75rem;padding:.2rem 0;
  font:.8rem/1.35 system-ui,sans-serif;border-bottom:1px dashed var(--rule)}
.freq-row:last-child{border-bottom:0}
.freq-n{font-variant-numeric:tabular-nums;font-weight:600}
.freq-empty,.freq-more{display:block;font:.74rem/1.4 system-ui,sans-serif;color:var(--muted);padding:.25rem 0}
/* Adjective marks are always in the markup and painted only on request, so
   the article reads as plain text until a reader asks to see them. */
.body mark.adj{background:transparent;color:inherit;border-radius:2px;
  transition:background-color .15s,box-shadow .15s}
.body.show-adj mark.adj{background:var(--hl-desc);box-shadow:0 0 0 2px var(--hl-desc)}
.evidence-block{margin:2.6rem 0}
.ev-notes p{font-size:.82rem;color:var(--muted);background:var(--wash);border-left:2px solid var(--rule);
  padding:.5rem .7rem;margin:.4rem 0;line-height:1.5;border-radius:0 3px 3px 0}
.ev-wrap{margin-top:.5rem}
.ev-wrap summary{cursor:pointer;font-size:.8rem;color:var(--muted);user-select:none}
.ev-wrap summary:hover{color:var(--ink)}
.ev-list{list-style:none;padding:0;margin:.6rem 0 0;display:flex;flex-direction:column;gap:.3rem}
.ev{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap;font-size:.82rem;
  padding:.3rem .5rem;border-radius:3px;background:var(--wash)}
.ev code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.82em;
  background:var(--codebg);padding:.1rem .35rem;border-radius:3px}
.ev-w{font-variant-numeric:tabular-nums;font-size:.76rem;color:var(--muted);min-width:3.2em}
.ev-pos .ev-w{color:var(--joy-ink)}
.ev-neg .ev-w{color:var(--grief-ink)}
.ev-note{color:var(--muted);font-size:.78rem;flex:1 1 16ch;min-width:0}
.ev-empty{font-size:.82rem;color:var(--muted);margin:.5rem 0 0}
.strip{display:flex;align-items:center;gap:.7rem;margin-top:.5rem;font-family:system-ui,sans-serif}
.op{display:flex;align-items:baseline;gap:.28rem;white-space:nowrap}
.op b{font-variant-numeric:tabular-nums;font-size:.95rem;font-weight:600;letter-spacing:-.01em}
.op span{font-size:.6rem;text-transform:uppercase;letter-spacing:.07em;color:var(--muted)}
.op-brief span{font-style:normal;opacity:.85}
.ticks{display:flex;gap:.22rem;margin-left:auto}
.tick{position:relative;display:block;width:1.15rem;height:4px;border-radius:2px;
  background:linear-gradient(90deg,var(--grad))}
.tick::after{content:"";position:absolute;left:var(--p);top:-2px;width:2px;height:8px;
  border-radius:1px;background:var(--ink);transform:translateX(-1px)}
.tick-na{background:var(--track)}
.tick-na::after{display:none}

.media-item-bare figcaption{padding-top:0}

.media-block{margin:2.4rem 0}
.media-item{margin:0 0 2rem;padding:0}
.media-item img{width:100%;max-width:100%;height:auto;display:block;border-radius:3px;
  background:var(--wash,#f0efe9)}
.media-item figcaption{padding-top:.7rem}
.media-desc{font-size:.92rem;line-height:1.55;margin:0 0 .35rem;color:var(--ink,inherit)}
.media-prov{font-size:.72rem;color:var(--muted,#777);margin:0 0 .7rem;
  text-transform:uppercase;letter-spacing:.06em;font-family:system-ui,sans-serif}
.media-framing{display:grid;grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));
  gap:.9rem;padding:.8rem .9rem;background:var(--wash,#f4f2ec);border-radius:3px}
.mf-top{display:flex;justify-content:space-between;align-items:baseline;gap:.5rem;
  font-size:.72rem;text-transform:uppercase;letter-spacing:.07em;color:var(--muted,#777);
  font-family:system-ui,sans-serif}
.mf-v{font-variant-numeric:tabular-nums;font-size:.9rem;color:var(--ink,inherit);
  text-transform:none;letter-spacing:0;font-weight:600}
.mf-track{position:relative;height:4px;background:var(--track,#e3e0d8);border-radius:2px;margin:.35rem 0 .3rem}
.mf-mark{position:absolute;top:-4px;width:2px;height:12px;background:var(--ink,#222);transform:translateX(-1px)}
.mf-hint{font-size:.72rem;color:var(--muted,#777);line-height:1.4;font-family:system-ui,sans-serif}
.media-shot{grid-column:1/-1;font-size:.72rem;color:var(--muted,#777);margin:0;
  font-family:system-ui,sans-serif;text-transform:uppercase;letter-spacing:.06em}
.media-note{grid-column:1/-1;font-size:.8rem;color:var(--muted,#777);line-height:1.5;margin:.2rem 0 0;
  font-family:system-ui,sans-serif}
.media-note-set{background:var(--wash,#f4f2ec);border-left:2px solid var(--rule,#ddd);
  padding:.7rem .9rem;border-radius:0 3px 3px 0;margin:.8rem 0 0}
.media-depicted{font-size:.75rem;color:var(--muted,#777);margin:.5rem 0 0;font-family:system-ui,sans-serif}
.media-depicted code{font-family:ui-monospace,monospace;background:var(--codebg,#eceae2);
  padding:.1rem .3rem;border-radius:2px;font-size:.92em}
tr.mundane-row{background:var(--wash,#f4f2ec)}
tr.mundane-row td{font-weight:600}
tr.mundane-row .mundane-note{display:block;font-weight:400;font-size:.72rem;color:var(--muted,#777);
  margin-top:.15rem;text-transform:none;letter-spacing:0}

.ex{position:relative;display:inline-block;vertical-align:baseline}
.ex-b{font:inherit;font-size:.68rem;line-height:1;width:1.15em;height:1.15em;padding:0;
  margin-left:.3em;border:1px solid var(--rule,#ddd);border-radius:50%;background:transparent;
  color:var(--muted,var(--ink-soft,#6b6b6b));cursor:pointer;vertical-align:.08em;
  font-family:system-ui,sans-serif}
.ex-b:hover,.ex-b:focus-visible{border-color:var(--ink,#222);color:var(--ink,#222)}
.ex-b:focus-visible{outline:2px solid var(--accent,#666);outline-offset:2px}
.ex-p{position:absolute;left:50%;bottom:calc(100% + .5rem);transform:translateX(-50%);
  width:min(22rem,78vw);padding:.7rem .85rem;
  background:var(--bg,var(--panel,#fff));color:var(--ink,#222);
  border:1px solid var(--rule,#ddd);border-radius:4px;box-shadow:0 6px 20px rgba(0,0,0,.18);
  font:400 .78rem/1.5 system-ui,sans-serif;text-transform:none;letter-spacing:0;
  text-align:left;white-space:normal;
  z-index:40;display:none}
.ex-p b{display:block;margin-bottom:.15rem}
.ex:hover .ex-p,.ex:focus-within .ex-p,.ex.is-open .ex-p{display:block}
/* A fade was the first version. While it ran, the panel was partly transparent
   and the page showed through it, which reads as a rendering fault rather than
   an animation. It shows at once now. */
@media (hover:none){ .ex:hover .ex-p{display:none}
  .ex.is-open .ex-p{display:block} }

.lede{font-size:1.1rem;line-height:1.6;color:var(--muted);margin:.6rem 0 2rem;max-width:62ch}
form.signup{display:flex;gap:.5rem;margin:.9rem 0;flex-wrap:wrap}
form.signup input[type=email]{flex:1;min-width:12rem;padding:.5rem .6rem;border:1px solid var(--rule);
  border-radius:3px;font:inherit;background:var(--bg);color:inherit}
form.signup button,form.checkout button{padding:.5rem .9rem;border:1px solid var(--ink);border-radius:3px;
  background:var(--ink);color:var(--bg);font:inherit;font-weight:600;cursor:pointer;white-space:nowrap}
form.checkout{margin:.9rem 0}
.tiers{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:1rem;margin:1.5rem 0 2.5rem}
.tier{border:1px solid var(--rule);border-radius:4px;padding:1rem 1.1rem;background:var(--bg)}
.tier.is-pick{border-color:var(--ink)}
.tier h3{margin:0 0 .15rem;font-size:1rem;font-weight:600}
.tier .amt{font-size:1.5rem;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.tier .per{font-size:.76rem;color:var(--muted);font-family:system-ui,sans-serif}
.tier ul{margin:.7rem 0 0;padding-left:1.05rem;font-size:.82rem;line-height:1.55;
  color:var(--muted);font-family:system-ui,sans-serif}
.tier li{margin:.2rem 0}
.tier .note{background:none;border:0;padding:.55rem 0 0;margin:0;font-size:.78rem}
table.grid{width:100%;border-collapse:collapse;font-size:.85rem;font-family:system-ui,sans-serif;
  margin:.5rem 0 2rem}
table.grid th,table.grid td{text-align:left;padding:.55rem .6rem;border-bottom:1px solid var(--rule);
  vertical-align:top}
table.grid th{font-weight:600;color:var(--muted);font-size:.72rem;text-transform:uppercase;
  letter-spacing:.06em}
table.grid td.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
table.grid code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.86em;
  background:var(--codebg);padding:.1rem .35rem;border-radius:3px;white-space:nowrap}
.verb{font-family:ui-monospace,Menlo,monospace;font-size:.7rem;font-weight:600;
  border:1px solid var(--rule);border-radius:3px;padding:.05rem .3rem;color:var(--muted)}
.principles{margin:0 0 2rem;padding-left:1.1rem;font-size:.92rem;line-height:1.6;max-width:62ch}
.principles li{margin:.4rem 0}
pre.sample{background:var(--codebg);padding:.9rem 1rem;border-radius:4px;overflow-x:auto;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.78rem;line-height:1.55;margin:.5rem 0 2rem}
.method h2{margin-top:2.6rem}
.method table.grid{margin-bottom:1.6rem}
.method blockquote{margin:1.2rem 0;padding:.2rem 0 .2rem 1rem;border-left:2px solid var(--rule);
  color:var(--muted);font-style:italic}

.mapwrap{margin:.25rem 0 0;padding:.6rem 0 0}
.mp{width:100%;max-width:30rem;height:auto;display:block;margin:0 auto;overflow:visible}
.mp-land{fill:var(--wash);stroke:var(--rule);stroke-width:1.1;stroke-linejoin:round}
.mp-border{stroke:var(--rule);stroke-width:.8;stroke-dasharray:3 3}
.mp-label{font:600 9px system-ui,sans-serif;fill:var(--muted);letter-spacing:.06em;
  cursor:pointer;user-select:none}
.mp-label:hover,.mp-label:focus-visible{fill:var(--ink)}
.mp-label.is-on{fill:var(--bg);paint-order:stroke;stroke:var(--ink);stroke-width:7px;
  stroke-linejoin:round}
.mp-dot circle{fill:var(--accent);fill-opacity:.55;stroke:var(--accent);stroke-width:1.2;
  cursor:pointer;transition:fill-opacity .12s ease}
.mp-dot:hover circle,.mp-dot:focus-visible circle{fill-opacity:.95}
.mp-dot.is-off circle{fill-opacity:.12;stroke-opacity:.3}
.mp-dot:focus-visible{outline:none}
.mp-dot:focus-visible circle{stroke:var(--ink);stroke-width:2}
.map-toggle{font:inherit;color:var(--muted);background:transparent;border:1px solid var(--rule);
  border-radius:999px;padding:.28rem .7rem;cursor:pointer}
.map-toggle:hover{color:var(--ink);border-color:var(--ink)}
.map-toggle[aria-expanded="true"]{color:var(--bg);background:var(--ink);border-color:var(--ink)}

/* What was taken out is struck through in the warning clay; our wording in its
   place is underlined in forest. Both are the palette's own (web/brand.js),
   so the dark theme's lighter pair comes with the tokens rather than being
   written out a second and third time here. */
del.rm{color:var(--warn);text-decoration:line-through;text-decoration-color:var(--warn);text-decoration-thickness:2px;
  background:color-mix(in srgb,var(--warn) 8%,transparent)}
ins.add{text-decoration:underline;text-decoration-color:var(--accent);text-decoration-thickness:2px;text-underline-offset:3px}
.changes-bar{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem 1rem;margin:0 0 1.2rem;font:.85rem/1.4 system-ui,sans-serif}
.changes-toggle{display:inline-block;padding:.45rem .8rem;border:1px solid currentColor;border-radius:999px;color:inherit;text-decoration:none;font-weight:600}
.changes-toggle[aria-pressed="true"]{background:var(--ink,#1a1a1a);color:var(--bg,#fff);border-color:var(--ink,#1a1a1a)}
.changes-legend{color:var(--muted)}
.report-edit{font:500 .7rem/1 system-ui,sans-serif;color:var(--muted);text-decoration:underline;margin-left:.2rem;vertical-align:middle}


.wx-icon{flex:none;vertical-align:-.18em}
.wx-icon-lg{width:44px;height:44px;stroke-width:1.3}

:root{
  /* The colours are in web/brand.js and set once, at the top of the base
     sheet. What stays here is shape and type. The Good news green and the
     warning red, which each had a contrast note here, are now forest and a
     darkened clay: 7.0:1 and 5.7:1 on the page. */
  --r-card:14px;
  /**
   * One typographic scale, declared here and used everywhere.
   *
   * The lead headline, every other headline, the standfirst and the byline
   * used to be set in four different rules each, and at phone width three of
   * them landed within a point of one another: a list headline was 16.3px and
   * the lead story's standfirst was also 16.3px, so nothing on the page told a
   * reader what to look at first. These are the sizes the Guardian, the ABC,
   * the Herald and AP all settle on at 375px — a lead in the mid twenties,
   * every other headline around 17px, and everything that is not a headline
   * plainly smaller than the smallest headline.
   *
   * The tokens are redefined at the breakpoints rather than the rules, so a
   * headline's size is set in one place and the steps between the sizes hold
   * at every width.
   */
  --t-lead:1.6rem;    /* the one story at the top of the feed */
  --t-head:1.06rem;   /* every other headline in a list */
  --t-sub:.95rem;     /* a standfirst or a card's summary */
  --t-meta:.76rem;    /* outlet, time, reading, the Niral Score */
  --t-kicker:.68rem;  /* a place or a content type above a headline */
  /* Headlines are set tight; only running prose gets loose leading. Display
     sizes are tighter again, because the same ratio that reads well at 17px
     opens a visible gap between lines at 38px. */
  --lh-head:1.17;
  --lh-display:1.1;
}
@media (min-width:52rem){ :root{ --t-lead:2rem; --t-head:1.18rem; --t-sub:1rem } }
@media (min-width:68rem){ :root{ --t-lead:2.35rem } }
body{background:var(--bg);color:var(--ink);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
h1{font-weight:700;letter-spacing:-.02em}
/* top bar */
header.site{padding:.75rem 0;margin-bottom:1.2rem;border-bottom:1px solid var(--rule)}
nav.site{gap:.15rem .35rem}
nav.site a.nav-main{font:500 .9rem/1 system-ui,sans-serif;color:var(--muted);padding:.5rem .6rem;border-radius:8px}
nav.site a.nav-main:hover{color:var(--ink);background:var(--wash)}
nav.site a[aria-current="page"]{color:var(--ink);box-shadow:inset 0 -2px 0 var(--accent);border-radius:0}
@media (max-width:78rem){nav.site a.nav-main[href="/method"]{display:none}}
/* A ninth link went in beside the search icon, so the band drops one more of
   the section links before it would wrap. Chip in is never the one dropped: on
   a phone the whole band is hidden and the tab bar carries it instead. */
@media (max-width:73rem){nav.site a.nav-main[href="/index"]{display:none}}
@media (max-width:68rem){nav.site a.nav-main[href="/topics"]{display:none}}
nav.site .nav-search{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:999px;color:var(--muted)}
nav.site .nav-search:hover{background:var(--wash);color:var(--ink)}
nav.site a.acct-link{margin-left:.3rem}
/* home controls */
.controls{border-bottom:0;padding:.2rem 0 .4rem}
.chip{min-height:34px}
.more-filters{margin:.5rem 0 .2rem}
.more-filters>summary{display:inline-flex;align-items:center;gap:.35rem;cursor:pointer;list-style:none;font:600 .82rem/1 system-ui,sans-serif;
  padding:.55rem .85rem;border:1px solid var(--rule);border-radius:999px;color:var(--ink);background:var(--surface)}
.more-filters>summary::-webkit-details-marker{display:none}
.more-filters>summary::before{content:"";width:14px;height:10px;background:linear-gradient(currentColor,currentColor) 0 0/14px 2px no-repeat,linear-gradient(currentColor,currentColor) 3px 4px/8px 2px no-repeat,linear-gradient(currentColor,currentColor) 5px 8px/4px 2px no-repeat}
.more-filters[open]>summary{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.more-filters>.filter-row{margin-top:.7rem}
.filter-count{color:inherit;opacity:.75}
.filter-foot{font:.78rem/1.4 system-ui,sans-serif;color:var(--muted)}
/**
 * What kind of day it is.
 *
 * Deliberately quiet, and it does not change colour for a heavy day. A panel
 * that turns red when the news is bad is doing the thing this site removes
 * from everybody else's writing; the left rule thickens and the words do the
 * rest.
 */
.day-reading{border:1px solid var(--rule);border-left:3px solid var(--rule);border-radius:10px;
  padding:.8rem 1rem;margin:0 0 1rem;background:var(--wash)}
.day-reading.is-heavy,.day-reading.is-light{border-left-color:var(--ink)}
.day-reading-line{margin:0;font:600 .95rem/1.5 system-ui,sans-serif;color:var(--ink)}
.day-reading-do{margin:.45rem 0 0;font:.85rem/1.5 system-ui,sans-serif}
.day-reading-how{margin:.45rem 0 0;font:.74rem/1.45 system-ui,sans-serif;color:var(--muted)}
.related{margin:2rem 0}
.related ul{list-style:none;padding:0;margin:.6rem 0}
.related li{border-top:1px solid var(--rule);padding:.6rem 0}
.related li a{display:block;font-weight:600;color:inherit;text-decoration:none}
.related li a:hover{text-decoration:underline}
.related li span{font:.75rem/1.4 system-ui,sans-serif;color:var(--muted)}
.tool-btn{font:600 .8rem/1 system-ui,sans-serif;padding:.45rem .7rem;border:1px solid var(--rule);border-radius:999px;background:var(--surface);color:var(--ink);cursor:pointer;min-height:34px}
.tool-btn:hover{border-color:var(--ink)}
.text-size{display:inline-flex;gap:.25rem}
.chip.chip-link{text-decoration:none;display:inline-flex;align-items:center;color:var(--happy);border-color:color-mix(in srgb,var(--happy) 40%,var(--rule))}
.settings-nav{display:flex;flex-wrap:wrap;gap:.4rem;margin:.6rem 0 1.4rem}
.settings-nav a{font:500 .8rem/1 system-ui,sans-serif;padding:.45rem .7rem;border:1px solid var(--rule);border-radius:999px;color:var(--ink);text-decoration:none}
.brief-strip{display:flex;align-items:center;gap:.8rem;margin:.4rem 0 1.2rem;padding:.8rem 1rem;border-radius:12px;background:var(--wash);color:var(--ink);text-decoration:none;font:.9rem/1.4 system-ui,sans-serif}
.brief-strip:hover{background:color-mix(in srgb,var(--wash) 80%,var(--rule))}
.brief-strip-k{font-weight:700;white-space:nowrap;color:var(--accent)}
.brief-strip span:nth-child(2){flex:1}
.article-cta{margin:2rem 0;padding:1rem 1.2rem;border:1px solid var(--rule);border-radius:12px;font:.92rem/1.5 system-ui,sans-serif}
.article-cta a{font-weight:600}
.footer-theme{display:flex;align-items:center;gap:.6rem;font:.8rem system-ui,sans-serif;color:var(--muted)}
/* cards */
.feed{gap:1.6rem 1.4rem}
.card{border-radius:var(--r-card);background:var(--surface);box-shadow:var(--lift);border:1px solid var(--rule);transition:border-color .18s ease,box-shadow .18s ease}
.card:hover{transform:none;box-shadow:var(--lift-hover);border-color:color-mix(in srgb,var(--rule) 60%,var(--ink))}
.card h3{font-weight:650;letter-spacing:-.01em}
/* The lead's size is set here rather than beside the other card rules because
   a .card h3 selector and a .card-lead h3 selector weigh exactly the same, so
   source order decides. This sheet is applied last, which is how the lead wins
   without an id selector or an !important. */
.card-lead h3{font-size:var(--t-lead);font-weight:700;letter-spacing:-.018em;line-height:var(--lh-display)}
.card-meta{text-transform:none;letter-spacing:0}
.card-when{color:var(--muted);white-space:nowrap}
.card-meta .dateline{font-weight:600;text-transform:none;letter-spacing:0}
.card-sum{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;opacity:.86}
.brief-tag{text-transform:none;letter-spacing:0;font:500 .72rem/1 system-ui,sans-serif;color:var(--muted);border:0;background:none;padding:0}
.good-tag{font:600 .72rem/1 system-ui,sans-serif;color:var(--happy);background:var(--happy-soft);padding:.32rem .55rem;border-radius:999px}
.place-picker{margin:.4rem 0 1.4rem}
.place-now{font:600 .92rem system-ui,sans-serif;margin:0 0 .5rem}
.place-search{display:block;font:.85rem system-ui,sans-serif;color:var(--muted);max-width:26rem}
.place-search input{display:block;margin-top:.25rem;width:100%;font:inherit;font-size:1rem;
  padding:.55rem .7rem;border:1px solid var(--rule);border-radius:8px;background:var(--bg);color:var(--ink)}
.place-results{list-style:none;margin:.3rem 0 0;padding:0;max-width:26rem;border:1px solid var(--rule);
  border-radius:8px;overflow:hidden;background:var(--bg)}
.place-results li{padding:.5rem .7rem;font:.92rem system-ui,sans-serif;cursor:pointer;border-top:1px solid var(--rule)}
.place-results li:first-child{border-top:0}
.place-results li:hover,.place-results li:focus{background:var(--wash);outline:none}
.place-or{font:.85rem system-ui,sans-serif;color:var(--muted);margin:.6rem 0 0}
.place-or button{font:inherit;color:inherit;background:none;border:0;padding:0;text-decoration:underline;cursor:pointer}
.pref-select{display:block;margin:.6rem 0 1rem;font:.9rem system-ui,sans-serif}
.pref-select select{display:block;margin-top:.3rem;font:inherit;font-size:1rem;padding:.5rem .6rem;
  border:1px solid var(--rule);border-radius:8px;background:var(--bg);color:var(--ink);max-width:22rem;width:100%}
/* The Niral Score on a card: a dot that fills with the reading, then the
   number. Small enough to ignore, present enough to learn from. */
/* The number is the argument, so it is not the smallest thing on the card. It
   was 10.9px, below everything else in the foot; it takes the meta size, and
   tabular figures so a column of scores lines up down the feed. */
.niral-pill{display:inline-flex;align-items:center;gap:.3rem;
  font:600 var(--t-meta)/1 system-ui,sans-serif;font-variant-numeric:tabular-nums;
  color:var(--muted);white-space:nowrap}
.niral-pill i{width:.6rem;height:.6rem;border-radius:50%;display:inline-block;
  background:conic-gradient(var(--pole-hot) calc(var(--n) * 1%),var(--track) 0)}
/* What has happened since the reader was last here. */
.since-bar{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;margin:0 0 1rem;padding:.6rem .9rem;
  border:1px solid var(--accent);border-radius:10px;color:inherit;text-decoration:none;
  font:.88rem/1.4 system-ui,sans-serif;background:color-mix(in srgb,var(--accent) 8%,transparent)}
.since-bar span{color:var(--accent);text-decoration:underline}
/* The marker hangs off the card body rather than off the kicker line, because
   the kicker line is only rendered when a story has a place or a type, and a
   story filed in the last few minutes is exactly as likely to have neither. */
.card.is-new .card-body::before{content:"New";font:700 var(--t-kicker)/1.4 system-ui,sans-serif;
  color:var(--accent);letter-spacing:.04em;margin-bottom:.3rem}
.feed-mode{display:none}
@media (max-width:40rem){
  .feed-mode{display:inline-flex;margin:0 0 .6rem;border:1px solid var(--rule);border-radius:999px;overflow:hidden}
  .feed-mode button{font:600 .78rem/1 system-ui,sans-serif;padding:.45rem .85rem;min-height:36px;
    border:0;background:none;color:var(--muted);cursor:pointer}
  .feed-mode button[aria-pressed="true"]{background:var(--ink);color:var(--bg)}
}
.place-strip{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin:0 0 1rem;padding:.65rem .9rem;
  border:1px solid var(--rule);border-radius:10px;color:inherit;text-decoration:none;
  font:.86rem/1.4 system-ui,sans-serif;background:var(--wash)}
.place-strip:hover{border-color:currentColor}
.place-strip.has-warning{border-color:var(--warn)}
.ps-name{font-weight:600}
.ps-temp{font-weight:600;font-size:1.05rem}
.ps-range,.ps-more,.ps-fuel{color:var(--muted)}
.ps-fuel{font-variant-numeric:tabular-nums}
.ps-warning{color:var(--warn);font-weight:600}
.ps-more{margin-left:auto}
.short-note{font:.85rem/1.5 system-ui,sans-serif;color:var(--muted);margin:.8rem 0 0}
/* Which rules fired on this article, each a link to what it means. */
.rule-chips{display:flex;align-items:center;flex-wrap:wrap;gap:.3rem;font:.78rem/1.3 system-ui,sans-serif;color:var(--muted)}
.rule-chip{display:inline-flex;align-items:center;gap:.15rem;padding:.12rem .4rem;border:1px solid var(--rule);
  border-radius:999px;color:inherit;text-decoration:none}
.rule-chip:hover{border-color:currentColor}
.rule-chip code{font:600 .74rem/1 ui-monospace,SFMono-Regular,Menlo,monospace}
.rule-n{font-variant-numeric:tabular-nums}
.rule-all{color:var(--muted);text-decoration:underline}
/* Chip in.
   The ask sits in the same washed card the article summary uses, so the page
   has one obvious thing to do with the argument for doing it underneath. The
   amounts read as buttons; the native radio stays visible inside each one,
   because :has() is what paints the chosen state and a browser without it
   would otherwise show no selection at all. */
.contribute{max-width:34rem;margin:1.6rem 0 2.4rem;background:var(--wash);border:1px solid var(--rule);
  border-radius:12px;padding:1.1rem 1.2rem 1.2rem;font-family:system-ui,sans-serif}
.contribute h2{margin:0 0 .25rem;font:700 1.15rem/1.3 system-ui,sans-serif}
.contribute-lede{font:.9rem/1.5 system-ui,sans-serif;color:var(--muted);margin:0 0 1.1rem}
.contribute .auth-error{margin:.7rem 0 1rem}
.contribute fieldset{border:0;padding:0;margin:0 0 1.1rem;min-width:0}
.contribute legend{font:600 .7rem/1.6 system-ui,sans-serif;color:var(--muted);text-transform:uppercase;
  letter-spacing:.05em;padding:0;margin:0 0 .45rem}
.amounts{display:grid;grid-template-columns:repeat(auto-fit,minmax(6.5rem,1fr));gap:.5rem}
.amount{display:inline-flex;align-items:center;justify-content:center;gap:.45rem;padding:.55rem .8rem;
  border:1px solid var(--rule);border-radius:999px;background:var(--bg);color:var(--ink);
  font:600 .95rem/1.2 system-ui,sans-serif;cursor:pointer;min-height:44px;text-align:center}
.amount input{accent-color:var(--ink);margin:0;width:1rem;height:1rem;flex:none}
.amount:hover{border-color:var(--ink)}
/* :focus-visible rather than :focus-within, so a chip clicked with a mouse is
   not left wearing a keyboard ring. Where :has() is not understood the native
   radio inside keeps its own focus outline, which is the point of leaving it
   visible. */
.amount:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:2px}
.amount:has(input:checked){background:var(--ink);color:var(--bg);border-color:var(--ink)}
.amount:has(input:checked) input{accent-color:var(--bg)}
.amount-other{grid-column:1/-1;font-weight:500}
.other-amount{margin:.75rem 0 0}
.other-amount label{display:block;font:600 .7rem/1.6 system-ui,sans-serif;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em}
.amount-field{display:flex;align-items:center;gap:.4rem;max-width:11rem;margin-top:.25rem}
.amount-field .currency{font:600 1rem/1 system-ui,sans-serif;color:var(--muted)}
.amount-field input{flex:1;min-width:0;padding:.55rem .6rem;border:1px solid var(--rule);border-radius:4px;
  background:var(--bg);color:var(--ink);font:1rem/1.2 system-ui,sans-serif;min-height:44px}
.contribute .hint{font:.78rem/1.5 system-ui,sans-serif;color:var(--muted);margin:.35rem 0 0}
.choices{display:flex;flex-wrap:wrap;gap:.5rem}
.choice{display:inline-flex;align-items:flex-start;gap:.5rem;flex:1 1 12rem;padding:.6rem .85rem;
  border:1px solid var(--rule);border-radius:10px;background:var(--bg);color:var(--ink);cursor:pointer;
  min-height:44px;font:500 .92rem/1.35 system-ui,sans-serif}
.choice input{accent-color:var(--ink);margin:.15rem 0 0;flex:none}
.choice:hover{border-color:var(--ink)}
.choice:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:2px}
.choice:has(input:checked){border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
.choice small{display:block;font:.76rem/1.4 system-ui,sans-serif;color:var(--muted);margin-top:.15rem}
.contribute button{width:100%;font:600 .95rem system-ui,sans-serif;padding:.75rem 1.2rem;border:0;
  border-radius:4px;background:var(--ink);color:var(--bg);cursor:pointer;min-height:48px}
.contribute button:hover{opacity:.88}
.contribute button:disabled{opacity:.6;cursor:progress}
.contribute-foot{font:.8rem/1.6 system-ui,sans-serif;color:var(--muted);margin:.8rem 0 0}
@media (max-width:26rem){.amounts{grid-template-columns:repeat(2,1fr)}.choices{display:block}
  .choice{display:flex;margin-bottom:.5rem}}
/* An error on a form is the one message that has to be read, and this one was
   painted in --bg on --hot: white on tan, about 1.6:1. It is the page colour on
   a warm tint now, with the warning rule beside it doing the shouting. */
.auth-error{color:var(--ink);background:var(--hot);border-left:3px solid var(--warn);
  border-radius:0 4px 4px 0;font:500 .88rem/1.55 system-ui,sans-serif;padding:.7rem .9rem}


/* The Notebook: a list of what we have written, and the piece itself. */
.notebook-list{list-style:none;padding:0;margin:1.2rem 0 0}
.notebook-list .row{border-top:1px solid var(--rule);padding:1rem 0}
.notebook-list .row p{margin:.35rem 0 0;color:var(--muted)}
.notebook-post h2{margin-top:2rem}

.our-version{margin:1rem 0 0;padding:.8rem .9rem;border:1px solid var(--rule);border-radius:10px;
  font:.82rem/1.5 system-ui,sans-serif}
.our-version h2{font-size:.7rem;text-transform:uppercase;letter-spacing:.12em;color:var(--muted);margin:0 0 .5rem}
.our-version ul{list-style:none;padding:0;margin:0}
.our-version li{display:flex;justify-content:space-between;gap:1rem;padding:.15rem 0}
.our-version .ov-nums{color:var(--muted);font-variant-numeric:tabular-nums}
.our-version .ov-nums b{color:var(--ink)}
.our-version p{margin:.6rem 0 0}
/**
 * The headline check.
 *
 * It sits between the headline and the report, because that is the order the
 * question arrives in: a reader has just read the headline and wants to know
 * whether to believe it. It takes the same washed, bordered card the rest of
 * the page's asides use, with one hairline down the left in the colour of the
 * answer — the green the Good news tag uses when the claims are all in the
 * report, the warning colour when they are not, and the rule colour when
 * there was nothing to check, because "we could not tell" is not a warning.
 */
/**
 * A story you have already opened, and the end of the day.
 *
 * A read story is quieter, not gone: it stays in its place in the feed so the
 * page does not rearrange itself under a reader's thumb, and it comes back to
 * full strength under the pointer because "I have read this" should never make
 * it harder to read again. Hiding them is a choice at the end of the feed, and
 * the front page's own filter does the hiding.
 */
/**
 * Quieter is not the same as fainter.
 *
 * This was one rule — the whole card at 58% opacity — which put the headline at
 * 4.24:1 against the card, under the 4.5:1 that text this size has to meet. A
 * story you have already read is still a story, and dropping it below the
 * contrast floor is a worse thing to do to it than leaving it alone. So the
 * picture fades and the headline takes the muted colour, which is 5.6:1 in
 * light and 6.3:1 in dark, and both come back under the pointer.
 */
/**
 * A story you have opened is faded back, but only its picture — the picture's
 * contents, rather than the frame around them.
 *
 * Fading .card-pic itself put an opacity below 1 on it, and that makes a
 * stacking context: the share button inside it, at z-index 3, stopped being
 * above the headline link's z-index 1 overlay and became unclickable on every
 * card the reader had already opened. It was also being dimmed along with the
 * photograph, which said the control was spent when only the story was.
 */
#feed .card.is-read .card-pic img,#feed .card.is-read .card-pic .pic-none{opacity:.5}
#feed .card.is-read h3{color:var(--muted)}
#feed .card.is-read:hover .card-pic img,#feed .card.is-read:focus-within .card-pic img,
#feed .card.is-read:hover .card-pic .pic-none,#feed .card.is-read:focus-within .card-pic .pic-none{opacity:1}
#feed .card.is-read:hover h3,#feed .card.is-read:focus-within h3{color:var(--ink)}
.rows .row.is-read .row-title{color:var(--muted)}
.rows .row.is-read:hover .row-title,.rows .row.is-read:focus-within .row-title{color:inherit}
.read-tag{font:600 .72rem/1 system-ui,sans-serif;color:var(--muted)}
.card-foot .read-tag::before{content:"";display:inline-block;width:.42rem;height:.42rem;border-radius:50%;
  background:currentColor;margin-right:.32rem;vertical-align:.04em}
.row-meta .read-tag{margin-left:.4rem}
/**
 * A muted subject.
 *
 * It takes the opposite state to every other chip on the page: the section and
 * place chips fill in when they are ON and folding something IN, and this one
 * fills in when it is folding something OUT. So it is not painted in the ink
 * colour the others use, which would read as "selected" — it goes flat and
 * struck through, which is what a reader means by "not today".
 */
.chip-mute .chip-n{font:600 .72rem/1 system-ui,sans-serif;color:var(--muted);font-variant-numeric:tabular-nums}
.chip-mute.is-off{border-style:dashed;color:var(--muted);text-decoration:line-through;
  text-decoration-thickness:1px;background:var(--wash)}
.chip-mute.is-off .chip-n{text-decoration:none;display:none}
#mute-note button+button{margin-left:.6rem}
/* One subject has taken over the day. A statement of fact with an offer after
   it, in the washed strip the Brief and the place strip already use, so it
   reads as part of the page rather than as something shouting at the reader. */
.dominant{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin:0 0 1rem;padding:.6rem .9rem;
  border:1px solid var(--rule);border-radius:10px;background:var(--wash);
  font:.88rem/1.45 system-ui,sans-serif;color:var(--ink)}
.dominant[hidden]{display:none}
.dominant span{flex:1 1 14rem}
.dominant button{font:600 .8rem/1 system-ui,sans-serif;padding:.45rem .8rem;min-height:38px;border-radius:999px;
  border:1px solid var(--ink);background:var(--bg);color:var(--ink);cursor:pointer}
.dominant button:hover{background:var(--ink);color:var(--bg)}
/* The end of the feed. A line, not a card: it is the page finishing, not
   another thing to read. */

.feed-end{margin:2rem 0 1rem;padding-top:1.2rem;border-top:1px solid var(--rule);
  font-family:system-ui,sans-serif}
.feed-end p{margin:0 0 .35rem}
.feed-end-line{font:.98rem/1.5 system-ui,sans-serif;color:var(--ink)}
.feed-end-read{font:.85rem/1.5 system-ui,sans-serif;color:var(--muted);min-height:1.2em}
.feed-end-ways{display:flex;flex-wrap:wrap;align-items:center;gap:.45rem;margin-top:.6rem}
.feed-end-ways a,.feed-end-toggle{font:500 .82rem/1 system-ui,sans-serif;padding:.5rem .8rem;min-height:38px;
  display:inline-flex;align-items:center;border:1px solid var(--rule);border-radius:999px;
  background:var(--surface);color:var(--ink);text-decoration:none;cursor:pointer}
.feed-end-ways a:hover,.feed-end-toggle:hover{border-color:var(--ink)}
.feed-end-toggle[aria-pressed="true"]{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.feed-end-toggle[hidden]{display:none}
.hcheck{margin:1.2rem 0;padding:.8rem .95rem;border:1px solid var(--rule);border-left:3px solid var(--rule);
  border-radius:0 10px 10px 0;background:var(--wash);font-family:system-ui,sans-serif}
.hcheck.is-clean{border-left-color:var(--happy)}
.hcheck.is-gap{border-left-color:var(--warn)}
.hcheck h2{margin:0 0 .3rem;font:600 .68rem/1.4 system-ui,sans-serif;text-transform:uppercase;
  letter-spacing:.11em;color:var(--muted)}
.hcheck-said{margin:0 0 .5rem;font:.85rem/1.5 system-ui,sans-serif;color:var(--muted)}
.hcheck-said strong{color:var(--ink);font-weight:600}
.hcheck-verdict{margin:0;font:600 .98rem/1.45 system-ui,sans-serif;color:var(--ink)}
.hcheck ul{list-style:none;padding:0;margin:.55rem 0 0}
.hcheck li{position:relative;padding-left:1.1rem;margin:.35rem 0;font:.88rem/1.5 system-ui,sans-serif}
.hcheck li::before{content:"";position:absolute;left:.1rem;top:.62em;width:.42rem;height:.42rem;
  border-radius:50%;background:var(--warn)}
.hcheck-foot{margin:.6rem 0 0;font:.76rem/1.5 system-ui,sans-serif;color:var(--muted)}
.hcheck-foot a{color:inherit}
@media (max-width:26rem){ .hcheck{padding:.7rem .8rem} .hcheck-verdict{font-size:.94rem} }
/* Following a story: the one thing a digest can do that a front page cannot. */
.follow-form{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin:0 0 1.2rem}
.follow-btn{font:600 .88rem system-ui,sans-serif;padding:.5rem .9rem;border-radius:999px;
  border:1px solid var(--ink);background:var(--bg);color:var(--ink);cursor:pointer;min-height:40px}
.follow-btn:hover{background:var(--wash)}
.follow-btn.is-on{background:var(--ink);color:var(--bg)}
.follow-note{font:.8rem/1.4 system-ui,sans-serif;color:var(--muted);flex:1 1 12rem}
.follow-list{list-style:none;padding:0;margin:.5rem 0 1.2rem}
.follow-list li{display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap;padding:.5rem 0;border-top:1px solid var(--rule)}
.follow-list .small{color:var(--muted)}
.browser-list{list-style:none;padding:0;margin:.4rem 0 .6rem}
.browser-list li{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding:.55rem 0;border-top:1px solid var(--rule)}
.browser-list li:last-child{border-bottom:1px solid var(--rule)}
.browser-list .pref-help{margin:0}
.browser-list form{flex:none}
.browser-list button{font:600 .85rem/1.2 var(--font-sans);padding:.45rem .95rem;border-radius:999px;cursor:pointer;
  background:transparent;color:var(--ink);border:1px solid var(--rule)}
.browser-list button:hover{border-color:var(--ink)}
.linkish{background:none;border:0;padding:0;color:var(--muted);text-decoration:underline;cursor:pointer;font:inherit;margin-left:auto}
.topic-row{display:flex;flex-wrap:wrap;gap:.4rem;margin:0 0 1.1rem}
.topic-chip{font:.78rem/1 system-ui,sans-serif;padding:.32rem .6rem;border:1px solid var(--rule);
  border-radius:999px;color:var(--muted);text-decoration:none}
.topic-chip:hover{color:var(--ink);border-color:currentColor}
.timeline{margin:1.6rem 0}
details.timeline>summary{cursor:pointer;font:600 .95rem/1.4 system-ui,sans-serif;margin:0 0 .4rem}
.timeline ol{list-style:none;padding:0;margin:.6rem 0 0;border-left:2px solid var(--rule)}
.timeline li{position:relative;padding:.45rem 0 .45rem 1rem;font:.9rem/1.5 system-ui,sans-serif}
.timeline li::before{content:"";position:absolute;left:-5px;top:1rem;width:8px;height:8px;border-radius:50%;background:var(--rule)}
.tl-when{color:var(--muted);margin-right:.4rem}
.tl-title{display:block;color:var(--muted)}
.tl-diff{display:block}
.revisions{border:1px solid var(--rule);border-radius:10px;padding:.7rem .9rem;margin:0 0 1.2rem;
  font:.85rem/1.5 system-ui,sans-serif;background:var(--wash)}
.revisions>summary{cursor:pointer;font-weight:600}
.revisions ul{margin:.6rem 0 0;padding-left:1.1rem}
.revisions li{margin:.3rem 0}
.rev-when{color:var(--muted)}
.rev-foot{color:var(--muted);margin:.6rem 0 0}
.type-tag{font:600 .68rem/1 system-ui,sans-serif;color:var(--muted);border:1px solid var(--rule);
  padding:.2rem .42rem;border-radius:4px;text-transform:uppercase;letter-spacing:.04em}
.card-foot .good-tag{margin-left:auto}
.card-foot .good-tag + .brief-tag{margin-left:.5rem}
@media (min-width:68rem){
  .feed{grid-template-columns:repeat(3,minmax(0,1fr))}
  .card-lead{grid-column:span 2;grid-row:span 2}
  /**
   * The lead's picture is sized against the window, not against its own width.
   *
   * At 16/9 across two of three columns it came out 448px tall on a 1280x900
   * laptop, and with the masthead and the filters above it that put the lead
   * story's headline at 970px — below the fold. Someone opening the front page
   * saw a photograph and had to scroll to find out what the day's main story
   * was. A third of the window leaves room for the headline and the standfirst
   * under it, and the picture is still the largest thing on the page. The
   * bounds keep it a photograph on a short window and stop it filling a tall
   * one; the image inside crops to whatever the frame is.
   */
  .card-lead .card-pic{aspect-ratio:auto;height:clamp(15rem,33vh,22rem)}
  .card-lead .card-sum{-webkit-line-clamp:4;font-size:1.08rem}
}
/* articles */
.summary-block{background:var(--wash);border-radius:12px;padding:1rem 1.2rem}
.summary-block .section-label{margin-top:0}
/* The overview: the five points, for a reader who may read nothing else. */
.overview{margin:1.4rem 0 .4rem}
.overview .section-label{margin-top:0}
.overview-points{margin:.6rem 0 .5rem;padding:0;list-style:none;display:grid;gap:.7rem}
.overview-points li{position:relative;padding-left:1.15rem;line-height:1.55}
.overview-points li::before{content:"";position:absolute;left:0;top:.62em;width:.42rem;height:.42rem;
  border-radius:50%;background:var(--accent,currentColor);opacity:.55}
@media (max-width:46rem){.overview-points{gap:.85rem}}
/**
 * The line being read aloud.
 *
 * A wash rather than a box: the highlight moves every few seconds and a
 * border redrawing itself down the page is the sort of motion that makes a
 * page hard to read rather than easy to follow. The left rule is what the eye
 * actually tracks.
 */
.is-speaking{background:color-mix(in srgb,var(--accent) 16%,transparent);
  box-shadow:-3px 0 0 0 var(--accent);border-radius:2px;
  transition:background .2s ease}
@media (prefers-reduced-motion:reduce){.is-speaking{transition:none}}
.listen-btn[aria-pressed="true"]{background:var(--ink);color:var(--bg);border-color:var(--ink)}
/* Said once, beside the button, the first time anyone presses it. */
.listen-note{flex-basis:100%;font:.76rem/1.45 system-ui,sans-serif;color:var(--muted);margin-top:.3rem}

/* --------------------------------------------- readers: reactions and posts */
.reactions{margin:2rem 0 1rem}
.reaction-row{display:flex;flex-wrap:wrap;gap:.5rem}
.reaction-form{margin:0}
/**
 * A reaction is a label with a number, not a bare face.
 *
 * A row of emoji with counts under them is a scoreboard, and a scoreboard is
 * what turns a reaction into a pile-on. The words are what the reader is
 * actually saying, so the words are on the button.
 */
.reaction{display:inline-flex;align-items:center;gap:.4rem;cursor:pointer;
  font:500 .8rem/1 system-ui,sans-serif;padding:.45rem .7rem;min-height:36px;
  border:1px solid var(--rule);border-radius:999px;background:var(--surface);color:var(--ink);
  transition:border-color .16s ease,background .16s ease}
.reaction:hover{border-color:var(--ink)}
.reaction.is-mine{background:var(--wash);border-color:var(--ink)}
.reaction-emoji{font-size:1rem;line-height:1}
.reaction-count{color:var(--muted);font-variant-numeric:tabular-nums}
.reaction.is-mine .reaction-count{color:var(--ink)}
@media (max-width:30rem){.reaction-label{display:none}.reaction{padding:.45rem .6rem}}

.discussion{margin:1.6rem 0 2rem}
.discuss-sub{font:600 .95rem/1.3 system-ui,sans-serif;margin:1.4rem 0 .6rem;color:var(--ink)}
.discuss-note,.discuss-rules{font:.84rem/1.55 system-ui,sans-serif;color:var(--muted);margin:.4rem 0}
.discuss-rules{margin-top:1.2rem;padding-top:.8rem;border-top:1px solid var(--rule);font-size:.78rem}
.posts{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.9rem}
.posts .answers{margin:.7rem 0 0 1rem;padding-left:.9rem;border-left:2px solid var(--rule)}
.post,.question{background:var(--wash);border-radius:9px;padding:.75rem .9rem}
.post-meta{font:.76rem/1.4 system-ui,sans-serif;color:var(--muted);margin:0 0 .35rem;
  display:flex;gap:.5rem;align-items:baseline;flex-wrap:wrap}
.post-body{margin:0;font-size:.95rem;line-height:1.55;white-space:pre-wrap;overflow-wrap:anywhere}
/**
 * A post waiting to be read is shown to its author, dimmed and labelled. It is
 * not on anybody else's page, and the label is the only thing standing between
 * that fact and a reader who thinks it is.
 */
.post-held{opacity:.75;border:1px dashed var(--rule);background:none}
.post-waiting{font-style:italic}
.post-report{margin:.4rem 0 0}
.linkish{background:none;border:0;padding:0;cursor:pointer;color:var(--muted);
  font:.74rem/1 system-ui,sans-serif;text-decoration:underline}
.linkish:hover{color:var(--ink)}
.answer-fold{margin:.7rem 0 0}
.answer-fold summary{cursor:pointer;font:600 .8rem/1 system-ui,sans-serif;color:var(--muted);
  list-style:none;display:inline-block;padding:.35rem 0}
.answer-fold summary::-webkit-details-marker{display:none}
.answer-fold summary::before{content:"+ "}
.answer-fold[open] summary::before{content:"− "}
.answer-fold summary:hover{color:var(--ink)}
.discuss-form{margin:1rem 0 0;display:flex;flex-direction:column;gap:.5rem;align-items:flex-start}
.discuss-form textarea{width:100%;font:inherit;font-size:.95rem;line-height:1.5;padding:.7rem .8rem;
  border:1px solid var(--rule);border-radius:9px;background:var(--surface);color:var(--ink);resize:vertical}
.discuss-form textarea:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.discuss-said{font:600 .85rem/1.5 system-ui,sans-serif;border-radius:9px;padding:.6rem .8rem;margin:.6rem 0}
.discuss-said-ok{background:var(--wash);color:var(--ink)}
.discuss-said-wait{background:var(--wash);color:var(--ink);font-weight:500}
.discuss-said-no{background:var(--wash);color:var(--ink);font-weight:500}
/**
 * The story before and the story after.
 *
 * Two columns on a wide screen and two rows on a phone, with the newer one
 * always on the left: the feed reads newest first, so left is back towards
 * what the reader has already seen and right is onwards.
 */
/**
 * The report, folded away where the overview already covers it.
 *
 * Styled as a control rather than as a heading, because that is what it is;
 * the arrow is drawn rather than left to the browser, which shows a different
 * triangle in every one of them.
 */
.report-fold{margin:1.4rem 0 1.6rem}
.report-fold > summary{cursor:pointer;list-style:none;display:flex;align-items:center;gap:.5rem;
  font:600 .92rem/1 system-ui,sans-serif;color:var(--ink);padding:.75rem .95rem;
  border:1px solid var(--rule);border-radius:10px;background:var(--wash);
  transition:border-color .16s ease}
.report-fold > summary::-webkit-details-marker{display:none}
.report-fold > summary:hover{border-color:var(--ink)}
.report-fold > summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.report-fold > summary::before{content:"";width:0;height:0;flex:none;
  border-left:6px solid currentColor;border-top:4.5px solid transparent;border-bottom:4.5px solid transparent;
  transition:transform .18s ease}
.report-fold[open] > summary::before{transform:rotate(90deg)}
.report-fold-len{margin-left:auto;font-weight:400;color:var(--muted);font-size:.82rem}
.report-fold-shut{display:none}
.report-fold[open] .report-fold-open{display:none}
.report-fold[open] .report-fold-shut{display:inline}
.report-fold .body{margin-top:1.1rem}
/**
 * Printing, and any browser reading the page without these styles, gets the
 * whole article. The contents of a <details> are in the document either way;
 * this makes sure the closed state is not what comes out of a printer.
 */
@media print{.report-fold > summary{display:none}.report-fold .body{margin-top:0}}
.story-step{display:grid;grid-template-columns:1fr 1fr;gap:.7rem;margin:2rem 0 1rem}
.step{display:flex;flex-direction:column;gap:.25rem;text-decoration:none;color:inherit;
  border:1px solid var(--rule);border-radius:10px;padding:.8rem .9rem;background:var(--surface);
  transition:border-color .16s ease}
.step:hover{border-color:var(--ink)}
.step:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.step-dir{font:600 .7rem/1 system-ui,sans-serif;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.step-next{text-align:right}
.step-dir::before{content:"←  "}
.step-next .step-dir::after{content:"  →"}
.step-next .step-dir::before{content:none}
.step-title{font-size:.95rem;line-height:1.4;font-weight:600;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
@media (max-width:40rem){
  .story-step{grid-template-columns:1fr}
  .step-next{text-align:left}
}
/* The one page where something cannot be undone reads like it. */
.danger{border:1px solid var(--rule);border-left:3px solid var(--hot,var(--rule));
  border-radius:10px;padding:1.1rem 1.2rem;margin:1.4rem 0}
.danger p{font-size:.95rem;line-height:1.6;max-width:62ch}
.danger-ask{margin-top:1.2rem}
.danger-btn{background:var(--ink);color:var(--bg);border:1px solid var(--ink)}
.danger-btn:hover{background:var(--hot,var(--ink));border-color:var(--hot,var(--ink))}
/* The engine's working, for whoever has to answer for it. */
.why{margin:2rem 0}
.why-table{width:100%;border-collapse:collapse;font:.82rem/1.45 system-ui,sans-serif;margin:.8rem 0 1.4rem}
.why-table caption{text-align:left;font-weight:600;color:var(--muted);padding:.3rem 0 .5rem}
.why-table th,.why-table td{text-align:left;padding:.4rem .55rem;border-bottom:1px solid var(--rule);vertical-align:top}
.why-table th{font-weight:600;color:var(--muted);white-space:nowrap}
.why-table .num{text-align:right;font-variant-numeric:tabular-nums}
.why-word{font-weight:600}
.why-word a{color:inherit;text-decoration:underline;text-decoration-style:dotted;text-underline-offset:2px}
/**
 * The word the admin just pressed, found in the article above. It flashes
 * rather than staying marked: a permanent mark on one word while eleven
 * others are highlighted as adjectives is one highlight too many.
 */
mark.why-found,span.why-found{animation:why-flash 1.6s ease both}
@keyframes why-flash{0%,60%{background:var(--accent);box-shadow:0 0 0 3px var(--accent)}100%{background:transparent;box-shadow:none}}
@media (prefers-reduced-motion:reduce){.why-found{animation:none;outline:2px solid var(--accent)}}
.why-verdict{white-space:nowrap}
.why-why{color:var(--muted)}
.why-code{display:block;margin-top:.2rem;font:.74rem/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;
  color:var(--ink);opacity:.65}
@media (max-width:52rem){.why-table .why-why{display:none}}
.mod-list{list-style:none;margin:1.2rem 0;padding:0;display:flex;flex-direction:column;gap:1.1rem}
.mod-item{border:1px solid var(--rule);border-radius:10px;padding:.9rem 1rem;background:var(--surface)}
.mod-meta{font:.76rem/1.4 system-ui,sans-serif;color:var(--muted);margin:0 0 .3rem}
.mod-reported{color:var(--ink)}
.mod-why{font:.8rem/1.4 system-ui,sans-serif;color:var(--muted);margin:0 0 .5rem;font-style:italic}
.mod-body{margin:0 0 .7rem;padding:.6rem .8rem;background:var(--wash);border-radius:7px;
  font-size:.95rem;line-height:1.55;white-space:pre-wrap;overflow-wrap:anywhere}
.mod-actions{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center}
.mod-actions input[type="text"]{flex:1;min-width:12rem;font:inherit;font-size:.85rem;
  padding:.4rem .6rem;border:1px solid var(--rule);border-radius:999px;background:var(--bg);color:var(--ink)}
/* A closed box is a decision, so it reads as a statement and not as an error. */
.discussion-closed .discuss-note{font-size:.88rem;max-width:62ch}
@media print{.overview-points li::before{opacity:1}}
.article-main .body p{max-width:68ch}
/* phone tab bar */
.tabbar{display:none}
@media (max-width:40rem){
  nav.site a.nav-main,nav.site .nav-search,nav.site .theme,.brand-lockup .tagline{display:none}
  /**
   * The section band holds nothing on a phone.
   *
   * Every one of its children — the eight section links, the search icon and
   * the theme buttons — is hidden at this width, so what was left was an empty
   * 17px bar with a rule under it, which read as a divider below the masthead
   * and cost a fiftieth of a 375px screen before a word of news. The bottom tab
   * bar carries Today, Brief, Local, Search, Chip in and You; the rest of those
   * links are in the footer, and the theme buttons are there too.
   */
  .navband{display:none}
  header.site .wrap{flex-wrap:nowrap}
  header.site{padding:.55rem 0;margin-bottom:.6rem}
  /* The name and the promise, with the air a phone can spare for them. */
  .masthead .wrap{padding-block:.7rem .6rem}
  /* The bar's own height, so anything that has to clear it can say so rather
     than guess. 48px of tap target plus the 4px padding either side. */
  :root{--tabbar:calc(56px + env(safe-area-inset-bottom))}
  .tabbar{display:grid;grid-template-columns:repeat(6,1fr);position:fixed;left:0;right:0;bottom:0;z-index:40;
    background:color-mix(in srgb,var(--bg) 94%,transparent);backdrop-filter:saturate(1.2) blur(10px);-webkit-backdrop-filter:saturate(1.2) blur(10px);
    border-top:1px solid var(--rule);padding:4px 4px calc(4px + env(safe-area-inset-bottom))}
  .tabbar a{display:flex;flex-direction:column;align-items:center;gap:2px;padding:6px 2px;min-height:48px;color:var(--muted);text-decoration:none;font:500 .66rem/1 system-ui,sans-serif}
  /* Six labels rather than five: the longest of them has to survive a 320px
     screen without wrapping into the icon above it. */
  .tabbar a span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  @media (max-width:22.5rem){.tabbar a{font-size:.6rem}}
  .tabbar a[aria-current="page"]{color:var(--accent)}
  body{padding-bottom:calc(64px + env(safe-area-inset-bottom))}
  :root{--gutter:1rem}
  /**
   * On a phone the article starts sooner.
   *
   * The headline used to be followed by the follow button, the share and text
   * size controls and the changes bar before a word of the report. The reading
   * comes first now and the tools move under it, which is the order a reader
   * uses them in anyway.
   */
  .article-main{display:flex;flex-direction:column}
  .article-main > h1{order:1}
  .article-main > .meta{order:2}
  .article-main > .topic-row{order:3}
  .article-main > figure.lead{order:4}
  /**
   * The overview goes where it is useful: above the report it summarises.
   *
   * It had no order of its own, so it fell into the catch-all at the bottom
   * and a phone showed five bullets covering the story UNDER the story, after
   * the changes bar and the follow button. The whole point of it is to be read
   * first.
   */
  .article-main > .overview{order:5}
  .article-main > .summary-block{order:6}
  /* The headline check stands in for the "Headline as published" line and
     takes its place in the order, so a phone reads: our headline, the summary,
     what they called it and whether that holds, then the report. Without an
     order of its own it would fall to the catch-all below and land under the
     footnote at the end of the article, which is nobody's question. */
  .article-main > .note,.article-main > .hcheck{order:7}
  .article-main > .section-label{order:8}
  .article-main > .body{order:9}
  .article-main > .short-note{order:10}
  .article-main > .changes-bar{order:11}
  .article-main > .follow-form{order:12}
  .article-main > .fulltext{order:13}
  .article-main > .source-foot{order:13}
  .article-main > .article-eyebrow{order:0}
  /* Reactions and the discussion are in .article-tail, which already follows
     .article-main, so they need no order of their own. Rules were written for
     them here first and did nothing at all. */
  .article-main > *{order:14}
  /**
   * The measure, on a phone.
   *
   * At 375px the report was 19.5px type in a 335px column, which is 37
   * characters a line, and the summarized version above it was 20.5px in a
   * 297px column, which is 32. Both are short enough that a sentence breaks
   * three or four times, and the two were within a point of each other, so the
   * summary did not read as the lede it is.
   *
   * The report comes down to 17.9px, which is about 42 characters and still
   * larger than the ABC, the Guardian or the Herald set their article text on a
   * phone. The summary keeps its size and gives back some of its padding, so it
   * stays plainly the larger of the two and gains a couple of characters.
   */
  .article-main > .body{font-size:1.12rem}
  .summary-block{padding:.95rem .9rem}
  /* Above the news, only what a reader needs: the sections on one scrolling
     line, the filters, and the reading mode. The explainer and the second
     place row belong further down on a screen this size. */
  .controls .chips{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
    margin-inline:calc(var(--gutter,1rem) * -1);padding-inline:var(--gutter,1rem)}
  .controls .chips::-webkit-scrollbar{display:none}
  /**
   * The word "Section" above the section chips, on a phone only.
   *
   * The chips run edge to edge on one scrolling line, so the label cannot share
   * their row and takes one of its own: 26px to say what "All / Good news /
   * Politics / Business" already says. None of the papers label that row. The
   * label is still read aloud, because a screen reader gets no help from the
   * chips being obviously chips. The labels inside Filters keep their place —
   * "Anywhere / NSW / VIC" does need saying that it means Place.
   */
  .controls > .filter-row > .filter-label{position:absolute;width:1px;height:1px;overflow:hidden;
    clip:rect(0 0 0 0);white-space:nowrap}
  .controls .filter-row + .filter-row{margin-top:.4rem}
  .filter-foot{font-size:.76rem;color:var(--muted)}
  .filter-foot .foot-note{display:none}
  /**
   * The List/Cards toggle and the story count share a line.
   *
   * On a 375px screen the page put 607 pixels of furniture in front of the
   * first headline, and 198 of them were this block: section chips, a filters
   * disclosure, a mode toggle on its own line, and a count on another. The
   * toggle and the count are both one short row's worth of content and there
   * is no reason they cannot sit together. Nothing is removed and nothing
   * moves on a larger screen.
   */
  .controls{padding:.2rem 0 .3rem}
  .mode-row{display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;margin:.45rem 0 0}
  .mode-row .feed-mode{margin:0}
  .mode-row .filter-foot{margin:0}
  #feed{margin-inline:calc(var(--gutter,1rem) * -1)}
  /**
   * Smaller on a phone. At 2.9rem the button was 46px on a 375px screen —
   * an eighth of the width, sitting over the story. The circle is 2.15rem
   * here and the part a thumb has to hit is still 44px, held by a
   * transparent ring rather than by the circle, so the target meets WCAG
   * 2.5.8 while the thing a reader sees is two thirds the size.
   */
  .to-top{bottom:calc(72px + env(safe-area-inset-bottom));width:2.15rem;height:2.15rem;
    box-shadow:0 3px 10px -4px rgba(22,21,15,.45)}
  .to-top svg{width:17px;height:17px}
  .to-top::before{content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;
    transform:translate(-50%,-50%)}
  /**
   * On a phone the feed is one lead and then a list.
   *
   * Every card used to fill the screen, so forty stories were forty screens
   * with nothing to scan and no sense of which mattered. The lead keeps its
   * picture; the rest become rows with a thumbnail, which is how every news
   * front page on a phone works, and the whole front page now fits in about
   * eight screens instead of forty.
   *
   * Every rule below is held to list mode by the html:not() in front of it.
   * They used to be written as plain #feed rules, and because
   * "#feed .card:not(.card-lead) …" outweighs
   * "html[data-feed=cards] #feed .card …" — the :not() counts as a class, and
   * that is one more than the attribute selector — the list quietly won inside
   * the one-story-a-screen mode. Every card after the first showed a 92px-wide
   * strip of photograph down the side of the screen, its summary set to
   * display:none and its text against the edge with no gutter. The two modes
   * can no longer reach each other.
   */
  html:not([data-feed="cards"]) #feed{display:block}
  /* The lead's picture runs to both edges; everything else keeps the page's
     gutter, so no text ever touches the side of the screen. */
  html:not([data-feed="cards"]) #feed .card{border-left:0;border-right:0;border-radius:0;box-shadow:none;background:none;
    padding-inline:var(--gutter,1rem)}
  html:not([data-feed="cards"]) #feed .card-lead{padding-inline:0}
  html:not([data-feed="cards"]) #feed .card-lead .card-body{padding-inline:var(--gutter,1rem)}
  html:not([data-feed="cards"]) #feed .card + .card{border-top:1px solid var(--rule)}
  html:not([data-feed="cards"]) #feed .card:not(.card-lead){display:grid;grid-template-columns:1fr 92px;gap:.7rem;
    align-items:start;padding:.85rem 0}
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) .card-pic{grid-column:2;grid-row:1;aspect-ratio:1;border-radius:8px;
    width:92px;height:92px;overflow:hidden}
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) .card-body{grid-column:1;grid-row:1;padding:0}
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) h3{margin:.15rem 0 .3rem;
    display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) .card-sum{display:none}
  /**
   * BRIEF: the card is the story.
   *
   * Everything above is the list, which is a scanning layout — a thumbnail, a
   * headline, and the summary hidden because forty summaries is not a list any
   * more. Brief is the opposite choice: the whole summary on every card, no
   * clamp, so a reader goes down the feed and is done without opening
   * anything.
   *
   * The headline stays a link. The indicators, the overview, "show what we
   * removed" and the link to the original are all still behind it, and a card
   * that led nowhere would be hiding those rather than replacing them.
   */
  html[data-feed="brief"] #feed .card:not(.card-lead) .card-sum{display:block;
    -webkit-line-clamp:none;overflow:visible;margin-top:.45rem}
  html[data-feed="brief"] #feed .card:not(.card-lead){grid-template-columns:1fr 64px;padding:1rem 0}
  html[data-feed="brief"] #feed .card:not(.card-lead) .card-pic{width:64px;height:64px}
  html[data-feed="brief"] #feed .card:not(.card-lead) .card-body{grid-column:1;grid-row:1}
  /* The summary runs the full width, under the thumbnail rather than beside
     it, because 240px of column is not a paragraph. */
  html[data-feed="brief"] #feed .card:not(.card-lead) .card-sum{grid-column:1 / -1;grid-row:2}
  html[data-feed="brief"] #feed .card:not(.card-lead) .card-foot{grid-column:1 / -1;grid-row:3}
  html[data-feed="brief"] #feed .card:not(.card-lead) h3{-webkit-line-clamp:none;overflow:visible}
  html[data-feed="brief"] #feed .card:not(.card-lead) .pic-tag{display:none}
  /* A 28px button on a 64px thumbnail covers half of it. */
  html[data-feed="brief"] #feed .card:not(.card-lead) .card-share{min-width:24px;height:24px;bottom:.2rem;right:.2rem}
  html[data-feed="brief"] #feed .card:not(.card-lead) .card-share svg{width:13px;height:13px}
  /**
   * NOT HERE: the four reaction buttons.
   *
   * They were asked for on the card and they belong on the article. Every one
   * of them says something about the READING — whether it was clear, whether
   * you learned something, whether something is missing — and a reader who has
   * seen only the summary has not read the article yet. A reaction collected
   * here would be a reading of the summary filed as a reading of the report,
   * which is worse than no reaction at all, because the counts are the thing
   * we would act on. Share is different: a reader can want to send somebody a
   * story without having finished it.
   */
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) .pic-tag{display:none}
  /* A list row's body column is about 240px wide. The Good news and Summary
     tags push themselves to the right on a full-width card, which in that
     column is enough to break the foot onto a second line and make a row two
     lines of furniture under two lines of headline. Here they sit with the
     rest, and the whole foot is one quiet line. */
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) .card-foot{margin-top:.3rem;padding-top:.45rem;gap:.5rem}
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) .card-foot .good-tag,
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) .card-foot .brief-tag{margin-left:0}
  /* A list row's picture is a 92px thumbnail, so the button is smaller and
     sits in the bottom corner rather than the top one: a thumbnail is a crop,
     and the bottom corner is the part of a crop least likely to hold the face
     or the subject. Its hit area is widened past its ink by the rule in the
     main sheet, which is what keeps it thumb-sized at this size. */
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) .card-share{top:auto;bottom:.3rem;right:.3rem;
    min-width:28px;height:28px;padding:0}
  /* Confirming the copy matters more than the thumbnail does for the second
     it takes to say it, so the pill grows leftwards across the picture rather
     than being suppressed. It is anchored on its right edge, so it grows on
     its own; 85px of words fit inside a 92px thumbnail. */
  html:not([data-feed="cards"]) #feed .card:not(.card-lead) .card-share.is-copied{padding:0 .45rem}
  /* A 16/9 lead picture is 211px of a 375px screen, and with the strips above
     it that put the lead story's headline under the tab bar. 2/1 is the crop
     the wide layout already uses, and the 24px it gives back are the 24px that
     decide whether a reader sees the day's main headline without scrolling. */
  html:not([data-feed="cards"]) #feed .card-lead .card-pic{aspect-ratio:2/1}
  html:not([data-feed="cards"]) #feed .card-lead{padding-bottom:1rem}
  html:not([data-feed="cards"]) #feed .card-lead .card-body{padding:.9rem var(--gutter,1rem) 0}
  html:not([data-feed="cards"]) #feed .card-lead .card-sum{-webkit-line-clamp:3;display:-webkit-box;
    -webkit-box-orient:vertical;overflow:hidden}
  .chip{min-height:40px}
  /**
   * The Brief strip reads as a sentence on a phone rather than as two columns.
   *
   * "The Daily Brief" sat in its own column with the arrow in a third, which
   * left the description about 200px to wrap in and made it three lines and the
   * strip 106px tall. Wrapping the name into the same paragraph gives the words
   * the whole width, and the same sentence takes two lines.
   */
  .brief-strip{display:block;position:relative;padding:.7rem 2.2rem .75rem .9rem;margin:.4rem 0 1rem}
  .brief-strip .brief-strip-k{display:inline;margin-right:.35rem}
  .brief-strip span:nth-child(3){position:absolute;right:.9rem;top:50%;transform:translateY(-50%);color:var(--muted)}
}
@media (prefers-reduced-motion: reduce){*,*::before,*::after{transition:none!important;animation:none!important;scroll-behavior:auto!important}}

:root{--font-serif:"Source Serif 4",Charter,"Iowan Old Style",Georgia,serif;--font-sans:system-ui,-apple-system,"Segoe UI",sans-serif;--font-mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,"DejaVu Sans Mono",monospace}
::selection{background:var(--sage);color:var(--ink)}
:focus-visible{outline:3px solid var(--focus);outline-offset:3px}

/* A page's headline grows with the screen, as the kit's do: 32px on a phone,
   39px on a laptop. The article's own and the introductory pages' are larger
   again and set where those are. */
h1{font-size:clamp(2rem,1.45rem + 1.5vw,2.45rem)}

/* The eyebrow, and every label that already worked as one: the name of a
   section, a panel, a table's columns or a form's fields. The tiniest labels
   — a dial's two ends, a picture's corner tag, a warning level — stay in the
   sans, where the wider monospace would not fit the space they were drawn
   for. Rules that a page inlines after this sheet (the Brief, the lists, the
   local page) set the same face at their source. */
.eyebrow,.section-label,.panel-title,.footer-cols h2,.filter-label,
.account-sub,.auth-pair h2,.plan-name,.key-label,.contribute legend,.our-version h2,.hcheck h2,.media-prov,.media-shot{
  font-family:var(--font-mono);font-weight:500;text-transform:uppercase;letter-spacing:.14em}
table.grid th,table.cmp th,.board th,.account-form label,.auth-pair label,.other-amount label,.step-dir,.sib-src{
  font-family:var(--font-mono);font-weight:500;letter-spacing:.08em}
.eyebrow{display:block;font-size:.72rem;line-height:1.5;color:var(--accent);margin:0 0 .6rem}
.section-label,.panel-title,.footer-cols h2,.filter-label{font-size:.68rem}
/* A place above a headline is where a paper puts its dateline, and in the kit
   it is an eyebrow in forest: LOCAL / TRANSPORT. The card rule it overrides
   is written with two classes, so this one is too. */
.dateline,.card-meta .dateline{font-family:var(--font-mono);font-weight:500;font-size:.66rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--accent)}
.type-tag{font-family:var(--font-mono);font-weight:500;letter-spacing:.1em}

/* Links in running text are forest and stay underlined, as the kit asks. The
   selector weighs no more than the base sheet's "a", so any component that
   sets its own link colour keeps it. */
:where(p,li,dd,figcaption,blockquote,td) a:where(:not([class])){color:var(--accent);
  text-decoration-thickness:1px;text-underline-offset:.18em}
:where(p,li,dd,figcaption,blockquote,td) a:where(:not([class])):hover{text-decoration-thickness:2px}

/* ── the masthead ─────────────────────────────────────────────────────── */
/* The header's own padding and rule were the frame of an older masthead; with
   the ink rule under the bands they drew a second, fainter line beneath it and
   a sliver of empty page above the date. */
header.site{padding:0;border-bottom:0}
.topbar{background:var(--bg)}
.tb-date{font-family:var(--font-mono);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase}
.tb-sub{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
.tb-sub:hover{background:color-mix(in srgb,var(--accent) 86%,var(--ink));border-color:transparent;color:var(--accent-ink)}
.masthead .wrap{padding-block:1.35rem 1.2rem}
/* The lockup is the name: the link around it carries "Mundane Read, home" and
   the drawing is hidden from assistive technology. Its clear space is the
   kit's one capital M, which at this size is about 1.3rem. */
.masthead .brand{display:block;line-height:0;color:var(--ink);border-radius:4px}
.brand-lockup{display:block;width:clamp(280px,26vw,372px);height:auto;aspect-ratio:4105/685}
.masthead .tagline{display:none}
.navband{border-bottom:1px solid var(--rule-ink)}
nav.site a[aria-current="page"]{box-shadow:inset 0 -2px 0 var(--accent)}
@media (max-width:40rem){
  .masthead{border-bottom:1px solid var(--rule-ink)}
  .masthead .wrap{padding-block:1rem .9rem}
  .brand-lockup{width:min(100%,330px)}
}

/* ── actions ──────────────────────────────────────────────────────────── */
/* The one thing a form asks for is a forest pill, the kit's button. Choices,
   toggles and pressed states stay in ink: those say what is selected, not
   what to do next. */
.btn-primary,.cool-form button,.search-form button,.search-inline button,.account-form button:not(.secondary),
.pref-actions button:not(.secondary),.plan button,.plan .plan-cta,.key-box button,.auth-pair button,.contribute button{
  background:var(--accent);color:var(--accent-ink);border:0;border-radius:999px;
  font:600 .95rem/1.2 var(--font-sans);padding:.72rem 1.25rem;cursor:pointer;text-decoration:none}
.btn-primary{display:inline-flex;align-items:center;justify-content:center;min-height:44px}
.btn-primary:hover,.cool-form button:hover,.search-form button:hover,.search-inline button:hover,.account-form button:not(.secondary):hover,
.pref-actions button:not(.secondary):hover,.plan button:hover,.plan .plan-cta:hover,.key-box button:hover,.auth-pair button:hover,.contribute button:hover{
  background:color-mix(in srgb,var(--accent) 86%,var(--ink));opacity:1}
.account-form button.secondary,.pref-actions button.secondary{border-radius:999px}

/* ── panels ───────────────────────────────────────────────────────────── */
/* Sage is for the panels that explain: the short version of a story, what
   kind of day it is, what the reader is looking at. */
.summary-block,.day-reading,.fulltext,.topic-hint{background:var(--sage);border-color:transparent}
.day-reading,.day-reading.is-heavy,.day-reading.is-light{border:0;border-left:3px solid var(--accent)}
.summary-block{border-radius:10px}
.card,.plan,.cool-score,.status-item{background:var(--surface)}
.good-tag{color:var(--happy);background:var(--happy-soft)}
/* A chip is one pill on one line. In the row of sections that scrolls
   sideways on a phone, "Good news" was being squeezed onto two. */
.chip{white-space:nowrap;flex:none}
/* The two strips above the stories that are links — the reader's town and the
   Daily Brief — are the same white card; only the one that explains, what
   kind of day it is, is sage. A warning still turns the town's border clay. */
.place-strip{background:var(--surface)}
/* The Daily Brief strip wears the newsletter's mark: a forest page of lines. */
.brief-strip{background:var(--surface);border:1px solid var(--rule)}
.brief-strip:hover{background:var(--surface);border-color:var(--ink)}
/* Spaced by a margin rather than a gap: on a phone the label is set inline, where a gap does nothing. */
.brief-strip-k{color:var(--accent);display:inline-flex;align-items:center}
.brief-strip-k::before{margin-right:.55rem;vertical-align:-.3em}
/* The page itself: a forest sheet with five ruled lines, as the banner has it. */
.brief-strip-k::before,.brief-icon{content:"";flex:none;display:inline-block;width:1.05rem;height:1.3rem;border-radius:3px;background:
  linear-gradient(var(--accent-ink),var(--accent-ink)) 50% 24%/66% 1px no-repeat,
  linear-gradient(var(--accent-ink),var(--accent-ink)) 50% 37%/66% 1px no-repeat,
  linear-gradient(var(--accent-ink),var(--accent-ink)) 50% 50%/66% 1px no-repeat,
  linear-gradient(var(--accent-ink),var(--accent-ink)) 50% 63%/66% 1px no-repeat,
  linear-gradient(var(--accent-ink),var(--accent-ink)) 50% 76%/66% 1px no-repeat,var(--accent)}
.brief-head{margin:0 0 1rem}
.brief-head .brief-date{margin:0 0 .7rem}
.brief-title{display:flex;align-items:center;justify-content:space-between;gap:1rem;border-top:1px solid var(--rule-ink);padding-top:1rem}
.brief-title h1{font-size:clamp(2.4rem,1.6rem + 3vw,3.6rem);line-height:1.02;letter-spacing:-.025em;margin:0}
.brief-icon{width:3.2rem;height:3.9rem;border-radius:6px;background-size:66% 1.5px,66% 1.5px,66% 1.5px,66% 1.5px,66% 1.5px}
.brief-tagline{font:1.15rem/1.4 var(--font-sans);margin:.5rem 0 0;color:var(--ink)}
@media (max-width:40rem){.brief-icon{width:2.4rem;height:2.9rem}}

/* ── the welcome ─────────────────────────────────────────────────────── */
/* Shown once, to somebody who has not been here, and gone for good on "Got
   it". Text on the left, where the drawing leaves its paper empty for it; on
   a phone the kit says to stack the reader below the heading rather than
   squeeze the words over her. */
.welcome{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.95fr);align-items:center;gap:1rem 2rem;
  margin:0 0 1.6rem;padding:0 0 1.2rem;border-bottom:1px solid var(--rule)}
.welcome[hidden]{display:none}
.welcome-h{font:700 clamp(2rem,4.2vw,3.35rem)/1.06 var(--font-serif);letter-spacing:-.025em;margin:0 0 1rem}
.welcome-lede{font-size:1.1rem;line-height:1.6;max-width:34rem;margin:0 0 1.3rem}
.welcome-do{display:flex;align-items:center;flex-wrap:wrap;gap:.6rem 1.2rem;margin:0;font:.95rem var(--font-sans)}
.welcome-close{font:600 .9rem var(--font-sans);background:none;border:0;padding:.5rem .2rem;color:var(--muted);
  text-decoration:underline;text-underline-offset:.2em;cursor:pointer;min-height:44px}
.welcome-close:hover{color:var(--ink)}
.welcome-art{margin:0;justify-self:end;width:100%;max-width:520px}
.welcome-art img{display:block;width:100%;height:auto}
.welcome-h span{display:block}
/* The drawing's paper is the page's paper give or take a grain, but a
   rectangle of grain on flat colour still shows its edge. Feathered, it is
   drawn on the page rather than pasted onto it. */
.art img,.welcome-art img{
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 5%,#000 96%,transparent),linear-gradient(transparent,#000 4%,#000 96%,transparent);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(90deg,transparent,#000 5%,#000 96%,transparent),linear-gradient(transparent,#000 4%,#000 96%,transparent);
  mask-composite:intersect}
/* Side by side down to a phone: stacked on a tablet, the drawing sat alone and
   centred under a column of left-aligned words and the welcome filled the
   screen. On a phone the drawing is held under 300px so the stories start
   within a thumb of it. */
@media (max-width:40rem){
  .welcome{grid-template-columns:1fr}
  .welcome-art{justify-self:start;max-width:300px}
}

/* ── illustration, anywhere ──────────────────────────────────────────── */
/* The drawings are printed on the same paper as the page, so in the light
   theme their edges vanish into it. On a dark page that paper would be a
   bright box with no edge, so it becomes a print with a margin and corners. */
.art img{display:block;width:100%;height:auto}
:root[data-theme="dark"] .art img,:root[data-theme="dark"] .welcome-art img{border-radius:12px;-webkit-mask-image:none;mask-image:none}
@media (prefers-color-scheme: dark){:root[data-theme="auto"] .art img,:root[data-theme="auto"] .welcome-art img{border-radius:12px;-webkit-mask-image:none;mask-image:none}}

/* ── the article ──────────────────────────────────────────────────────── */
/* The source stays in view (the kit's article design): after the report, one
   ink rule and the two ways out — the original, and what we changed. */
.source-foot{margin:2.2rem 0 0;padding:1rem 0 0;border-top:1px solid var(--rule-ink);display:flex;flex-wrap:wrap;
  gap:.6rem 2.4rem;font:1rem/1.4 var(--font-sans)}
.source-foot a{color:var(--accent);text-underline-offset:.2em}
.source-note{margin:.9rem 0 0;font:.88rem/1.5 var(--font-sans);color:var(--muted)}

/* ── introductory pages ──────────────────────────────────────────────── */
/* The kit's introductory page: an eyebrow, a large serif headline and a
   standfirst on the left, the drawing on the right; stacked on a phone, with
   the drawing under the words. */
.page-hero{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);align-items:center;gap:1rem 2.5rem;
  margin:0 0 2rem;padding:0 0 1.5rem;border-bottom:1px solid var(--rule)}
.page-hero h1{font-size:clamp(2.2rem,4.6vw,3.4rem);line-height:1.06;letter-spacing:-.025em;margin:0 0 1rem}
.page-hero .page-lede{font-size:1.12rem;line-height:1.6;color:var(--ink);max-width:36rem;margin:0}
.page-hero-art{margin:0;justify-self:end;width:100%;max-width:500px}
@media (max-width:40rem){.page-hero{grid-template-columns:1fr}.page-hero-art{justify-self:start;max-width:340px}}

/* The punctuation animation (settleFigure), on a five-second loop: the three
   marks for a moment, the stems fold up and the outer dots slide in over the
   middle one, the full stop holds, and the marks come back. */
.settle{margin:2rem 0;padding:1.4rem 1.2rem 1rem;background:var(--sage);border-radius:10px;text-align:center}
.settle svg{display:block;width:100%;max-width:420px;height:auto;margin:0 auto}
.settle g{fill:var(--accent)}
.settle .stem{transform-box:fill-box;transform-origin:top}
.settle .stem{animation:settle-stem 5s ease-in-out infinite}
.settle .dot1{animation:settle-left 5s ease-in-out infinite}
.settle .dot3{animation:settle-right 5s ease-in-out infinite}
@keyframes settle-stem{0%,16%{transform:scaleY(1);opacity:1}44%,84%{transform:scaleY(0);opacity:0}100%{transform:scaleY(1);opacity:1}}
@keyframes settle-left{0%,16%{transform:translateX(0)}44%,84%{transform:translateX(90px)}100%{transform:translateX(0)}}
@keyframes settle-right{0%,16%{transform:translateX(0)}44%,84%{transform:translateX(-90px)}100%{transform:translateX(0)}}
.settle.is-paused .stem,.settle.is-paused .dot1,.settle.is-paused .dot3{animation-play-state:paused}
@media (prefers-reduced-motion: reduce){.settle .stem{display:none}.settle .dot1{transform:translateX(90px)}.settle .dot3{transform:translateX(-90px)}}
.settle figcaption{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:.4rem .8rem;margin-top:.8rem;
  font:.9rem/1.4 var(--font-sans);color:var(--ink)}
/* Pause: there, and quiet. */
.motion-pause{font:600 .78rem var(--font-sans);padding:.35rem .8rem;min-height:36px;border-radius:999px;cursor:pointer;
  border:1px solid var(--rule);background:var(--surface);color:var(--muted)}
.motion-pause:hover{border-color:var(--accent);color:var(--accent)}
.motion-pause[hidden]{display:none}

/* The method page's three characters: a row of three, and on a phone a list
   with each drawing beside its line. */
.cast{margin:1.8rem 0 2.2rem}
.cast-list{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.4rem}
.cast-list .art{display:block}
.cast-list p{font:.9rem/1.5 var(--font-sans);margin:.7rem 0 0}
.cast figcaption{font:.8rem/1.45 var(--font-sans);color:var(--muted);margin:1rem 0 0}
@media (max-width:40rem){
  .cast-list{grid-template-columns:1fr;gap:1rem}
  .cast-list li{display:grid;grid-template-columns:6.5rem minmax(0,1fr);gap:1rem;align-items:center}
  .cast-list p{margin:0}
}

/* The kit's "short version": the sage panel that says the story in brief.
   Here that is the overview where there is one, and the summary where there
   is not; a summary directly under an overview is not boxed a second time. */
.overview{background:var(--sage);border-radius:10px;padding:1rem 1.2rem .9rem;margin:1.2rem 0 1rem}
.overview .summary-how{margin-bottom:0}
.overview + .summary-block{background:none;padding:0 .1rem;border-radius:0}
/* At the page's 18px the bullets ran 78 characters to the line across the
   panel; at the report's own reading size they run about 73. */
.overview-points{font-size:1.2rem}
@media (max-width:40rem){.overview-points{font-size:1.12rem}}
/* The heading over the report itself is a heading, as the kit sets "The
   report, in plain language" — not one more label in capitals. */
.section-label.report-head{font:700 1.45rem/1.2 var(--font-serif);text-transform:none;letter-spacing:-.012em;
  color:var(--ink);margin:1.8rem 0 .8rem}
.section-label.report-head::after{display:none}

/* A drawing set beside the opening words of a page rather than above them. */
.spot-art{float:right;width:min(32%,12rem);margin:.2rem 0 1rem 1.6rem}
@media (max-width:40rem){.spot-art{width:7.5rem;margin-left:1rem}}

/* The sign-in, account, paywall and not-found pages are set in the sans, and
   their headline went with it, in the muted grey. A page headline is the serif, in
   ink, on every page. */
.empty h1{font-family:var(--font-serif);color:var(--ink)}

/* ── the footer ───────────────────────────────────────────────────────── */
footer.site{border-top:1px solid var(--rule-ink)}
.footer-sign{display:flex;align-items:center;gap:.7rem;margin:0 0 1rem;font:500 .72rem/1.4 var(--font-mono);
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.footer-sign .brand-mark{width:2rem;height:2rem;color:var(--ink)}
