/* The Zambia presentation. Its own stylesheet on purpose: tokens.css is shared
   with the register's other pages, and this scroll is meant to look like their
   book rather than like our record pages. One idea a sheet, one graphic, and a
   footer paragraph the presenter can read aloud. */
/* No webfont: Canopy sets the system sans, declared in tokens.css. */
@import url("tokens.css?v=9ff180fc");

* { box-sizing: border-box }

body {
  margin: 0;
  background: #f0efec;
  font-family: var(--kr-serif);
  color: var(--kr-ink);
  -webkit-font-smoothing: antialiased;
}

/* One sheet. A4 landscape, which is what their page proportions measure out to,
   and which is also close enough to a laptop screen to scroll comfortably. */
.sheet {
  position: relative;
  width: var(--kr-page-w);
  height: var(--kr-page-h);
  margin: 0 auto 8mm;
  background: var(--kr-paper);
  box-shadow: 0 1mm 5mm rgba(0,0,0,.22);
  display: flex;
  flex-direction: column;
  padding: 0 18mm;
  overflow: hidden;
}
.sheet:first-child { margin-top: 8mm }

/* ----------------------------------------------- the flow experiment (?flow=1)
   Ralph, 21 Sept 2026: "maybe we should redo them as vertical pages, maybe there
   should not be page breaks, maybe this should be a seamless vertical webpage."
   This is that, as one rule, behind a flag.

   HEIGHT AND OVERFLOW ARE THE WHOLE EXPERIMENT. Everything else here is the
   page-card costume coming off: without dropping the shadow and the gap the
   sheets still read as slides, which is the thing being tested. Width is left
   alone on purpose, so only one variable moves; narrowing the column is the
   obvious next dial and a separate question.

   WHY A FLAG AND NOT A SWITCH. z.css is shared by pa-new.html, country-new.html
   and prototype-pa/brief.html, and brief.html is the Keystone Register, a book
   that is actually printed. Only pa-new sets this class, and only when the URL
   asks, so the register, the country brief, print and the default page are all
   exactly as they were.

   WHY THE PDF BUTTON GOES WITH IT. artOver() measures scrollHeight minus
   clientHeight, so an auto-height sheet reports zero overflow, fitBoard returns
   on its first step without ever tightening, and spillFeeds never spills.
   pdf.js rasterises that same live DOM one sheet to one A4 page, so in flow the
   builder would be handed sheets of a dozen different heights whose boards were
   never fitted. Not broken-and-hidden: not meaningful yet. Making both work is
   the two-media model, which is the real job this experiment is scouting. */
