/* news.css — magazine editorial layout for /news.
   The rest of the site is an instrument panel: mono labels, hairlines, tabular figures. A
   newsroom should not be. This sheet is the ONE place the site uses editorial proportion —
   a lead well, a two-up, then a river — and the display face is allowed to run large because
   a headline is the whole point of the page. */
/* THE PAGE OPENED ON 217px OF NOTHING, AND THE CAUSE WAS TWO PADDINGS, NOT ONE.
   `.news-hero` sits directly inside a bare `<main class="news"> <section>`, so it takes
   base.css `section{padding:clamp(64px,9vw,132px) 0}` AND its own top padding, and the two
   stack. Measured on the live site, header-bottom to the first character of the kicker:

       1280   115.2 + 76.8  = 192   ->  193px of empty navy before the first word
       1440   129.6 + 86.4  = 216   ->  217px
       1920   132.0 + 88.0  = 220   ->  221px

   That is 24% of a 900px first screen spent above the first character, and it is the
   worst opening band on the site by a factor of ~2.6: every other page measured
   77-146px (the instrument pages 77-84, company/careers 117-124, contact 132-146).
   Confirmed three independent ways — the ink map, the computed padding sum above, and a
   screenshot of the band.

   Cured by removing the DUPLICATE, not by trimming the intended one: the wrapping
   section's top padding goes, `.news-hero`'s own 46-88px stays, and the opening band
   lands at 77-88px — the same place the instrument pages open. Scoped to the first
   section of `main.news` so the river and the closing section keep the site's normal
   section rhythm. `berita.html` shares this markup exactly and is cured by the same rule.
   Bottom padding is untouched: it is the only separation from the lead well. */
main.news > section:first-of-type{padding-top:0}
.news-hero{padding:clamp(46px,6vw,88px) 0 clamp(28px,3vw,44px);border-bottom:1px solid var(--hairline)}
.news-hero h1{margin:0;font-family:var(--f-display);font-weight:420;
  font-size:clamp(44px,8.4vw,120px);line-height:.92;letter-spacing:-0.0102em}
.news-hero .kicker{margin:0 0 18px;font-family:var(--f-mono);font-size:13px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--signal-gold)}
.news-hero .stand{margin:22px 0 0;max-width:56ch;font-size:19px;line-height:1.55;color:var(--ink-muted)}

.lead{display:grid;grid-template-columns:1.35fr 1fr;gap:clamp(24px,3vw,52px);
  padding:clamp(34px,4vw,60px) 0;border-bottom:1px solid var(--hairline);align-items:start}
.lead figure{margin:0;position:relative;overflow:hidden;aspect-ratio:4/5;background:var(--device-recess);
  border:1px solid var(--hairline)}
.lead figure img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 1.1s var(--e-quart)}
.lead a:hover figure img,.riv a:hover figure img{transform:scale(1.04)}
/* Same inversion as the river tokens above, in its purest form. `.lead` is a 1.35fr/1fr
   grid inside the capped `.wrap`, so this headline's column is effectively FIXED across
   desktop — measured 457 / 455 / 451px at 1280 / 1440 / 1920 — while `3.6vw` kept pushing
   the type up: 46.08 / 51.84 / 52.00px. Constant box, growing type, so the measure fell
   16.7ch -> 14.8ch -> 14.6ch (28 -> 21 -> 21 characters to a line). The reader with the
   widest screen got the most cramped lead headline on the site.
   3.6vw reaches 52px only at 1444px, well past the 1368px where `.wrap` stops growing; 49px
   is the value it holds at the cap, so the type now stops growing exactly where its column
   does. Below 1368 nothing changes. */
.lead h2{margin:14px 0 0;font-family:var(--f-display);font-weight:420;
  font-size:clamp(28px,3.6vw,49px);line-height:1.02;letter-spacing:-0.0075em}
.lead .stand{margin:16px 0 0;font-size:17px;line-height:1.6;color:var(--ink-muted);max-width:48ch}

.meta{display:flex;flex-wrap:wrap;gap:10px 16px;align-items:center;
  font-family:var(--f-mono);font-size:12px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-subtle)}
.cat{color:var(--crude-amber);border:1px solid rgba(200,136,40,.42);border-radius:2px;padding:5px 9px}
/* `.meta` is a wrapping flex row and its own character count is meaningless — but a single
   CHIP inside it has a measure, and this one has no cap: the four-masthead source tag ("The
   Star · Asia News Network · Nanyang Siang Pau · OFI Magazine") ran 91.6ch over two lines at
   every desktop width, on news and berita alike. 64ch of 12px mono is 461px; with .13em
   tracking that is 49 characters to a line, and the tag wraps between mastheads instead of
   mid-name. Capped on the chip, not the row, for the same reason proof.css caps
   `.plate figcaption>*` rather than the figcaption. */
/* Sentence case: this chip is a list of MASTHEADS — "The Star · Asia News Network ·
   Nanyang Siang Pau · OFI Magazine" — and uppercase erased the capitalisation that tells a
   reader they are proper names. 86 characters at the widest. It inherits .meta's uppercase
   and .13em, so both are undone here; the measure cap above was calculated at .13em and is
   left alone because a tighter track can only shorten the line, never lengthen it. */
.src-tag{color:var(--ink-ghost);max-width:min(100%,64ch);
  text-transform:none;letter-spacing:.02em}

.nw-two{display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,3vw,48px);
  padding:clamp(30px,3.4vw,52px) 0;border-bottom:1px solid var(--hairline)}
.nw-two h3{margin:12px 0 0;font-family:var(--f-display);font-weight:420;
  font-size:clamp(22px,2.3vw,32px);line-height:1.06;letter-spacing:-0.0051em}
.nw-two figure{margin:0;aspect-ratio:4/5;overflow:hidden;background:var(--device-recess);border:1px solid var(--hairline)}
.nw-two figure img{width:100%;height:100%;object-fit:cover;display:block}

.riv{padding:clamp(28px,3vw,46px) 0 0}
.riv article{display:grid;grid-template-columns:112px 1fr auto;gap:clamp(16px,2vw,34px);
  padding:26px 0;border-bottom:1px solid var(--hairline);align-items:baseline}
.riv .when{font-family:var(--f-mono);font-size:12px;letter-spacing:.11em;color:var(--ink-subtle);
  text-transform:uppercase;white-space:nowrap}
.riv h3{margin:0;font-family:var(--f-display);font-weight:420;font-size:clamp(19px,1.9vw,26px);
  line-height:1.16;letter-spacing:-0.0041em}
.riv .stand{margin:8px 0 0;font-size:15.5px;line-height:1.6;color:var(--ink-muted);max-width:62ch}
.riv .nw-go{font-family:var(--f-mono);font-size:12px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-ghost);white-space:nowrap}
.riv a:hover .nw-go{color:var(--signal-gold)}

/* `.news a` (0,1,1) out-specifies `.btn-primary` (0,1,0), so a blanket colour:inherit here
   silently repaints any button placed inside the section — measured on the news hero CTA as
   #F4F6F8 on #FFD658, 1.29:1, effectively invisible. shell.css:58 already carries this exact
   bug and its fix for `nav.main a`; this is the same trap, met a second time in a new file.
   Excluding buttons at the source beats bolting on another override, because the next
   component dropped into this section inherits the fix instead of the bug. */
.news a:not(.btn){color:inherit;text-decoration:none;display:block}
.news a:focus-visible{outline:2px solid var(--signal-gold);outline-offset:4px}

@media (max-width:900px){
  .lead,.nw-two{grid-template-columns:1fr}
  .lead figure{aspect-ratio:3/2}
  .riv article{grid-template-columns:1fr;gap:8px}
  .riv .nw-go{display:none}
}
@media (prefers-reduced-motion:reduce){ .lead figure img,.nw-two figure img{transition:none} }

/* River thumbnails. The river was text-only, which read as a footnote list rather than a
   continuation of the same magazine. A 4:5 thumb at the head of each entry keeps the rhythm
   without competing with the lead. */
.riv article{grid-template-columns:96px 92px 1fr auto}
.riv figure{margin:0;aspect-ratio:4/5;overflow:hidden;background:var(--panel-navy);
  border:1px solid var(--hairline)}
.riv figure img{width:100%;height:100%;object-fit:cover;display:block}
@media (max-width:900px){
  .riv article{grid-template-columns:74px 1fr;gap:14px}
  .riv article>figure,.riv article>a>figure{grid-row:span 2}
  .riv .when{grid-column:2}
  .riv .nw-go{display:none}
}