@media screen {
  /* A CHAPTER IS A CARD. Ralph, 21 Sept 2026: rounded border, three rows, a
     tinted title row and footer with a white middle. The rows are the sheet's
     existing children given backgrounds rather than new wrappers: h1 and .cap
     are stacked flex siblings with no gap, so two matching tints read as one
     band, and .art and .foot are already single elements. Nothing in the DOM
     moves, which is how print and the Register stay exactly as they were.
     overflow comes BACK to hidden here, which it could not be on a fixed page:
     with height auto nothing is ever clipped by it, and it is what makes the
     radius cut the row tints instead of letting them square off the corners. */
  html.flow .sheet {
    height: auto;
    overflow: hidden;
    /* THE SHADOW COMES BACK, Ralph 22 Sept 2026: "add the shadow too."
       The flow rule dropped it because a sheet carrying one read as a SLIDE,
       and that was right while the sheet was still page-SHAPED: a 297x210
       rectangle with a drop shadow is a slide whatever you call it. The shape
       has since stopped being a page. It is a 240mm column of variable height
       with a 14px radius and three banded rows, and a shadow on that reads as
       what it is. Kept small and close for the same reason the old one was
       dropped: this lifts the card off the page, it does not float it. */
    box-shadow: 0 2px 10px -2px rgba(26, 26, 24, .13);
    margin: 0 auto 7mm;
    padding: 0;
    border: 1px solid var(--kr-rule);
    border-radius: 14px;
    background: var(--kr-paper);
  }
  html.flow .sheet:first-child { margin-top: 0 }
  /* the Download button stays: pdf.js re-draws the document paginated for the
     life of its dialog, so the builder never sees an unfitted flow sheet. */

  /* ROW 1, the title band. .hdr is empty in flow now: .who is hidden below and
     the chapter line is gone, so it would otherwise print a tinted blank strip
     above the heading. */
  html.flow .hdr { display: none }
  /* THE GROUND AND THE BANDS SWAP, Ralph 22 Sept 2026: "i want the cards to pop
     more and be obvious as cards. maybe swap overall background colour with the
     cards top and bottom row background colour. so cards lighter and overall
     background colour darker."

     Taken literally: the two values trade places. The page was #f0efec with
     #e8e6e0 bands, so the card's own darkest part was darker than the ground it
     sat on, and a card cannot read as raised while its edges are heavier than
     what is behind them. Now the whole card (#f0efec bands around a #ffffff
     middle) is lighter than the #e8e6e0 ground, so the lightness runs one way
     the whole width of the card and the border only has to finish the edge
     rather than carry it.

     That earlier note was RIGHT about its own question and is kept here because
     it explains the constraint: --kr-bone (#f5f5f2) was lighter than the page,
     which is why the bands vanished. The answer then was to darken the bands;
     the answer now is to darken the PAGE and let the bands take the lighter
     value. Same observation, the other lever.

     Screen and flow only. The paginated page, print and the Keystone Register
     keep a white ground and no bands at all. */
  html.flow .sheet { --kr-band: #f0efec }
  /* THE GROUND GOES FURTHER DOWN THAN THE SWAP ALONE, and the measurement is the
     reason. Trading the two values straight across puts #e8e6e0 behind an
     #f0efec band, which is a contrast ratio of 1.085:1. That is not an edge: at
     that distance the band still melts into the page and the 1px border is left
     carrying the whole card on its own, which is the thing being complained
     about. #dcd8ce takes it to 1.238 against the band and 1.423 against the
     white middle, which is where the card stops needing its border to be read
     as raised.

     Still the move Ralph asked for, just far enough to land it: the bands take
     the page's old value and the page goes darker. The shadow was held back
     here as a separate decision and Ralph then took it, so both levers are in:
     see the box-shadow above.

     Specificity beats the bare `body` at the top of this file, so their order
     does not decide it. At narrow the same rule still wins over that block's
     `body { background: #e4e3df }`, which is correct: that value was picked to
     darken the ground under phone cards back when the page was #f0efec, and
     this supersedes it in the same direction. Non-flow narrow keeps it. */
  html.flow body { background: #dcd8ce }
  /* A millimetre under the headline, taken from the caption's top so the band is
     the same height. The headline's line-height (1.08) is shorter than the
     font's own box, so a "g" or "p" hangs below h1; the sheet is a flex column,
     so the caption paints as a unit on top of it and cut the descenders off
     ("Akagera on one page.", 24 Sept 2026). */
  html.flow .sheet > h1 { background: var(--kr-band); margin: 0; padding: 6mm 12mm 1mm }
  html.flow .sheet > .cap {
    background: var(--kr-band); margin: 0; padding: .6mm 12mm 5mm;
    border-bottom: 1px solid var(--kr-rule);
  }

  /* ONE SIZE ACROSS THE TITLE ROW. Ralph: the number, the chapter word and the
     title are all the heading's size now. The chips were 10.5pt against a 25pt
     headline, which is why they read as furniture beside it rather than as part
     of the same line. Their padding and tracking are in em, so both had to come
     down as the size went up: .085em of letter-spacing is invisible at 10.5pt
     and a gap at 25pt. */
  html.flow .sheet > h1 .no,
  html.flow .sheet > h1 .kw { font-size: inherit; letter-spacing: .012em }

  /* TWO LINES, AND A SIZE DOWN. Ralph, 21 Sept 2026: "on cards top row, maybe
     reduce font size slightly. line 1 = number and title word. line 2 =
     header." The one-size decision above is kept and only the arrangement
     changes: the number and the keyword hold the first line as a label, and the
     sentence the sheet is actually making takes the second on its own.

     THE TWO CHANGES PAY FOR EACH OTHER, and by more than they cost. Measured on
     Gorongosa's chapter 3 at 240mm: 25pt on one line was a 109px band, 21pt on
     two is 101px. The break is free because it was not really a break. At 25pt
     that headline already wrapped to THREE lines, with the wrap falling wherever
     the chips happened to leave off, so the first line was a number, a keyword
     and however much of the sentence fitted. Naming the break puts it where the
     meaning is instead of where the chips end, and the smaller type buys the
     line back. A one-line headline is the case that genuinely grows, and it
     grows by a line of 21pt on a card with no height to overrun.

     .qt is already the sentence's own span, so this is display:block on an
     element that exists rather than a wrapper. Print, the paginated page and
     the Register keep all three on one line: the chips are 10.5pt there against
     the 25pt headline, which is the arrangement this one replaced and the right
     one on a fixed page, where vertical room is the scarce thing. */
  html.flow .sheet > h1 { font-size: 21pt }
  html.flow .sheet > h1 .qt {
    display: block;
    /* The gap is the chip's own trailing margin turned vertical. Small: these
       are two halves of one title, not a title and a subtitle. */
    margin-top: 1.6mm;
  }
  /* Nothing follows the keyword on its line now, so the gap it was holding open
     for the headline is just a ragged right edge. */
  html.flow .sheet > h1 .kw {
    font-weight: 500; padding: .04em .38em .06em; margin-right: 0;
    border: 0; background: var(--kr-paper); color: var(--kr-ink);
  }

  /* THE CHAPTER NUMBER IS A TRAFFIC LIGHT. White in a circle, the circle taking
     the sheet's own verdict, which is the same four states the summary board's
     dots read and from the same source: s.verdict() writes data-v on the sheet,
     so this cannot disagree with the board or with the chapter. A sheet that
     makes no judgement keeps the grey, which is a state and not a default.
     It does NOT flash the way the board's red dot does. The board is a list
     being scanned for the one bad line; this is one card you are already
     reading, and a flashing 25pt disc on every red chapter is a different
     thing from a 2.6mm dot in a table. */
  html.flow .sheet > h1 .no {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.5em; height: 1.5em; padding: 0; border: 0; border-radius: 50%;
    font-weight: 600; letter-spacing: 0;
    color: #fff; background: #c3c2be;
    vertical-align: middle; margin-right: .34em;
  }
  html.flow .sheet[data-v="good"]  > h1 .no { background: #17913f }
  html.flow .sheet[data-v="check"] > h1 .no { background: #e39411 }
  html.flow .sheet[data-v="bad"]   > h1 .no { background: #d5241a }
  /* ROW 2, the drawing, on paper white */
  html.flow .sheet > .art { background: var(--kr-paper); padding: 6mm 12mm; flex: 0 0 auto }
  /* On a phone 12mm a side took 90px of a 375px screen and every drawing
     shrank with it (launch audit, 24 Sept 2026). */
  @media screen and (max-width: 760px) {
    html.flow .sheet > .art { padding: 5mm 4mm }
  }
  /* ROW 3, the footer band, matching row 1 */
  html.flow .sheet > .foot {
    background: var(--kr-band); margin: 0; padding: 4mm 12mm 5mm;
    border-top: 1px solid var(--kr-rule); border-bottom: 0;
  }

  /* NARROWER COLUMN, Ralph 21 Sept 2026. --kr-page-w is 297mm because that is the
     long edge of A4 landscape, a print fact that means nothing once the document
     scrolls. 240mm is about 907px against the page's 1123px.

     THIS WAS HELD AT 297mm FOR ONE ROUND, and the reason is worth keeping. Every
     figure is an SVG on its own viewBox that scales to its container, so a
     narrower column is smaller type inside every chart. Measured at 240mm before
     the re-typing below: the smallest label fell to 3.2px with 113 of the brief's
     234 labels under 6px. With the feed grid picking its own columns and the axis
     type at 9u, the same measurement is 6.1px and NOTHING under 6. The width is
     earned, not asserted. Still a dial: ?flow=1&w=260mm, or w=297mm for the old
     one. */
  html.flow .sheet { width: min(100%, var(--kr-flow-w, 240mm)) }

  /* THE PILL GOES IN FLOW, and only in flow. The case for keeping it was that
     just 5 of the 15 headlines name the park and the context chapter names the
     COUNTRY, so on nine sheets it was the only thing saying which park you held,
     and the PDF turns every sheet into a page that travels on its own. Both
     halves of that are about a PAGINATED document. Here there are no separate
     pages: the name is established once at the top and never left behind. The
     chapter label beside it stays, so a sheet still says where in the brief it
     is. Print, the PDF and the Register are untouched and keep theirs. */
  html.flow .who { display: none }
  /* "park chapter 4 of 13" goes with the card. In flow the number is already in
     the title row's top-left corner and the scroll position says the rest. It
     stays on the paginated page and in the Register, where a loose sheet has
     nothing else to locate it. */
  html.flow .ch { display: none }
}

/* Header: who this is and where we are. The chapter number never travels
   alone, because the country chapters restart at one and a bare number would
   be ambiguous. */
.hdr {
  display: flex;
  /* the title is a box now and the chapter label is a line of text, so they
     align on the box rather than on a baseline the box does not share */
  align-items: center;
  justify-content: space-between;
  /* WAS 11mm. The title grew from 15pt to 24pt and the box adds its own padding,
     so the space comes out of the gap above it rather than off the bottom of the
     sheet, where the footer lives and there is no headroom at all. */
  padding: 7mm 0 0;
}
/* Whose brief this is. Ralph, 14 Sept 2026: "way too small, make it bold and
   much bigger and even maybe in a box." It is the only thing on a sheet that
   says which document you are holding, and at 15pt regular it was smaller than
   the headline's own keyword chip. */
/* Ralph, 21 Sept 2026: "too aggressive and prominent. Maybe put it in a
   round-cornered pill with no black border." The 1.5px outline in title blue was
   doing most of that: a hard rule around 24pt bold reads as a stamp on the page.
   The pill keeps the standing the box was asked for on 14 Sept and drops the
   outline, so the tint alone holds it. Size and weight are untouched; this is a
   quieter frame, not a smaller title. */
.who {
  /* 24pt -> 15pt, Ralph 21 Sept 2026. It went to 24pt on 14 Sept ("way too
     small, make it bold and much bigger") and that is now more page than the
     job needs: it identifies the sheet, it does not head it. Kept rather than
     cut, because only 5 of the 15 headlines name the park and the chapter on
     country context names the COUNTRY, so on nine sheets this is the only thing
     saying which park you are holding, and the PDF turns every sheet into a
     page that can travel on its own. */
  font-size: 15pt;
  font-weight: 600;
  color: var(--kr-title-blue);
  font-variant-caps: normal;
  letter-spacing: .035em;
  line-height: 1;
  /* scaled with the type: a pill with no outline needs the tint to carry past
     the text to read as one, but 4.2mm around 15pt is a lozenge */
  padding: 1.4mm 2.9mm 1.3mm;
  border: 0;
  border-radius: 999px;
  background: var(--kr-bone, #f5f5f2);
}
.ch {
  font-size: 8pt;
  color: #5f5e5a;
  font-variant-caps: normal;
  letter-spacing: .030em;
  white-space: nowrap;
}

/* The question the sheet answers, in the plainest words available. */
h1 {
  /* Tightened from 5mm when the subtitle grew: the space the bigger subtitle
     needs comes out of the gaps around it rather than out of the footer, which
     is the thing that falls off the sheet. */
  margin: 3.5mm 0 0;
  font-weight: 400;
  font-size: 25pt;
  line-height: 1.08;
  letter-spacing: .004em;
}

/* The chapter number, in front of the question the sheet answers, so a reader
   scrolling a couple of hundred sheets can find their way back to one. */
/* Ralph, 14 Sept 2026: "have all header words in their own boxes to separate
   them from the actual header." Both are boxes now and the box is what marks
   them out, so the keyword drops the bold it was given on 13 September and the
   number drops its literal brackets, which the box says instead.

   HEIGHT IS THE RISK on 156 sheets whose footers have almost no headroom, so
   the chips are set SMALLER than the 25pt heading and aligned on `middle`
   rather than `baseline`: an inline-block on the baseline hangs its padding and
   border BELOW the line, which is how you grow every h1 on every sheet by a
   few points without noticing. check_sheets.py is the proof, not this comment. */
h1 .no,
h1 .kw {
  display: inline-block;
  font-size: 10.5pt;
  line-height: 1;
  font-weight: 600;
  font-variant-caps: normal;
  text-transform: uppercase;
  letter-spacing: .085em;
  /* Ralph, 21 Sept 2026: "have titles like Summary and Score also in a
     round-cornered pill." Same move the .who box took: the outline goes and the
     radius arrives, so the tint alone marks the chip out. Slightly wider side
     padding, because a pill with no outline needs the tint to carry past the
     text. HEIGHT, per the note above, gets SAFER here rather than riskier: the
     1px border came off the top and bottom of an inline-block, so each chip is
     about 2px shorter than it was and the padding added is horizontal only. */
  padding: .34em .75em .3em;
  border: 0;
  border-radius: 999px;
  background: var(--kr-bone, #f5f5f2);
  vertical-align: middle;
  /* Ralph, 21 Sept 2026: "have a space between Summary and Akagera on one page.
     Have that same for all headers on all pages, they are too close together."
     WAS .3em, measured against the 10.5pt chip, so about 3px of air between a
     bordered box and a 25pt headline. This is the only rule either page uses for
     that gap, so both the number and the keyword on every sheet widen together.
     Horizontal only: the risk here is a headline that now wraps to a second line
     and pushes a footer off a sheet, which is what data-over is read for. */
  margin-right: .85em;
  white-space: nowrap;
}

/* The number is how a reader gets back to a sheet; the keyword is what the
   sheet IS. Same box, so they read as one kind of thing, and the keyword takes
   the darker ink because it is the one being scanned for. */
h1 .no {
  color: #5f5e5a;
}

/* With the outlines gone the darker ink is the whole difference between the two
   chips, which is what the note above says it was for anyway. */
h1 .kw {
  color: var(--kr-ink, #1a1a18);
}

/* The keyword: what this sheet IS, before what it says. A reader scrolling
   two hundred sheets finds the fire one by looking for the word FIRE, not by
   reading twelve headlines. */

/* One line saying what the graphic measures, so the sheet reads without the
   footer. Larger than it was (Ralph, 13 Sept 2026): with the headline carrying
   the finding, this line carries what the finding is worth, and at 10pt it was
   being skipped. */
.cap {
  margin: 2mm 0 0;
  font-size: 12pt;
  font-style: italic;
  color: #5f5e5a;
  line-height: 1.25;
}

/* The graphic owns the middle of the sheet. */
/* min-height:0 because a flex item defaults to min-height:auto and so cannot
   shrink below its own content: without it the max-height on the drawing below
   never engages, and a chart one row too tall pushes the footer off the sheet
   instead of scaling. */
.art { flex: 1; min-height: 0; display: flex; flex-direction: column;
  justify-content: center; padding: 2mm 0 }
/* max-height so a drawing taller than the space it has scales down instead of
   running off the bottom of the sheet. An SVG with a viewBox keeps its aspect
   when clamped, so this costs nothing on a sheet that already fits and rescues
   one whose chart grew a row. */
.art svg { display: block; width: 100%; height: auto; max-height: 100% }

/* The cover carries no chapter number and no graphic. It says what the
   document is and who it belongs to, and it is where the confidentiality
   notice lives. */
.cover { justify-content: space-between }
.cover .title { padding-top: 46mm }
.cover h1 {
  margin: 0;
  font-size: 40pt;
  font-variant-caps: normal;
  letter-spacing: .03em;
  color: var(--kr-title-blue);
  line-height: 1;
}
.cover h2 {
  margin: 3mm 0 0;
  font-weight: 400;
  font-size: 23pt;
  font-variant-caps: normal;
  letter-spacing: .017em;
  color: #5f5e5a;
  line-height: 1;
}
.cover .lede {
  margin: 9mm 0 0;
  font-size: 13pt;
  line-height: 1.5;
  color: #3a3a37;
  max-width: 168mm;
}
.cover .lede + .lede { margin-top: 4mm; font-size: 11.5pt; color: #5f5e5a }

/* The abstaining parks get a map instead of a chart: the reason they cannot be
   compared is a fact about where they sit, so it is drawn rather than asserted. */
.mapwrap { display: flex; align-items: center; gap: 14mm }
.mapwrap svg { height: 101mm; width: auto; flex: 0 0 auto }
.mapwrap .side { flex: 1 }
.key { list-style: none; margin: 4mm 0 0; padding: 0; font-size: 9pt; color: #4a4945 }
.key li { display: flex; align-items: center; gap: 3mm; padding: .8mm 0 }
.key i { width: 6mm; height: 3.2mm; border-radius: .6mm; flex: 0 0 auto }

/* The one number that matters, in the accent. Theirs was a terracotta read off
   the book; tokens.css points --kr-terracotta at Canopy's own accent, which is
   still a terracotta, and the role did not move. */
.call {
  display: flex;
  align-items: baseline;
  gap: 4mm;
  margin: 0 0 1mm;
}
.call .big {
  font-size: 30pt;
  line-height: 1;
  color: var(--kr-terracotta);
  letter-spacing: -.01em;
}
.call .lede { font-size: 12.5pt; line-height: 1.25; color: #3a3a37; max-width: 150mm }

/* The presenter's paragraph. Everything needed to defend the sheet out loud:
   what it shows, what it is measured against, how old it is, and the catch. */
.foot {
  border-top: .4pt solid var(--kr-rule);
  margin: 0 0 10mm;
  padding: 3mm 0 0;
  font-size: 8.6pt;
  line-height: 1.55;
  color: #4a4945;
  max-width: 247mm;
}
.foot b { font-weight: 600; color: var(--kr-ink) }
.foot .catch { color: #8a3f22 }
/* The footer's bullets (footList in z.js). Local to the sheet on purpose:
   site.css's .page-lede is sized for a page intro, at 14.5px with 10px gaps,
   and would push every A4 sheet off its bottom edge. Same dot, sheet type. */
.foot ul.fb { list-style: none; margin: .8mm 0 0; padding: 0 }
.foot ul.fb li { position: relative; padding-left: 3.6mm }
.foot ul.fb li + li { margin-top: .6mm }
.foot ul.fb li::before { content: ""; position: absolute; left: .4mm; top: .62em;
  width: 1.4mm; height: 1.4mm; border-radius: 50%; background: var(--kr-sage-dk) }

/* A sheet is a fixed 297mm wide, so on any screen narrower than that the page
   would scroll sideways while it is being presented. Z.fit() sets --k to the
   fraction that fits and `zoom` shrinks the sheet to it. zoom rather than a
   transform, because zoom re-lays-out and the page height follows; a scaled
   transform leaves the original height behind as dead space. Screen only: the
   printed sheet is already the right size. */
@media screen {
  .sheet { zoom: var(--k, 1) }
}

@media print {
  @page { size: A4 landscape; margin: 0 }
  body { background: #fff }
  /* break BEFORE each sheet after the first: break-after on a sheet that already
     fills the page emits a trailing blank sheet */
  /* .sheet:first-child outranks .sheet, so its screen margin has to be
     cleared by name or the first sheet is pushed off the page */
  .sheet, .sheet:first-child { margin: 0; box-shadow: none }
  .sheet + .sheet { break-before: page }
}

/* --------------------------------------------------------- their own page
   GONE, with the loader that drew it. Both briefs used to open on the Rob
   Walton Foundation's own page for the country or the park; both now open on
   one of ours, and no sheet in this document embeds a page out of their
   book. The rules are deleted rather than left unused, so that putting a
   facsimile back is a decision somebody has to make rather than something
   that still happens to be styled. */

/* ------------------------------------------------------------- state chips
   Three states, never two: held, specimen, not held. A chip is only ever the
   label; the reason a thing is not held lives in the footer paragraph, which
   is the only place long enough to give it honestly. */
.chip {
  display: inline-block;
  font-size: 7.6pt;
  font-variant-caps: normal;
  letter-spacing: .020em;
  padding: .3mm 2mm;
  border-radius: .8mm;
  white-space: nowrap;
}
.chip.held { background: var(--kr-title-blue); color: #fff }
.chip.spec { background: var(--kr-terracotta-lt); color: #fff }
.chip.none { background: transparent; color: #6e6d69; border: .3pt dashed var(--kr-rule) }

/* ---------------------------------------------------------------- the grid
   Used by the two sheets that are lists rather than charts: what the pipeline
   declines to state, and what is known about one park. Cards rather than a
   table, because a table of absences reads as a table of measurements. */
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm 8mm }
.cols.three { grid-template-columns: 1fr 1fr 1fr }
.card { border-top: .5pt solid var(--kr-rule); padding: 1.6mm 0 0 }
.card .t { font-size: 10.5pt; line-height: 1.18; display: block }
.card .w { font-size: 8.3pt; line-height: 1.4; color: #5f5e5a; margin: .8mm 0 0 }
.card .w b { font-weight: 600; color: #3a3a37 }
/* People chapter: every value carries the label its source gave it, as a small
   chip in front of the figure. Measured, modelled and proxy take a fill; no data
   takes the dashed outline the state chips above use for "not held", so an
   absence never looks like a reading. Stale marks a survey old enough that the
   region has likely moved on. */
.se .card .w { line-height: 1.55 }
.se-lab { display: inline-block; font-size: 6.6pt; line-height: 1; padding: .5mm 1.1mm;
  border-radius: .8mm; margin-right: .8mm; vertical-align: .25em; letter-spacing: .02em;
  color: #fff; background: #8a8985 }
.se-lab.measured { background: var(--kr-title-blue) }
.se-lab.modelled { background: var(--kr-slate-lt) }
.se-lab.proxy { background: var(--kr-terracotta-lt) }
.se-lab.not-available { background: transparent; color: #6e6d69; border: .3pt dashed var(--kr-rule) }
.se-lab.stale { background: var(--kr-caution) }
.se-lab.part { background: var(--kr-caution) }
.se-src { font-size: 7pt; color: #999896 }
/* Inside the park against the ring: one row a reading, the reading's name and
   source on the left, a column for each geometry. The ring column goes when
   there is no ring to read, and the inside column takes its room. */
.se-tbl { width: 100%; border-collapse: collapse; font-size: 7.8pt; line-height: 1.35;
  color: #5f5e5a; margin: .4mm 0 0 }
.se-tbl th, .se-tbl td { text-align: left; vertical-align: top; font-weight: 400;
  padding: .4mm 2mm .4mm 0; border-top: .3pt solid var(--kr-rule) }
.se-tbl thead th { border-top: 0; font-size: 7pt; color: #999896; padding-bottom: .2mm }
.se-tbl tbody th { width: 20%; color: #3a3a37 }
.se-tbl td { width: 40% }
.se-tbl.one td { width: 80% }
.se-tbl b { font-weight: 600; color: #3a3a37 }
.se-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 4mm }
.se-pair + .w { margin-top: .4mm }

/* ------------------------------------------------------ the country ranking
   The one sheet on the C-FIN brief that is a list of fifty-two names rather
   than a drawing. Columns rather than rows, and read DOWN each column, because
   a reader looking for one country is looking for a name: four columns puts
   every name within a centimetre of the eye where fifty-two rows would not fit
   the page at all.

   MULTICOL, NOT GRID, for the reason the land-cover key gives further down:
   the list is RANKED, and a grid fills across so the first four names would
   land beside each other on one line. `column-fill: balance` is the default
   and is what keeps the last column from being a stub.

   Fixed line height and no wrapping room is what makes this safe to leave
   uncounted: every row is one line whatever the name, so the block's height is
   the row count and not the text. A name too long for its column is clipped by
   the ellipsis rather than folded onto a second line, which would push the
   block past the sheet with nothing to say so. data-over on the sheet is still
   the check. */
/* NO BRIEF HAD A LINK INSIDE A SHEET UNTIL THE C-FIN COUNTRIES CHAPTER. The
   park and country briefs carry none at all, so a browser default was never
   visible, and the first two -- the countries that abstain from the costing --
   arrived underlined in the user agent's blue in the middle of a grey note.
   Set here rather than on that one list, because the next sheet to link
   something should not have to discover this again. */
.sheet .art a, .sheet .foot a { color: var(--kr-title-blue); text-decoration: none;
  border-bottom: .4pt solid currentColor }

.cfTab { columns: 4; column-gap: 6mm; margin: 0; padding: 0; list-style: none;
  font-size: 8.6pt; line-height: 1.5 }
.cfTab li { display: flex; gap: 1.4mm; align-items: baseline;
  break-inside: avoid; border-bottom: .3pt solid var(--kr-rule); padding: .5mm 0 }
.cfTab .r { color: #9a9993; font-variant-numeric: tabular-nums; min-width: 4.4mm;
  text-align: right }
.cfTab a { color: var(--kr-title-blue); text-decoration: none; border-bottom: 0;
  flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.cfTab .f { color: #5f5e5a; font-variant-numeric: tabular-nums; white-space: nowrap }

/* Three boxes, one per assessment instrument, each carrying a tick or a cross
   and the reason under it. Ralph asked for a box a reader can read at a glance,
   and the third one is empty on every park in the register by design.

   The green and the red live here and not in tokens.css, which the record pages
   share: a palette change there leaks into pages this presentation never
   touches. Both are muted on purpose, so a tick is legible as a tick without
   shouting off an otherwise quiet sheet. */
/* A line under a drawing that qualifies what the drawing shows. Its colour is
   the caution one because it is always taking something away from the reading
   above it, never adding to it. */
.warn { margin: 3mm 0 0; font-size: 9pt; line-height: 1.3; color: var(--kr-caution) }

.boxes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 8mm;
  margin-top: 5mm }
.box { display: flex; gap: 4mm; align-items: flex-start;
  border-top: .5pt solid var(--kr-rule); padding: 2.4mm 0 0 }
.box .mark {
  width: 11mm; height: 11mm; flex: 0 0 auto;
  border: .8pt solid; border-radius: 1mm;
  display: flex; align-items: center; justify-content: center;
  font-size: 16pt; line-height: 1;
}
.box.yes .mark { color: #4a7c59; border-color: #4a7c59; background: #f1f4f2 }
.box.no .mark { color: var(--kr-caution); border-color: var(--kr-caution); background: #f7efeb }
.box.rec .mark { color: #5f5e5a; border-color: #999896; background: #f3f2ef }
.box .t { font-size: 10.5pt; line-height: 1.18; display: block }
.box .w { font-size: 8.3pt; line-height: 1.4; color: #5f5e5a; margin: .8mm 0 0; display: block }

/* The feed blocks come from canopy's satellite-detail.js, which styles itself.
   Two pieces of it are host chrome this presentation does not have: the info
   button opens an explainer overlay that lives on the site, and a dead button
   on a printed sheet is worse than no button. */
.sat-feed-info { display: none !important }

/* The borrowed block, scaled whole to the sheet it has to fit. */
/* A drawing that uses only part of its width, with the sheet's one reading set
   in the space it leaves. The drawing is cropped to what it uses and shown at
   that fraction of the width, so its labels keep the size they had. */
.calwrap { display: flex; align-items: center; gap: 9mm }
.calwrap svg { flex: 0 0 60%; width: 60%; height: auto }
.calwrap .call { flex: 1 1 auto; display: block }
.calwrap .call .big { display: block; margin-bottom: 2mm }
.calwrap .call .lede { display: block; max-width: none }

.satfit { flex: 0 0 auto; width: 100%; margin: 0 auto }
.satfit-in { display: grid; grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr));
  gap: 0 6mm; align-items: start }

/* THE AXIS TYPE IN THE FEED CHARTS. Ralph, 21 Sept 2026, re-typing so the column
   can narrow. satellite-detail.js draws these at font-size 8 on a 474-unit
   viewBox, which is right where it is used at something like full size. Here the
   grid runs three across, so a 474-unit chart is laid into about 263px and
   everything in it, the axis labels included, renders at 55 per cent: 8 units
   lands at 4.4px. Measured across the whole brief, 67 of its 234 SVG labels sit
   there, and NOTHING else on any sheet is below 4.4px, so that band is alone at
   the bottom by accident rather than by design. The three-across decision above
   was taken on whether the CAPTION still fit, which it does; the axis type was
   never in that argument.

   Set here and not in satellite-detail.js on purpose. That file is loaded by six
   pages (pa.html, african-parks, keystone-watch, portfolio-room, country-new and
   this one) and renders at a sensible size on the others; the squeeze belongs to
   this grid, so the correction belongs to this stylesheet. z.css is loaded only
   by the three brief hosts, so the blast radius is the brief and nothing else.

   A CSS length on SVG text is in USER UNITS, not screen pixels, so this is 14
   units and lands near 7.8px at three-across. Every text inside a .sat-chart svg
   is one of these axis labels, which is why this needs no new class. */
.sheet .sat-chart svg text { font-size: 9px }

/* ...and that is as far as the stylesheet can take it. Swept, at three-across:
   8u renders 4.4px with nothing escaping its chart, 9u renders 5.0px still with
   nothing escaping, and from 10u the labels start leaving the box: 3 escapes at
   10u, 5 at 11u, 19 at 14u. The chart's own padL and padB are the binding
   constraint, and they live in satellite-detail.js, which five other pages draw
   at something near full size and would not thank us for wider gutters. So 9u
   is the ceiling here and 5.0px is still too small to call fixed.

   FIXED ON THE PDF SHEETS, 24 Sept 2026, from the script rather than here:
   axisText in z.js redraws any chart rendering under 8.25px with the module's
   opt-in axisFont, which widens those gutters for that chart alone and sets
   the size inline, so it outranks this rule. The other five pages never pass
   it. Smallest PDF axis text is now 8.3px, with the same sheet count.

   THE SQUEEZE IS THE BUG, NOT THE TYPE. Three across exists because a sheet is
   a fixed page and three columns is how the feeds fit its height; the note by
   .satfit-in weighed that on whether the CAPTION fits, which it does. In flow
   there is no height to fit, so the grid can pick its columns from the width it
   actually has and the chart stops being laid into 55 per cent of itself. At
   two across a 474-unit chart gets about 482px, which is its own size, and the
   original 8u lands near 8px with no escapes at all because nothing inside the
   chart has changed. Narrowed to 240mm it is still about 6.3px. */
@media screen {
  /* .satfit-feeds, not .satfit-in: the wood sheet is a .satfit-in with --cols:1
     inline, and re-columning that one laid its 1000-unit chart into 282px and
     took six of its labels under 6px. Only the multi-feed grids re-column. */
  /* ONE COLUMN, NOT TWO. Ralph, 21 Sept 2026: "on pages with charts, i do not
     want 2 columns, give them horizontal breathing space, e.g. 6, 8, 9. fine
     for charts to be wide like on card 7."

     Those four numbers are this rule exactly, which is worth recording because
     it is what makes the request precise. Chapters 6, 8 and 9 (Fire, Greenness,
     Water) carry four feeds each, so auto-fit took the 814px of card it had and
     settled on two of about 396px. Chapter 7 (Canopy) carries ONE feed, so the
     same rule gave it the full 814px, and that is the card being pointed at:
     not a different design, the same grid with nothing to pair up. Asking for
     6, 8 and 9 to look like 7 is asking auto-fit to stop pairing.

     So the column count is stated rather than computed. minmax(340px, 1fr)
     would have to be raised past the widest card to guarantee one, which is a
     number that goes stale the moment --kr-flow-w is dialled; 1fr cannot.

     The type comes UP, which is the reverse of the problem the 9u note above
     solves. A 474-unit chart laid into 814px renders at about 1.7, so the axis
     labels land near 15px instead of 6.1px. That is card 7's size today and it
     is the size being asked for. Escapes are geometry in user units and do not
     move with render scale, so the 9u ceiling measured at three-across still
     holds here: still zero.

     Screen and flow only. Paginated, print and the Register drop back to the
     --cols the sheet sets, because a fixed page is short and four feeds down a
     single column is a sheet with one feed on it and three clipped. */
  html.flow .satfit-feeds {
    grid-template-columns: 1fr !important;
    gap: 7mm !important;
  }
  /* The 9u above applies here too, and is what carries the narrow column: at
     240mm the feed grid settles on two of about 323px, a 0.68 scale, and 9u
     lands at 6.1px. Escapes are geometry in USER units, so the 9u ceiling
     measured at three-across holds at any render scale: still zero. */
}


/* The laser's three figures, on one line above the chart they describe. A row
   rather than three cards: they are the smallest thing on the sheet and were
   taking a third of it. */
.woodrow { display: flex; align-items: baseline; gap: 7mm; flex-wrap: wrap;
  border-bottom: .5pt solid var(--kr-rule); padding-bottom: 2mm; margin-bottom: 3mm }
.woodrow span { font-size: 8.6pt; color: #5f5e5a }
.woodrow b { font-size: 14pt; color: var(--kr-terracotta); margin-right: .6mm }
.woodrow em { font-style: normal; display: block; color: #5f5e5a }
.woodrow .woodsrc { margin-left: auto; max-width: 62mm; text-align: right; line-height: 1.3 }
/* Canopy height per vegetation class (#1611), one full-width line tucked into the
   row's bottom margin. Styled as a second .woodrow it sat in the 62mm source
   column, wrapped to three lines and put 44 wood sheets over (28 Sept 2026). */
.woodcls { font-size: 8.6pt; color: #5f5e5a; line-height: 1.3; margin: -1.5mm 0 1.5mm }
/* The per-class table (#1637): classes across, the three figures down, set in the
   same small print so four short rows cost about what three wrapped lines did. */
.woodtab { border-collapse: collapse; font-size: 8pt; line-height: 1.25; margin: 0 0 1mm }
.woodtab th, .woodtab td { padding: .3mm 4mm .3mm 0; text-align: right; font-weight: normal }
.woodtab th { color: #999896 }
.woodtab tr > :first-child { text-align: left }
.woodtab td { font-variant-numeric: tabular-nums }
.woodcls p { margin: 0; font-size: 8pt; line-height: 1.3 }

/* The chart takes the wider column: it is the measurement, the picture beside
   it is the illustration. And the headline number is set down from the size it
   takes on a sheet of its own, where it has the width to be that big. */
.woodcols { grid-template-columns: 1.25fr .75fr; gap: 3mm 8mm; align-items: start }
/* No picture held for the park: the chart takes the whole width rather than
   sitting in the left of two columns beside an empty one. */
.woodcols.solo { grid-template-columns: 1fr }
.woodcall .big { font-size: 17pt; line-height: 1.1 }
.woodcall .lede { font-size: 10.5pt }

/* A map set beside the feed block it belongs to, and a picture set under one.
   Both ride inside the borrowed block's box, so they are fitted with it. */
.alertmap svg { width: 100%; height: auto; display: block; margin-bottom: 2mm }
/* A chart drawn in a companion column: same sizing as the alert map, its own
   viewBox width, so it is never scaled up from a full-sheet drawing. */
.sidechart svg { width: 100%; height: auto; display: block; margin-bottom: 2mm }
.feedmore:empty { display: none }

/* A number on its own line, for the one or two facts a list sheet still has
   to carry. Never in the prose: a measurement in a sentence cannot be read
   off the page at a glance. */
.pair { display: flex; gap: 3mm; align-items: baseline }
.pair .n { font-size: 13pt; color: var(--kr-terracotta); line-height: 1 }
.pair .l { font-size: 9pt; color: #5f5e5a }

/* ---------------------------------------------------------------- a phone
   A sheet is a fixed A4 landscape box and no amount of scaling makes that
   readable on a telephone: fitted to a 393 point screen the footer paragraph
   comes out at under three points. So below this width the sheet stops being
   a page and becomes a card: full width, its own height, type at its real
   size, and one column throughout. The drawings are re-laid-out in z.js
   against a narrower viewBox, because shrinking a drawing shrinks its labels
   with it and the labels are the point.

   Screen only, and only below the breakpoint. The printed sheet and the
   laptop the presentation is given from are untouched. */
@media screen and (max-width: 760px) {
  body { background: #e4e3df }

  .sheet {
    width: auto;
    height: auto;
    min-height: 0;
    margin: 0 0 3mm;
    padding: 0 5mm 6mm;
    box-shadow: none;
    border-bottom: 1px solid #dedcd7;
    /* Z.fit() leaves --k alone below the breakpoint, but a stale value from a
       rotation must not survive into this layout. */
    zoom: 1;
  }
  .sheet:first-child { margin-top: 0 }

  .hdr { flex-wrap: wrap; gap: 1mm 4mm; padding: 6mm 0 0 }
  .who { font-size: 13pt }
  .ch { font-size: 7.6pt }
  h1 { margin-top: 3mm; font-size: 19pt; line-height: 1.12 }
  .cap { font-size: 10pt; margin-top: 2mm }
  .art { padding: 3mm 0 1mm; display: block }
  .foot { margin-bottom: 0; padding-top: 2.5mm; font-size: 9.4pt; line-height: 1.5; max-width: none }

  /* The one number that matters stacks above its sentence rather than beside
     it: side by side, neither has room to be read. */
  .call { display: block; margin-bottom: 2mm }
  .call .big { display: block; font-size: 24pt; margin-bottom: 1mm }
  .call .lede { display: block; font-size: 11pt; max-width: none }

  /* The map and what it says, one under the other. */
  .mapwrap { display: block }
  .mapwrap svg { width: 100%; height: auto; max-height: 58vh; margin: 0 auto 3mm; display: block }
  .mapwrap .side { width: auto }
  .key { font-size: 9.6pt }
  .key li { padding: 1.2mm 0 }

  /* Cards in one column, always. Two columns at this width is two columns of
     three words. */
  .cols, .cols.three { grid-template-columns: 1fr; gap: 2.5mm }
  .se-pair { grid-template-columns: 1fr }
  .cfTab { columns: 2; column-gap: 4mm; font-size: 9.4pt }
  .boxes { grid-template-columns: 1fr; gap: 2.5mm }
  .box .t { font-size: 11.5pt }
  .box .w { font-size: 9.6pt; line-height: 1.45 }
  .card .t { font-size: 11.5pt }
  .card .w { font-size: 9.6pt; line-height: 1.45 }

  .cover .title { padding-top: 14mm }
  .cover h1 { font-size: 28pt }
  .cover h2 { font-size: 17pt }
  .cover .lede { font-size: 11.5pt; max-width: none }
  .cover .lede + .lede { font-size: 10.5pt }
  .cover { min-height: 78vh }

  }

/* The summary board: one row a chapter, on the sheet that leads a brief.
   Four columns, because a reader scanning it wants the same four things in the
   same places every time: which sheet, what it is, how it reads, what it says. */
.board { width: 100%; border-collapse: collapse; font-size: 11.5pt; line-height: 1.25 }
/* --bpad, not a literal: z.js tightens it until the board fits the sheet,
   because the board grows a row every time a chapter is added and a sheet is a
   fixed page. See fitBoard(). The literal here is the value it starts at and
   the one almost every park keeps. */
.board td { padding: var(--bpad, 2.6mm) 0; border-bottom: .4pt solid var(--kr-rule);
  vertical-align: baseline }
.board tr:last-child td { border-bottom: 0 }
/* A right pad, not just a width: at [10] the two digits fill the 10mm and the
   keyword beside them had nothing to sit against. Small capitals hid it by
   carrying their own side bearing; sentence case does not. */
.board .bn { width: 10mm; color: #999896; white-space: nowrap;
             padding-left: 2.4mm; padding-right: 2mm }
/* Quieter than the finding beside it: the keyword says which sheet, the
   sentence says what it found, and the sentence is the thing to read. */
.board .bk {
  width: 34mm;
  font-variant-caps: normal;
  letter-spacing: .027em;
  color: var(--kr-terracotta);
  white-space: nowrap;
}

/* A row whose sheet found something carries the weight. Nothing else separated
   "nobody has judged this park since 2009" from "where it is, and what is
   around it", and they were reading at the same weight. */
.board tr.found .bq { font-weight: 700; color: var(--kr-ink) }
.board .bq { color: var(--kr-ink); padding-left: 3mm }

/* The opening sheet's board: no number, no light column, and room for a
   sentence rather than a headline in the right-hand cell. */
.board.why .bk { width: 62mm; white-space: normal; vertical-align: top }
.board.why .bq { padding-left: 6mm }
.board.why td { padding: 3.4mm 0 }

/* SENTENCE CASE AT THE START OF A LINE. Ralph, 21 Sept 2026: "Never start
   sentences lowercase, even if on tables and lists." Applied to the elements
   that OPEN a line and deliberately not to the ones that continue one: .lede
   runs straight on from .big in the same sentence ("2nd of 200 parks we
   score"), and "up 4 tonnes a hectare across 15 years" is one sentence split
   across two spans, so capitalising .lede would drop a capital into the middle
   of it. ::first-letter rather than re-casing the strings, because these values
   come from a dozen helpers (usd() returns "not published", the legends build
   their own labels) and a capital belongs to where a value is PLACED, not to
   the helper that made it: the same usd() output runs mid-sentence elsewhere.
   A value starting with a digit is untouched, which covers most of .big.
   Checked before applying: no park in the 200 has a deliberately lowercase
   name, so nothing here turns an iSimangaliso into an ISimangaliso. That check
   does NOT carry to the wider site. */
.call .big::first-letter,
.sheet td.v::first-letter,
.sheet li::first-letter { text-transform: capitalize }

/* THE LIGHT, between the number and the keyword. Ralph, 21 Sept 2026: "summary
   page needs actual traffic light dots between each number and title. Must be
   red, green or amber. Actual colours." FOUR states, not three: a sheet that
   makes no judgement takes grey, which is the state Ralph named himself on
   Place and which the note below says a fourth colour was once dropped for.
   That note still stands for the WORD; this is the dot, and a blank where a
   dot belongs reads as a missing dot rather than as "nothing to say".

   Stronger hues than .bv below, deliberately. That rule's own comment says a
   polite green reads as grey at this size, and it is describing 11pt text; this
   is a 2.6mm circle, where the effect is worse.

   Red flashes, which Ralph asked for. Two places it must not: print, because
   the PDF export freezes whatever frame it lands on and a half-faded dot reads
   as a different colour, and reduced-motion, because a flashing element is the
   one thing that setting exists for. Both stop it solid, never hidden. */
.board .bd { width: 5mm; padding-right: 1mm; white-space: nowrap }
.board .dot {
  display: inline-block; width: 2.6mm; height: 2.6mm; border-radius: 50%;
  background: #c3c2be;
  vertical-align: middle;
}
.board .dot.good  { background: #17913f }
.board .dot.check { background: #e39411 }
.board .dot.bad   { background: #d5241a; animation: kr-flash 1.05s steps(1, end) infinite }
@keyframes kr-flash { 50% { opacity: .18 } }
@media print { .board .dot.bad { animation: none; opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .board .dot.bad { animation: none; opacity: 1 } }
/* And the third way this page becomes a still: pdf.js rasterises with
   html2canvas, which is not print media, so neither rule above fires for it. It
   sets html.pdfz-cap for the duration of the capture, and a red dot caught at
   18% opacity would come out of the builder as a pink one. Nothing says which
   frame a capture lands on, so this is not a bug that would fail a test run; it
   would just quietly ship a wrong colour in some PDFs and not others. */
html.pdfz-cap .board .dot.bad { animation: none !important; opacity: 1 !important }

/* The verdict, at the end of the line it belongs to. One word, one colour, and
   nothing at all where the sheet makes no judgement: a map and a comparison
   that cannot be made are not good or bad, and a fourth colour for "not
   applicable" was noise on a page whose job is to be read in one pass.

   Green, amber and red proper: a polite green reads as grey at this size. */
.board .bv {
  width: 20mm;
  padding-right: 2.4mm;
  text-align: right;
  white-space: nowrap;
  font-weight: 700;
  font-variant-caps: normal;
  letter-spacing: .023em;
  font-size: 11.5pt;
}
.board .bv.good  { color: #4a7c59 }
.board .bv.check { color: #b26a12 }
.board .bv.bad   { color: #a8332a }

/* THE WHOLE ROW CARRIES THE COLOUR (Ralph, 14 Sept 2026), so the board can be
   read at a glance instead of line by line.

   Tints, not fills. The word and the sentence are still the content and they
   have to stay black on them: these sit around 4% saturation, which reads as
   green/amber/red at arm's length and still prints. A saturated row would take
   the page over and put the heaviest thing on the sheet behind the text.

   A row with NO verdict takes NO tint, which is the fourth state and the one a
   three-colour scale cannot say. A cost rate and a calendar of dates are not
   good or bad, and tinting them would invent a judgement the sheet declines to
   make. There are three such rows on the country board.

   THE TINTS ARE GONE, Ralph 22 Sept 2026: "traffic light dots are good enough
   so we do not need row background colours to correspond. background of tables
   can be white." That revises his own 14 September call, which is the one the
   paragraph above argues for, and the reason it can be revised is that the dot
   arrived after it. The row said the verdict three times over, in the tint, in
   the dot and in the word at the end of the line, and a table where every row
   is tinted is a table with no quiet rows for the loud ones to stand out from.
   The fourth state above is now simply the absence of a dot.

   THE LEFT EDGE STAYS, and is not what was asked about: it is a 3px marker
   rather than a background, and its reason is unchanged by the dot. A tint is
   hard to tell apart on a projector and this document gets shown in rooms,
   where the edge reads at full strength from the back. It is one word to drop
   if it now looks like the correspondence doing its work twice. */
.board tr.v-good  td:first-child { box-shadow: inset 3px 0 0 #4a7c59 }
.board tr.v-check td:first-child { box-shadow: inset 3px 0 0 #b26a12 }
.board tr.v-bad   td:first-child { box-shadow: inset 3px 0 0 #a8332a }
/* the tint needs room to read as a band rather than a smear behind the text */
/* The inset applies to EVERY row, tinted or not. Putting it only on the tinted
   ones stepped the untinted rows about 8px to the right, so the board's columns
   stopped lining up and the eye caught the jog before it caught the colour. */


/* The ring, as a second number on chapter two. Ralph, 14 Sept 2026: "make the
   ring figure bigger." It was a clause in a 9.6pt table at the foot of the
   sheet, where a reader in a hurry does not go, and the ring is the ground every
   comparison in this brief is made against. It is out of that table entirely
   now rather than said twice.

   Smaller than the sheet's own headline number and in the identity colour rather
   than the accent, because the park's area is still the first fact and this is
   the second. Below the prose rather than beside that number: two big figures on one
   line read as a pair being compared, and these two are not a comparison. */
.call.ring { margin: 3.5mm 0 2mm }
.call.ring .big { font-size: 21pt; color: var(--kr-title-blue) }
.call.ring .lede { font-size: 10.5pt; max-width: 108mm; color: #4a4945 }

/* The land cover pie and its key. The key carries the numbers, because at this
   size a 0.9% wedge is a hairline and the reader is looking at the words.

   Two columns, and that is a fix rather than a preference. The key ran as one
   column of however many classes a park holds, so the card it sits in was a
   different height on every park: 158px on Lunga Luswishi at five classes,
   197px on Liuwa Plain at eight plus a fold note long enough to wrap. The hero
   column is a fixed height with `overflow: hidden`, so Liuwa's facts table ran
   10px past the bottom of the sheet and the Habitat row was CUT IN HALF with
   nothing scrolling and nothing thrown - and Bangweulu was already over its
   column and inside the sheet's padding by luck. Dynamic World has nine classes,
   so two columns is at most five rows, which is shorter than the pie beside it
   for every park there can be, and the card is the same height on all ten.

   Multi-column and not a two-track grid, because a grid fills ACROSS and this
   list is ranked: the reader wants the largest share top-left and the next one
   under it. `break-inside` keeps a row from being split down the middle. */
.lcWrap { display: flex; align-items: flex-start; gap: 3.5mm }
.lcWrap svg { width: 17mm; height: auto; flex: 0 0 auto }
.lcKey { list-style: none; margin: 0; padding: 0; flex: 1; min-width: 0;
  font-size: 7.4pt; line-height: 1.32; color: #3a3a37;
  columns: 2; column-gap: 5mm }
.lcKey li { display: flex; align-items: center; gap: 1.6mm; break-inside: avoid }
.lcKey i { width: 2.4mm; height: 2.4mm; flex: 0 0 auto; border-radius: .4mm }
.lcKey span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap }
.lcKey b { font-weight: 500; color: #1a1a18; font-variant-numeric: tabular-nums }

/* ------------------------------------------------------------------ the hero

   Canopy's opening sheet. The first cut of this borrowed the register's own
   composition wholesale: a narrow column of figures down the left, the map
   filling the right, hairline rules between everything, and a radar plot. That
   is THEIR page, and reading the two side by side you could not tell whose was
   whose. This is built out of the live site's own furniture instead:

     a header band            eyebrow, name, meta row, the way pa.html opens
     the score on that band   not boxed in a panel of its own
     the map on the left      large, and the first thing read
     bordered cards           tinted grounds, as the site uses everywhere
     horizontal score bars    not a radar, which is the register's signature

   Bands across, then two columns: their sheet is a vertical split top to
   bottom, so the horizontal band is what makes this one read differently at a
   glance, before any colour or typeface registers. */
.sheet.hero { display: flex; flex-direction: column; padding: 0; overflow: hidden }

.heroTop {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 10mm;
  padding: 8mm 9mm 5mm;
  border-bottom: 1.2px solid var(--kr-title-blue);
  flex: 0 0 auto;
}
.heroEye {
  font-size: 8pt;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--kr-terracotta);
  margin-bottom: 2.2mm;
}
.heroId h2 {
  margin: 0;
  font-size: 26pt;
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.02;
  color: var(--kr-ink);
}
.heroMeta {
  margin-top: 2.4mm;
  font-size: 9.6pt;
  color: #5f5e5a;
  display: flex;
  flex-wrap: wrap;
  gap: 0 5mm;
}
/* Gaps, not separator glyphs: the register sets its facts with interpuncts and
   this is the same information without borrowing the punctuation. */
.heroMeta span::before { content: ''; }

.heroStats { display: flex; gap: 9mm; flex: 0 0 auto; text-align: right }
.heroStats .v {
  font-size: 21pt;
  font-weight: 600;
  line-height: 1;
  color: var(--kr-terracotta);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.heroStats .v em { font-size: 9pt; font-style: normal; font-weight: 400; color: #999896 }
.heroStats .k { font-size: 8.4pt; color: var(--kr-ink); margin-top: 1.2mm }
.heroStats .s { font-size: 7.6pt; color: #999896; margin-top: .4mm }
/* The park hero's three figures carry their chapters' verdicts (Ralph, 24 Sept
   2026: "so what?"). Same four states and colours as the chapter number discs.
   A figure with no verdict is ink, not terracotta, because beside a green or red
   figure terracotta reads as a verdict. Only the park hero sets data-v, so the
   country and C-FIN heroes keep their terracotta. */
.heroStats [data-v] .v { color: var(--kr-ink) }
.heroStats [data-v="good"] .v, .heroStats [data-v="good"] .s b { color: #17913f }
.heroStats [data-v="check"] .v, .heroStats [data-v="check"] .s b { color: #b8740a }
.heroStats [data-v="bad"] .v, .heroStats [data-v="bad"] .s b { color: #d5241a }
.heroStats .s b { font-weight: 700 }

/* Map left, cards right. min-height:0 so the map can be clamped rather than
   pushing the sheet; the sheet's height is fixed and the map is the only thing
   on it that would happily grow past the paper. */
.heroBody { flex: 1; min-height: 0; display: grid; grid-template-columns: 40fr 60fr }
.heroMapCol {
  min-width: 0;
  min-height: 0;
  background: #f4f6f4;
  border-right: .4pt solid var(--kr-rule);
  display: flex;
  flex-direction: column;
}
.heroMap { flex: 1; min-height: 0; display: flex; flex-direction: column }
/* An explicit ceiling in millimetres: flex-basis:auto would take the svg's own
   intrinsic height, which at this column width and a 154x210 viewBox runs past
   the bottom of the sheet. Bounded, preserveAspectRatio draws it as large as
   fits and centres it. */
.heroMap svg { display: block; width: 100%; height: auto; max-height: 152mm; min-height: 0 }
.heroKey {
  margin: 0;
  padding: 2.6mm 7mm 3.4mm;
  list-style: none;
  font-size: 7.8pt;
  color: #3a3a37;
  flex: 0 0 auto;
}
.heroKey li { display: flex; align-items: center; gap: 2.2mm; padding: .45mm 0 }
.heroKey .sw { width: 4.4mm; height: 2.6mm; flex: 0 0 auto; display: inline-block }
.heroKey .sw.park { background: rgba(26,74,46,.16); border: .45mm solid var(--kr-title-blue) }
.heroKey .sw.ring { background: rgba(166,77,46,.07); border: .4mm dashed var(--kr-terracotta) }
.heroKey .sw.other { background: #dfe7de }

.heroCards {
  min-width: 0;
  min-height: 0;
  padding: 5mm 9mm 3.5mm 7mm;
  display: flex;
  flex-direction: column;
  gap: 2.7mm;
  /* Slack collects here, between the cards and the reference rows, rather than
     inside a card that would stretch its contents out of shape. */
  justify-content: flex-start;
  overflow: hidden;
}
/* The site's card: a hairline border on a faintly tinted ground. Spent on the
   three blocks that are measurements, and withheld from the facts table below
   them, which is reference and does not need lifting off the page. */
.hcard {
  border: .4pt solid var(--kr-rule);
  background: var(--kr-paper);
  border-radius: 1.2mm;
  padding: 2.4mm 4mm 2.5mm;
  min-width: 0;
}
.hcard h3 {
  margin: 0 0 2.2mm;
  font-size: 8pt;
  font-weight: 700;
  letter-spacing: .085em;
  text-transform: uppercase;
  color: #6e6d69;
}
/* Sized to its content, not stretched. With flex:1 this card grew to fill the
   column and its two blocks overflowed their own box, printing the facts
   table on top of them; the sheet never scrolled, so nothing caught it. */
.hcard.split { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm 5mm;
  flex: 0 0 auto; min-height: 0 }
.hcard.split > div { min-width: 0 }
.hn { margin: 1.8mm 0 0; font-size: 7.4pt; line-height: 1.32; color: #999896 }

/* Ten rows, five steps each, filled to the score. */
.hbars { list-style: none; margin: 0; padding: 0 }
.hbars li {
  display: grid;
  grid-template-columns: 1fr auto 4.5mm;
  align-items: center;
  gap: 3mm;
  padding: .08mm 0;
  font-size: 8pt;
}
.hbars .n { color: #3a3a37; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.hbars .p { display: flex; gap: .7mm }
.hbars .p i { width: 4.2mm; height: 1.9mm; background: #eceae6; display: inline-block }
.hbars .p i.on { background: var(--kr-terracotta) }
.hbars .p i.on.hi { background: var(--kr-title-blue) }
.hbars .p i.on.mid { background: var(--lv-elev) }
.hbars .p i.on.lo { background: var(--lv-high) }
.hbars b {
  font-weight: 500;
  font-size: 7.6pt;
  color: #999896;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.heroFacts { border-collapse: collapse; width: 100%; font-size: 8.4pt; flex: 0 0 auto }
.heroFacts td { padding: .7mm 0; vertical-align: baseline }
.heroFacts td.k { width: 24mm; color: #999896 }
.heroFacts td.v { color: #3a3a37 }

.heroPop { border-collapse: collapse; font-size: 8.6pt; font-variant-numeric: tabular-nums }
.heroPop td { padding: .6mm 3.2mm .6mm 0 }
.heroPop td.y { color: #999896 }
.heroPop td.n { text-align: right; color: #1a1a18 }
.heroPop tr:first-child td.n { color: #999896; font-size: 7.4pt }

@media (max-width: 760px) {
  .heroTop { flex-direction: column; align-items: flex-start; gap: 5mm }
  .heroStats { text-align: left; gap: 7mm }
  .heroBody { grid-template-columns: 1fr }
  .heroMapCol { border-right: 0; border-bottom: .4pt solid var(--kr-rule) }
  /* The locator's two tracks become one: at this width the map half is about
     forty millimetres across, which is a continent nobody can read. */
  .cLoc { grid-template-columns: 1fr }
  .cLocMap svg { max-height: 86mm }
  .cPlate svg { max-height: none }
  .hcard.split { grid-template-columns: 1fr }
  /* One column at this width: two tracks of "Shrubland 75.8%" is two tracks of
     one word. The card is free to grow here, because a phone sheet scrolls. */
  .lcKey { columns: 1 }
}

/* The key's figures, set to the right of the thing they measure. */
.heroKey li b { margin-left: auto; font-weight: 500; color: #6e6d69;
  font-variant-numeric: tabular-nums; padding-left: 3mm; white-space: nowrap }

/* ------------------------------------------------- the country's two plates
   The continent above, the country below, in that order because the sheet's
   job is to put this country somewhere before it draws it in detail.

   The locator is a row rather than a full-width plate: Africa's outline is
   taller than it is wide, and given the whole column it would push the country
   map, which is the one worth looking at, off the bottom of the sheet. So it
   takes a little over half the width and the sentence explaining its three
   tones sits in the rest. */
/* The country sheet gives its map column more of the page than the park sheet
   does, because it carries two plates rather than one and the pair is the
   point of the sheet. Scoped to .heroC so the park hero's 40/60, which is
   tuned for one map and four cards, is untouched. */
.heroC .heroBody { grid-template-columns: 46fr 54fr }

/* THE C-FIN HERO HAS ONE MAP AND NOT TWO. The country hero's left column is a
   locator above a plate of that country's own areas, so .cLoc sits at its
   natural height and .cPlate takes what is left. C-FIN draws the continent once
   and has no second map, so with .cLoc's flex:0 0 auto the column was a small
   plate over two thirds of empty ground. Here the one block has the column, and
   the ceiling on the drawing rises to match: the budget the note above .cLocMap
   describes is being spent on one plate instead of two. */
.cfMapCol .cLoc { flex: 1; grid-template-columns: 1fr; align-items: start;
  align-content: start; gap: 3.4mm; padding: 5mm 7mm 5mm }
.cfMapCol .cLocMap svg { max-height: 132mm }

.cLoc {
  display: grid;
  grid-template-columns: 70fr 30fr;
  gap: 3mm;
  align-items: center;
  padding: 4mm 7mm 2mm;
  flex: 0 0 auto;
}
/* The ceilings on both plates are a BUDGET, not decoration, and they add up:
   the header takes about 30mm of a 210mm sheet, so the locator, its caption,
   the country plate and its note have to live inside the rest. Set the locator
   too low and it letterboxes inside its own cell, which is how it first drew:
   83mm of width holding a 71mm continent with grey either side. */
.cLocMap svg { display: block; width: 100%; height: auto; max-height: 70mm }
.cLocSay .hn { margin: 0 }
.cPlate {
  flex: 1;
  min-height: 0;
  padding: 0 7mm 3.4mm;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}
/* The same explicit ceiling the park map carries, for the same reason:
   flex-basis:auto takes the svg's intrinsic height, which at this column width
   runs past the bottom of the paper. */
.cPlate svg { display: block; width: 100%; height: auto; max-height: 88mm; min-height: 0 }
.cPlate .hn { margin: 2.4mm 0 0 }

/* Country money, held apart from the park's own facts on purpose: nothing in
   the repository attributes a share of it to one park, and a reader must not be
   able to take it as this park's number. Muted, ruled off, and its first words
   name the country. */
.heroCountry {
  margin: 0;
  padding: 2.4mm 7mm 3.4mm;
  border-top: .4pt solid var(--kr-rule);
  font-size: 7.6pt;
  line-height: 1.35;
  color: #999896;
  flex: 0 0 auto;
}
.heroCountry b { color: #6e6d69; font-weight: 600 }

/* The Score sheet's ten dimensions: a ranked table, five steps a row, coloured
   by how the score reads. See scoreTable() in z.js. */
.scoreTbl { width: 100%; border-collapse: collapse; font-size: 12.5pt; color: #3a3a37;
  margin-bottom: 5mm }
.scoreTbl th { font-size: 8.6pt; font-weight: 500; color: #999896; text-align: left;
  padding: 0 0 1.6mm; border-bottom: .5pt solid var(--kr-rule) }
.scoreTbl td { padding: 1.5mm 0; border-bottom: .5pt solid #efeeea; vertical-align: middle }
.scoreTbl td.n { padding-right: 6mm; white-space: nowrap }
.scoreTbl td.p { white-space: nowrap; width: 1%; padding-right: 4mm }
.scoreTbl td.p i { display: inline-block; width: 13mm; height: 4.2mm; margin-right: 1mm;
  background: #eceae6; border-radius: .6mm; vertical-align: middle; overflow: hidden }
.scoreTbl td.p i b { display: block; height: 100% }
.scoreTbl td.p b.hi { background: var(--kr-title-blue) }
.scoreTbl td.p b.mid { background: var(--lv-elev) }
.scoreTbl td.p b.lo { background: var(--lv-high) }
.scoreTbl tr.hot td.n { font-weight: 600 }
.scoreTbl tr.hot td.pc { color: var(--lv-high); font-weight: 600 }
.scoreTbl td.v { font-weight: 700; font-size: 14pt; width: 10mm }
.scoreTbl td.v.hi { color: var(--kr-title-blue) }
.scoreTbl td.v.mid { color: var(--lv-elev) }
.scoreTbl td.v.lo { color: var(--lv-high) }
.scoreTbl td.na { font-size: 10pt; color: #999896; white-space: nowrap }
.scoreTbl td.pc { color: #6e6d69; font-size: 10.5pt; white-space: nowrap; padding-left: 4mm }
/* A phone in flow leaves about 263px inside the sheet's padding; the table
   needs to fit that at its narrowest, so the steps shrink and the right-hand
   column wraps ("94th / percentile") rather than running off the sheet. */
@media screen and (max-width: 760px) {
  .scoreTbl { font-size: 10pt }
  .scoreTbl td.n { white-space: normal; padding-right: 2mm }
  .scoreTbl td.p { padding-right: 1.5mm }
  .scoreTbl td.p i { width: 3.2mm; height: 3.2mm; margin-right: .5mm }
  .scoreTbl td.v { font-size: 11pt; width: auto }
  .scoreTbl td.pc, .scoreTbl th { white-space: normal; font-size: 8pt; padding-left: 1.5mm }
}

/* INTRO V2 (the default since 24 Sept 2026; ?intro=v1 draws the old pair). The
   plain-words cover and summary. Every class below is new to it. */
.heroSay { margin: 0; flex: 0 0 auto; padding: 3mm 9mm 3.4mm; font-size: 12.5pt; line-height: 1.4; color: var(--kr-ink); border-bottom: .3mm solid var(--kr-rule) }
.heroStats .k { max-width: 40mm; margin-left: auto }
.heroId h2.long { font-size: 21pt }
.heroMapSay { margin-top: 2mm }
.glance { display: grid; grid-template-columns: repeat(auto-fit, minmax(50mm, 1fr)); gap: 5mm 6mm; align-content: start }
.glance h3 { margin: 0 0 2.2mm; font-size: 10pt; font-weight: 700; letter-spacing: .02em; display: flex; align-items: center; gap: 2mm }
.glance h3::before { content: ''; width: 3.2mm; height: 3.2mm; border-radius: 50%; background: #c9c7c1; flex: 0 0 auto }
.glance .g-good h3::before { background: #17913f }
.glance .g-check h3::before { background: #e39411 }
.glance .g-gap h3::before { background: #d5241a }
.glance ul { margin: 0; padding: 0; list-style: none }
.glance li { font-size: var(--gpt, 10.5pt); line-height: 1.4; color: var(--kr-ink); padding: 1.6mm 0; border-top: .3mm solid var(--kr-rule) }
.glance .gch { display: block; font-size: 7.6pt; color: #999896; margin-top: .6mm }

.heroParks { width: 100%; border-collapse: collapse; font-size: 8.8pt }
.heroParks td { padding: .9mm 0; border-top: .25mm solid var(--kr-rule) }
.heroParks tr:first-child td { border-top: 0 }
.heroParks .k a { color: var(--kr-ink); text-decoration: none }
.heroParks .v { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; padding-left: 3mm }
.heroParks .r { display: block; font-size: 7.4pt; color: #999896 }
.heroParks .v { vertical-align: top }

/* Why it matters: the first thing under the park's name. */
.heroWhy { flex: 0 0 auto; padding: 3mm 9mm 2.6mm; background: #f4f6f2; border-bottom: .3mm solid var(--kr-rule) }
.heroWhy h3 { margin: 0 0 1.4mm; font-size: 8pt; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--kr-title-blue) }
.heroWhy ul { margin: 0; padding: 0; list-style: none; display: grid; gap: .8mm }
.heroWhy li { font-size: 11pt; line-height: 1.35; color: var(--kr-ink); padding-left: 4mm; position: relative }
.heroWhy li::before { content: ''; position: absolute; left: 0; top: 2.1mm; width: 1.6mm; height: 1.6mm; border-radius: 50%; background: var(--kr-title-blue) }