/* LEAD BALANCE. A 4:5 lead photograph is 1.25x as tall as it is wide, and the standfirst
   beside it runs about a third of that — measured at 1440 the text column ended 380px above
   the frame, leaving a hole the eye reads as a mistake. Cap the frame's height against the
   text rather than the other way round (shrinking the text to fit a photo is the wrong
   trade) and hang the column from the top so headline and frame share a baseline.

   SCOPED TO DESKTOP (2026-08-26). This rule carried no media query, and at (0,1,1)
   it is the same specificity as `.lead figure{aspect-ratio:3/2}` forty lines above
   inside `@media (max-width:900px)` — a media query adds no specificity, so being
   later in the file made THIS rule win at every width and the 3:2 one dead code.
   The consequence was measurable, not theoretical: at 390px `36vw` is 140px, the
   clamp floors it at 340px, so the figure renders 350x340 and the picture inside
   it 348x338 — square. The file is mill-instrument.jpg at 1440x810 (16:9), so
   cover threw away 42.1% of it; the crop kept the panel but cut the operator down
   to a disembodied hand. Restoring the authored 3:2 at <=900px measures 15.5% and
   puts his shoulder back in the frame. The balance argument
   above only ever applied to the two-column desktop lead; on one column there is no
   text beside the frame to balance against. */
.lead{align-items:start}
@media (min-width:901px){
  .lead figure{aspect-ratio:auto;height:clamp(340px,36vw,440px)}
}
.lead figure img{width:100%;height:100%;object-fit:cover;object-position:50% 45%}
.lead>div{padding-top:2px}
/* TWO-UP BREATHING. The meta line sat hard against the photo's bottom edge and the
   standfirst ran straight on from the headline; at 15.5px that read as a caption block
   rather than two separate pieces of information. */
.nw-two figure{margin-bottom:16px}
.nw-two h3{margin:6px 0 8px}
.nw-two .stand{margin:0}
.nw-two .meta{margin-bottom:0}

/* The picture line sits in a fixed slot so the two-up row keeps its captions on one baseline.
   Without this, a card carrying the line dropped ~30px below one that did not — visible in the
   rendered page, invisible to every check. min-height, not a grid row, because the river and
   the lead use the same line at different widths. */
/* 11px -> 12.5px, the `.stat .src` third pass in base.css applied to the news sheet's own
   citation class. This one carries the longest citation on the site: the river's lead row
   runs 183 characters ("Twenty-two items from nineteen mastheads — fifteen newsrooms, once
   a paper's TV arm is counted…"), which is a paragraph, not a caption. `.nw-two .src` keeps
   its 36px min-height below — that floor exists to level two cards whose citations differ in
   length, and a taller line only makes it inert on the cards that already wrap. */
.src{font:500 12.5px/1.55 var(--f-mono);letter-spacing:.02em;color:var(--ink-ghost);
  margin:10px 0 0}
.nw-two .src{min-height:36px;margin:10px 0 12px}
.lead .src{margin-top:14px}
@media (max-width:900px){ .nw-two .src{min-height:0} }
/* "Part 1 ↗" / "Part 2 ↗" — the links to the two Edge pieces every Minsawi figure on this
   site is sourced from — measured 350x16 at 390px CSS px (is_mobile + has_touch,
   2026-08-26), under the tap-target floor, and stacked ~32px apart so the dead space
   between them was as tall as the targets themselves. 4 of these across news + ms/berita.

   A `.src a` rule sat HERE and has been REMOVED rather than left beside the `.lead .src a`
   rule near the bottom of this file, which now carries that floor. Two rules for the same
   two elements is the exact trap proof.css documents on `.bnote summary`: a floor set in
   two places, where the more specific one silently wins and the other rots unnoticed —
   and these disagreed on `display` (block here, flex there), so the loser was invisible.
   Measured before removing, both languages: `.src a` = 2 and `.lead .src a` = 2, with
   ZERO outside `.lead`, and news.css is loaded by news.html + ms/berita.html only — so
   the surviving rule covers every element this one did. One owner. */

/* ── LAUNCH EVENT STRIP ──────────────────────────────────────────────────────
   The river's other entries carry ONE 96px thumbnail because they are single
   reports. The launch is not a report, it is a day, and AIREI photographed five
   moments of it with their own captions — so this entry gets a strip. The
   captions are printed exactly as the company profile prints them; the
   attribution line says so, because a caption is a claim like any other. */
/* `.riv article` is a THREE-column grid (112px date | 1fr | auto) built for a one-line
   report with a 96px thumb. This entry is a photo essay and has two children, so it
   inherited that template and rendered its standfirst one word per line. It opts out of
   the river grid entirely rather than fighting it column by column. */
.riv article.ev-lead{display:block;border-bottom:1px solid var(--hairline-strong);
  padding:26px 0 30px}
.riv .ev-lead .when{display:block;margin-bottom:10px}
.riv .ev-lead .stand{max-width:68ch}
/* FIVE photographs do not divide into four columns, and auto-fit left one hanging alone on
   a second row. Rather than crop the set to fit a grid, the set gets an editorial shape: the
   launch itself is the lead and runs full width, the four supporting moments sit four-across
   beneath it. Every row is then full. 4 -> 2 -> 1 as the column narrows, and 4 and 2 both
   divide the four remaining images exactly.

   TWO, NOT FOUR, 2026-08-27 — the note above chose four on the ORPHAN question alone and
   never measured what four does to the caption. The strip sits in the `minmax(0,1fr)`
   headline track the `@media (min-width:901px)` block below assigns it, which is 728px at
   every desktop width, so four tracks are 170px and a 12.5px mono caption is 22.4ch — well
   under the 30ch floor. Looked at, not just counted: three captions ran 3 lines and the
   fourth ("YB Datuk Seri Johari stands witness in regards to the MoU signing between Dr
   Daniel (CEO of FIT) and Mr Suren (CEO of AIREI).", 108 characters) ran SEVEN, so its
   painted cell hung ~130px below its three neighbours and the row read as a broken card
   rather than a longer caption. Two tracks give 356px — 47.5ch — and that caption drops to
   three lines beside its neighbours' two.
   The note's own arithmetic already blessed this: "4 and 2 both divide the four remaining
   images exactly", so no row is left ragged either way. It also makes the strip ONE shape at
   every width above 560 instead of changing composition at 900 — the `max-width:900px` rule
   below is now a no-op that says the same thing, left in place rather than deleted because
   it is the anchor for the "superseded" note that follows it. */
.ev-strip{display:grid;gap:16px;margin-top:16px;
  grid-template-columns:repeat(2,minmax(0,1fr))}
.ev-strip figure:first-child{grid-column:1 / -1}
/* superseded — the lead keeps its own ratio; see the scoped rule below */
@media (max-width:900px){.ev-strip{grid-template-columns:repeat(2,minmax(0,1fr))}}
.ev-strip figure{margin:0}
/* `.riv figure img` (0,2,1) sets height:100% + object-fit:cover for the river's square
   thumbnails, and it OUT-SPECIFIES a bare `.ev-strip img` (0,1,1) — so height:auto never
   applied and the grid stretched these 3:2 photographs into portrait boxes, cropping 47%
   of each frame. Third instance of this same specificity shape on this site (nav.main a,
   .news a, .formstate a). Scoped to win, and the figures stop stretching. */
/* A 4/5 aspect-ratio meant for the river plates was landing on these figures too: at 1112px
   wide that forces 1390px of box for a 740px photograph, i.e. 630px of dead navy under the
   launch picture. These figures are sized by their own content. */
.riv .ev-strip figure{align-self:start;aspect-ratio:auto;height:auto}
.riv .ev-strip figure img{display:block;width:100%;height:auto;object-fit:fill;
  border:1px solid var(--hairline)}
/* The lead was a 460px banner, which cropped 38% off the launch photograph — the one frame
   on this page where the whole room is the point. It keeps its own ratio like the other four. */
.riv .ev-strip figure:first-child img{height:auto;object-fit:fill}
/* 11px -> 12.5px, third pass (see `.stat .src`, base.css). These are photograph captions,
   full sentences that name people — "YB Datuk Seri Johari launches the world's first A.I.
   Smart Mill.", 64 characters — and a caption that names a minister is the text a reader
   most needs to be able to read under the frame. */
.ev-strip figcaption{margin-top:8px;font:12.5px/1.55 var(--f-mono);
  letter-spacing:.02em;color:var(--ink-subtle)}
@media (max-width:560px){.ev-strip{grid-template-columns:1fr;gap:14px}
}

/* ── THE ROLL ────────────────────────────────────────────────────────────────
   Twenty-two citations for one day. As a paragraph of comma-separated names it
   read as a boast; as a list with the TYPE on every row it reads as a record,
   which is the only reason it earns the space. Two columns because the set is
   long and each row is short — one column ran the entry to twice the height of
   the photo essay above it and buried the 2019 item below the fold.

   `.news a:not(.btn){display:block}` (0,2,1) already owns every link in this
   section, so the anchor here is a block by inheritance and the row is built
   around that rather than fighting it — the publication and the headline stack
   inside the anchor, the type sits outside it. Fourth time this file has had to
   reckon with that selector; the others are noted where they occur. */
.rollhead{margin:26px 0 0;font-family:var(--f-mono);font-size:11px;letter-spacing:.2em;
  /* font-weight:inherit -- the year labels became <h4> so a screen reader and the
     heading outline can see the record's sections. A bare h4 renders 700 where the
     <p> rendered 400, which would have moved pixels for a semantics-only change.
     Proven red 2026-08-27: with this declaration removed the labels render 420
     against an ordinary <p>'s 400 -- qa/rollhead-pixels.py catches it. */
  text-transform:uppercase;color:var(--signal-gold);font-weight:inherit}
.pressroll{list-style:none;margin:12px 0 0;padding:0;
  display:grid;grid-template-columns:1fr 1fr;gap:0 clamp(20px,3vw,44px)}
.pressroll li{padding:11px 0;border-top:1px solid var(--hairline);min-width:0}
/* `.pressroll a>span` and `.riv .pressroll a:hover>span` were DELETED on 2026-08-26. They
   styled a headline that sat inside the row's anchor, and no headline does any more: the
   row is a <summary> and the only anchor left in it is the "read the original" line at the
   bottom of the panel. Both selectors would have matched nothing while still reading, to
   the next person, like the rules that style a citation. `.pressroll .hl` — declared at the
   foot of this file, and always the rule that styled the ONE row with no link — is now the
   only one, which is what it should have been all along. */
/* Sentence case per .src-tag above, and this is the STRONGEST case of that same argument,
   not a new one. Every one of the 37 `.pressroll b` on this page is an organisation's NAME —
   "The Star", "New Straits Times", "BERNAMA", "Business Today", "The Incorporated Society of
   Planters (ISP)" — and uppercase erased the capitalisation that tells a reader they are
   proper names. It also flattened the real ones: BERNAMA is genuinely an all-caps acronym and
   was indistinguishable from a lowercase masthead shouted by CSS. The provenance line directly
   BELOW this one (`.pressroll .pt`) was given sentence case on that reasoning already, which
   left the source's own name as the only part of the row still shouting.
   Measured 2026-08-27 at 1440x900: the longest ran 42 characters of 11px mono at .13em.
   Tracking drops to .02em with the caps, per .src-tag — wide tracking is what makes CAPITALS
   legible, and sentence case does not need it. */
.pressroll b{display:block;font-family:var(--f-mono);font-size:11px;letter-spacing:.02em;
  text-transform:none;color:var(--ink-muted);font-weight:500}
/* Sentence case per .src-tag above, and up off the 10px floor. This line carries the
   provenance of a press item — "18 Nov 2019 · Wire · original not recovered · headline
   descriptive", 76 characters — which is the part of the roll a sceptical reader checks. */
.pressroll .pt{display:block;margin-top:5px;font-family:var(--f-mono);font-size:11px;
  letter-spacing:.02em;color:var(--ink-ghost)}
.riv .ev-lead .pressroll+.src{margin-top:16px;max-width:62ch}
.riv .ev-lead code{font-family:var(--f-mono);font-size:11px;color:var(--ink-subtle)}

/* ── THE INDEX ───────────────────────────────────────────────────────────────
   The roll above covers ONE DAY. Fifteen more verified items sit outside it —
   the two Edge columns, the Dewan Rakyat, the syndication week, the trade press,
   the 2019 wire — and until 2026-08-26 the page narrated them in prose that
   named the publications without citing any of them. They are now printed as
   rows, generated from qa/news-timeline.json by qa/gen-press-index.py.

   NO NEW ROW COMPONENT. A citation should look the same wherever it appears, so
   this reuses `.pressroll` exactly and changes only the grouping — a year label
   above each set. What is new is the wrapper, which opts out of the river's
   three-column grid the same way `.ev-lead` does twenty lines above, and for the
   same reason: this entry is a list, not a one-line report with a thumbnail. */
.riv article.rec{display:block;padding:26px 0 30px}
.riv .rec .when{display:block;margin-bottom:10px}
.riv .rec .stand{max-width:68ch}
.riv .rec .pressroll+.rollhead{margin-top:22px}
.riv .rec .pressroll+.src{margin-top:14px;max-width:62ch}
.riv .rec code{font-family:var(--f-mono);font-size:11px;color:var(--ink-subtle)}
/* THE headline rule, for every citation row on both pages. It used to share the job with
   `.pressroll a>span` and only carried the one `text-only` row that has no link to hang a
   headline on; since the rows became <details> there are no anchored headlines left, so
   this is the whole story. The two-line clamp holds while the row is SHUT — a 240-character
   Malay headline in a list is a wall — and `.rd[open] .hl` releases it, because a row you
   opened in order to read should not still be hiding the end of its own headline. */
.pressroll .hl{display:block;margin-top:3px;font-size:14.5px;line-height:1.42;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* ══ THE DATE RAIL ═══════════════════════════════════════════════════════════
   THE BUG, MEASURED IN INK. `.riv .when` carried `white-space:nowrap` inside a FIXED
   92px grid track, so a date wider than 92px did not wrap — it overflowed, silently, into
   the column beside it. Measured in Chromium at 1440 with a Range over the text node (the
   box, which every previous probe read, is exactly 92px on all three thumbnail rows and
   tells you nothing):

     "20 NOV – 4 DEC 2024"  ink 161.9px in a 92px track — headline starts 41.1px INSIDE it
     "18 NOVEMBER 2019"     ink 136.3px in a 92px track — headline starts 15.5px INSIDE it
     "2023 – 2024"          ink  93.7px in a 92px track — 27.1px clear, by luck

   And the site loads NO webfont: `--f-mono` resolves to whatever the reader's machine has
   for `ui-monospace`. So the overlap is not a fixed 41px, it is "however much wider that
   reader's mono is than mine" — which is why one desktop shows a collision another does not.
   A track sized to a guess is the defect; the cure is a track wide enough for the longest
   date AND text that WRAPS instead of overflowing when a wider face proves the guess wrong.

   The other half of the complaint: two of the five rows put the date somewhere else
   entirely, because `.ev-lead` and `.rec` opt out of the river grid with `display:block`
   and their `.when` became a full-width line. The date is now column ONE on every row,
   flush with the section's left edge — a rail — and the two long entries keep their full
   width by spanning the columns after it instead of being squeezed into one.

   SCOPED TO ITS BREAKPOINT ON PURPOSE. A media query adds no specificity, so an unscoped
   rule this late in the file would beat the `@media (max-width:900px)` blocks above it at
   every width — the exact trap this sheet already documents on `.lead figure`. Desktop and
   mobile are both written out below, each inside its own query. */
/* THE MAXIMA WERE SET ABOVE THE POINT WHERE THE ROW STOPS GROWING, AND THE HEADLINE PAID.
   `.wrap` is capped at `--wrap:1240px` with a `--gut` that also caps, so from 1368px
   upward `.riv article` is a CONSTANT 1112px — but these three tokens are `vw`, and they
   kept growing inside it. Every pixel they gained came out of the `minmax(0,1fr)` headline
   track, which is the only track on this page whose content is the point. Measured on the
   press roll, header to headline column:

       1280   date 160.0  thumb 172.8  gap 25.6   ->  text 702px   .hl 287px  32.3ch
       1440   date 172.0  thumb 194.4  gap 28.8   ->  text 664px   .hl 239px  27.0ch
       1920   date 172.0  thumb 196.0  gap 34.0   ->  text 642px   .hl 224px  25.3ch

   So the reader with 640px MORE screen got a headline column 63px NARROWER — an inversion,
   not a trade-off, and it put 23 blocks on this page under the 30ch floor at 1440 and 1920
   while only 2 were under it at 1280. The same shape sits on `.lead h2` below.

   The rule this settles, and it is general: A `vw` TERM MAY ONLY GROW WHILE ITS CONTAINER
   GROWS. Past the wrap cap the viewport keeps getting wider and the container does not, so
   every `vw` inside becomes a straight subtraction from the text. The maxima are therefore
   pinned to the values these tokens already hold at 1280 — the width at which the row was
   composed. Below 1280 nothing changes at all (the `vw` term is under the max there, so the
   floors and the ramp are untouched); at and above it the row is frozen and the headline
   track keeps its full 702px at every desktop width. */
.riv{--riv-date:clamp(104px,12.5vw,160px);--riv-thumb:clamp(140px,13.5vw,172px);
  --riv-gap:clamp(24px,2vw,26px)}

@media (min-width:901px){
  .riv article,
  .riv article.ev-lead,
  .riv article.rec{display:grid;
    grid-template-columns:var(--riv-date) var(--riv-thumb) minmax(0,1fr) auto;
    column-gap:var(--riv-gap);row-gap:0;align-items:baseline}
  .riv article.ev-lead{border-bottom:1px solid var(--hairline-strong);padding:26px 0 30px}
  .riv article.rec{padding:26px 0 30px}
  /* normal, not nowrap: the wrap is the guarantee the track width is only the intention */
  .riv .when,
  .riv .ev-lead .when,
  .riv .rec .when{grid-column:1;grid-row:1;display:block;margin:0;
    white-space:normal;overflow-wrap:break-word;line-height:1.45}
  /* THE RIVER'S OWN THUMBNAIL, AND NOTHING ELSE. `.riv figure` was a DESCENDANT
     selector. It therefore also caught the five `.ev-strip figure`s nested three
     levels down inside the photo essay and pinned every one of them to
     `grid-column:2;grid-row:1` OF THEIR OWN GRID: measured at 1440, figures 2-5
     and their four captions all painted at the identical rect 597,2916 216x187 —
     four photographs and four captions printed on top of each other. That is the
     same defect this block was written to cure, one grid deeper, and a box probe
     that reads one figure at a time cannot see it because every box is correct.
     TWO selectors, not one: rows 3 and 4 wrap the thumbnail in
     `<a style="display:contents">`, which generates no box but is still the DOM
     parent, so `>` has to be spelled out for both shapes. */
  /* START, not the row's baseline. A grid item's baseline is the baseline of its last
     line box, and a figure whose only content is a replaced element has none — so the
     row aligned its BOTTOM MARGIN EDGE to the headline's baseline and the plate hung
     UPWARD out of the row. At 96px that was a few pixels nobody saw. At 196px it is a
     245px block climbing into the entry above it. The date keeps the baseline, because
     the date IS a line of text and sitting on the headline's baseline is the point. */
  .riv article>figure,
  .riv article>a>figure{grid-column:2;grid-row:1;align-self:start}
  .riv article>div{grid-column:3;grid-row:1}
  .riv .nw-go{grid-column:4;grid-row:1}
  /* ONE TEXT AXIS FOR ALL FIVE ROWS. These two started at column 2 — the thumbnail
     track — so their headlines began a whole thumbnail plus a gutter to the LEFT of
     the other three, and the river read as two interleaved layouts stacked in one
     list. They keep the date rail and all the width after the thumbnail track,
     which is where every other headline on this page begins. */
  .riv .ev-lead>div,
  .riv .rec>div{grid-column:3 / -1;grid-row:1}
}

@media (max-width:900px){
  .riv article,
  .riv article.ev-lead,
  .riv article.rec{display:grid;grid-template-columns:104px minmax(0,1fr);
    column-gap:14px;row-gap:8px;align-items:baseline}
  .riv .when,
  .riv .ev-lead .when,
  .riv .rec .when{grid-column:1 / -1;grid-row:1;display:block;margin:0;white-space:normal}
  /* scoped for the same reason as the desktop rule fifteen lines above */
  .riv article>figure,
  .riv article>a>figure{grid-column:1;grid-row:2;align-self:start}
  .riv article>div{grid-column:2;grid-row:2}
  .riv .ev-lead>div,
  .riv .rec>div{grid-column:1 / -1;grid-row:2}
  .riv .nw-go{display:none}
}

/* ══ A CITATION THAT OPENS WHERE IT IS ═══════════════════════════════════════
   Every row of both rolls used to be an anchor at a publisher: thirty-six ways off this
   page and none back. Each row is now a <details>. It opens in place with what the record
   holds — what kind of item it is, what the check found, how the copy was reached — and the
   publisher link survives inside it, demoted to one line. No script is involved, so the
   behaviour is identical with JavaScript off.

   ONE COLUMN, not two. The roll was a two-up grid, which is right for rows that only ever
   sit still and wrong for rows that grow: opening the left cell of a grid row stretches the
   row and leaves a hole beside it. One column also lets the publication, the headline and
   the kind sit on ONE line instead of stacked, so twenty-two rows cost about what eleven
   two-line rows cost before. */
.pressroll{grid-template-columns:1fr;gap:0}
.pressroll li{padding:0}
/* THE KIND COLUMN IS BOUNDED, not `auto`. An `auto` track takes as much as its content
   asks for, and the longest kind label on either page is four fields wide — it took half
   the row and squeezed the headline beside it to two clipped words. Bounded and wrapping,
   the widest label costs two lines of 10px mono and the headline keeps the row. */
.rd>summary{display:grid;
  grid-template-columns:var(--roll-pub,150px) minmax(0,1fr) minmax(0,var(--roll-pt,132px)) 16px;
  gap:4px clamp(14px,1.6vw,24px);align-items:baseline;
  padding:11px 0;cursor:pointer;list-style:none}
.rd>summary::-webkit-details-marker{display:none}
.rd>summary::after{content:"+";font-family:var(--f-mono);font-size:14px;line-height:1;
  color:var(--ink-subtle);justify-self:end;align-self:center}
.rd[open]>summary::after{content:"\2013"}
@media (hover:hover) and (pointer:fine){
  .rd>summary:hover .hl,.rd>summary:hover::after{color:var(--signal-gold)}
}
.rd>summary:focus-visible{outline:2px solid var(--signal-gold);outline-offset:3px}
.pressroll b{margin-top:0}
/* the headline is clamped while the row is shut and UNCLAMPED when it opens — a row you
   opened in order to read should not still be hiding the end of its own headline */
.pressroll .hl{margin-top:0}
.rd[open] .hl{-webkit-line-clamp:unset;display:block;overflow:visible;color:var(--ink)}
.pressroll .pt{margin-top:0;white-space:normal;line-height:1.5}

.rd-body{padding:0 0 18px calc(var(--roll-pub,150px) + clamp(14px,1.6vw,24px));
  max-width:74ch}
.rd-kind{margin:0;font-size:14.5px;line-height:1.55;color:var(--ink-muted)}
.rd-lab{margin:14px 0 0;font-family:var(--f-mono);font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--signal-gold)}
.rd-quote{margin:7px 0 0;padding-left:14px;border-left:2px solid rgba(200,136,40,.42);
  font-size:14.5px;line-height:1.6;color:var(--ink)}
/* 11.5px -> 12.5px. THE RECEIPT WAS THE SMALLEST THING ON THE ROW. Measured 2026-08-27 in
   Chromium: a press row sets its headline at 14.5px, its summary at 14.5px, its quote at
   14.5px — and these two lines, "Opened at the publisher's own site." and "Read the original
   at <masthead>", at 11.5px. They are the verification: one says how the record was checked,
   the other is the outbound link a reader follows to check it themselves. On a page whose
   whole argument is that the claims are verifiable, the two lines carrying verification were
   set smaller than everything they verify, and under the 12px floor besides. 12.5px is not a
   new step — base.css and home.css already set mono body at 12.5px — so this joins an
   existing rung rather than inventing one. Both are full sentences (35 and up to 65
   characters), which is why they take a body size and not a label size. */
.rd-how{margin:14px 0 0;font-family:var(--f-mono);font-size:12.5px;line-height:1.65;
  letter-spacing:.03em;color:var(--ink-subtle)}
/* Sentence case per .src-tag above: this is the "read the original at ..." line and it
   names the publisher, up to 65 characters. */
.rd-go{margin:14px 0 0;font-family:var(--f-mono);font-size:12.5px;letter-spacing:.02em}
/* `.news a:not(.btn){color:inherit}` (0,2,1) owns every link in this section — the fifth
   time this sheet has had to reckon with that selector, and the reason this one is written
   at (0,2,1) too rather than as a bare `.rd-go a`, which would lose. */
.news .rd-go a{color:var(--signal-gold);display:inline}
@media (hover:hover) and (pointer:fine){.news .rd-go a:hover{color:var(--crude-amber)}}

@media (min-width:701px){ .rd{--roll-pub:clamp(126px,15vw,186px);--roll-pt:clamp(118px,14vw,178px)} }
@media (max-width:700px){
  .rd>summary{grid-template-columns:minmax(0,1fr) 16px;gap:3px 12px}
  .rd>summary b,.rd>summary .hl,.rd>summary .pt{grid-column:1}
  .rd>summary::after{grid-column:2;grid-row:1 / span 3}
  .pressroll .pt{white-space:normal}
  .rd-body{padding-left:0}
}

/* TAP TARGETS ON TOUCH. "Read the original at The Star ↗" is the one link on a press row
   that leaves for the publisher's own site — the link that makes the row checkable — and
   it measured 15px tall at 390 in a real mobile context, well under the 24px WCAG 2.5.8
   floor. padding-block keeps it inline: it runs 344px of a 350px column in English and
   the Malay row is longer still, so anything that stops it wrapping would overflow. */
@media (pointer:coarse){
  .rd-go a{padding-block:15px}
  .lead .src a{min-height:44px;display:flex;align-items:center}
}
