/* ============================================================
   2035 INITIATIVE — REPORT PAGE STYLESHEET  v2.0
   Single source of truth. Every rule is scoped under .rpt so the
   sheet can be dropped into a site page that already has its own
   header, footer and typography without bleeding into them.

   Mode A (in the main site repo): put the report markup inside
     <div class="rpt"> … </div> in a normal site page.
   Mode B (own Cloudflare Pages project, iframed): use
     <body class="rpt"> in a standalone document.

   Host-page requirement (both modes): html,body{overflow-x:clip}
   (or overflow-x:hidden). The full-bleed bands are 100vw wide,
   which is a few pixels past the body when a scrollbar is present.
   The main site's chrome CSS already sets this.

   Mode A also needs Nunito Sans (400/600/700/800/900) loaded by
   the page — this sheet names the family but does not load it.

   Do not edit token values per report, except the co-branding set
   documented at --aqua-tint below. Never --navy, never --gold.

   NO ACCENT STRIPES. Nothing in this sheet marks a box with a thin
   coloured bar down one edge or across the top — no 3px aqua top
   border on a callout, no 4px gold left border on a quote. It is the
   single most recognisable "generated slide deck" tic, it multiplies
   into a page full of competing hairlines, and it does not appear in
   the printed reports. A pull-out is marked by its FILL (--tint), a
   1px --line border, and space. Colour goes into type, numerals and
   badges, which carry meaning. If a new component seems to need a
   stripe, it needs a fill instead.

   RULES ARE THE FINDING SERIES' ALONE. The only horizontal rule under
   a headline belongs to a numbered finding head. Every other rank is
   distinguished by colour, size and weight. Two rules stacked a few
   pixels apart — a band's underline above a heading's underline — is
   the failure this prevents.
   ============================================================ */

.rpt{
  /* UCSB / 2035 core palette */
  --navy:#003660; --navy-ink:#0b2436;
  --aqua:#047C91; --sea:#077268; --mist:#9CBEBE; --light-mist:#DAE6E6;
  --gold:#FEBC11; --coral:#D8583F; --sand:#C9BF9D;

  /* Aqua on the pull-out fill is 3.83:1 — below AA. Anything aqua that sits on
     a tinted card uses this darkened shade instead (4.64:1 on the fill, 5.4:1
     on white, so one token is safe on both). Same idea as --mut-tint below. */
  --aqua-tint:#046e80;

  /* ---------- CO-BRANDING ----------
     A co-produced report carries the partner's colour, but only where colour
     is decorative or categorical. Structure stays ours.

     SWAPPABLE for a partner's palette — all of these sit on white or on the
     pull-out fill, where contrast can be measured:
       --aqua / --aqua-tint   sub-section heads, h3, card kickers, hover states
       --sea                  body links, the affirmative badge
       --mist --sand --coral  chart series only
       --light-mist           the pull-out fill (a very light tint of theirs)

     NEVER swapped:
       --navy    the page's structure — masthead, bands, section rules,
                 numbered tiles, headings. Change it and the page stops
                 reading as ours.
       --gold    every accent that sits ON navy — the eyebrow date, the band
                 underline, the accent bar. Gold is the only colour tested
                 against those grounds; a partner's primary is as likely to
                 vanish into navy as to sit on it. It also marks the active
                 jump-nav entry, which sits on white; the reading-progress bar
                 beneath it is navy, so the two rules stay distinguishable.
       --ink --mut --faint --line   text and hairlines.

     Run scripts/partner-palette.js with the partner's hexes BEFORE editing any
     of this. Brand colours are picked for logos, not for 11px uppercase text on
     a tinted card, and about half of them fail somewhere in this layout. The
     script names the roles each colour can take and, where one fails, the
     nearest darker shade of the same hue that passes. */

  /* Neutrals. --faint is the caption/source color and must stay at or
     above 4.5:1 on white, the panel tint and the closing tint. */
  --ink:#152430; --mut:#596b75; --faint:#667380;
  --line:#e6eaed; --rule:#eef1f3; --panel:#f7f9fa;

  /* Pull-out fill. Every callout, quote, box and panel sits on this tint —
     it is how a pull-out is marked, INSTEAD of an accent stripe along one
     edge (see "no accent stripes" below). --mut is too light to sit on it,
     so tinted boxes use --mut-tint for secondary text: 6.1:1 on the fill,
     7.8:1 on white, so the same token is safe either way. */
  --tint:var(--light-mist); --mut-tint:#42555f;

  /* Measure */
  /* Frame is 1040px with the site's 22px gutter. Narrower than the site's own
     1220 container, which means the report sits slightly inset on wide screens —
     accepted deliberately, because at 1220 the gap between the end of a paragraph
     and the end of the rule above it read as the page being shifted left.
     Headings run the full frame; figures break past it to 1176. */
  --maxw:1040px; --readw:900px; --gutter:22px;

  /* The section-headline size. Everything about a numbered head is computed from
     it — the headline, the navy tile's side, the tile's top offset and the
     numeral inside it — so the whole head grows or shrinks as one object and
     stays aligned at every width in the clamp's fluid range.
     Keep an eye on the ratio to body copy (18px): 36 / 18 = 2.0, which is the
     ceiling. Past 2:1 the body starts reading as caption-scale, and the fix is
     to move both sizes, not just this one. */
  --headsize:clamp(27px, 2.9vw, 36px);
  --sans:'Nunito Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --serif:Georgia, 'Iowan Old Style', 'Times New Roman', serif;

  /* 17.5px body in a 900px column, dropped half a point from 18 on 15 Oct at
     comms' request. Long-form reading sits at 17–20px, so this is still inside
     that band, and the heading ratio (32px is 1.83x) stays inside the 1.8–2.0
     the house rule asks for. 17px was the other option on the table; it reads
     fine but pushes the measure past ~103 characters, which is the ceiling the
     900px column was chosen to hold. Do not run body copy the full frame width:
     1176px at this size is ~138 characters, well past readable. */
  font-family:var(--sans); font-size:17.5px; line-height:1.68;
  color:var(--ink); background:#fff; -webkit-font-smoothing:antialiased;
}
.rpt *{box-sizing:border-box; margin:0; padding:0}
.rpt ::selection{background:var(--light-mist)}

/* Keyboard focus. One visible treatment for every interactive element. */
.rpt a:focus-visible,
.rpt button:focus-visible,
.rpt summary:focus-visible{outline:3px solid var(--aqua); outline-offset:3px; border-radius:2px}


/* ---------- MASTHEAD ----------
   Full-bleed in both modes: the negative margins pull the element out
   to viewport width, so the hero photo and accent bar span edge to edge
   even when the report sits inside the site's centered container. */
.rpt .masthead{
  background:var(--navy); color:#fff;
  margin-left:calc(50% - 50vw); margin-right:calc(50% - 50vw);
}
.rpt .masthead .in{max-width:var(--maxw); margin:0 auto; padding:0 var(--gutter)}
.rpt .hero{padding:34px 0 46px}
/* Co-brand credit.
   The 2035 mark is NOT repeated here. The site header carries the identical
   UC Santa Barbara / 2035 Initiative lockup about 40px above this block, and the
   footer carries it a third time — three of the same mark on one page. What the
   site header cannot carry is a per-report partner, so that is all this row is:
   a worded credit plus the partner's own mark. A bare partner logo with no words
   would read as the partner's report, which is why the label is not optional.
   Single-brand reports delete the whole block and open on the date. */
.rpt .cobrand{display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-bottom:30px}
.rpt .cobrand .cb-l{font-size:11.5px; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--mist)}
.rpt .logo-partner{display:block; width:auto; height:26px}

/* The 2035 mark, for PRINT ONLY. Policy and legislative staff print these, and a
   printed page has no site header to supply the branding. Hidden on screen so it
   costs nothing there; the print block below reveals it in navy on white. */
.rpt .logo-print{display:none}
/* Print fallback for the partner. The partner file is the WHITE knockout version,
   so it disappears on white paper — print swaps the image for the partner's name
   as text. Screen shows the mark, print shows the words. */
.rpt .cb-print{display:none}
@media (max-width:560px){ .rpt .logo-partner{height:20px} }
.rpt .hero-band{position:relative; width:100%; height:clamp(220px,36vw,400px)}
/* The band crops the photo vertically. Centred, it cut the mill in half and gave
   a third of the band to sky; 35% kept the whole tower but spent too much of the
   band on the treeline; 72% dropped so far onto the working deck that the mill
   lost its height. 60% sits between them — the vent stacks crop off the top, by
   decision, while the tower still reads as tall and the conveyor and roofs carry
   the foreground. The hard ceiling is the steam: past about 75% the plumes lose
   their tops, and the steam is why this photograph is on the page at all. */
.rpt .hero-band img{display:block; width:100%; height:100%; object-fit:cover;
  object-position:50% 52%}
.rpt .photo-credit{position:absolute; right:12px; bottom:9px; font-size:10.5px; letter-spacing:.03em;
  color:rgba(255,255,255,.9); text-shadow:0 1px 4px rgba(0,0,0,.75)}
.rpt .eyebrow{display:inline-flex; align-items:center; gap:11px; color:var(--gold); font-size:13px; font-weight:800; letter-spacing:.16em; text-transform:uppercase}
.rpt .hero h1{font-family:var(--serif); font-weight:700; font-size:clamp(31px,4.6vw,46px); line-height:1.12;
  letter-spacing:-.015em; margin:16px 0 18px; max-width:17em; text-wrap:balance; color:#fff}
.rpt .hero .dek{font-size:19.5px; line-height:1.6; color:#d3dfe5; max-width:42em; text-wrap:pretty}
.rpt .hero .authors{margin-top:20px; color:#e7eef2; font-size:15px; font-weight:800; letter-spacing:.01em}
/* The line under the authors that says what the report rests on: sample sizes,
   fieldwork dates, the methodology link. Both live reports wanted one and the
   template had none, so it kept getting faked with an inline style. Lighter and
   lighter-weight than .authors on purpose — it is provenance, not a byline.
   #b9cbd6 is 7.41:1 on the navy, so it clears AA with room to spare. */
.rpt .hero .byline{margin-top:7px; color:#b9cbd6; font-size:14.5px; line-height:1.55;
  font-weight:400; max-width:46em; text-wrap:pretty}
.rpt .hero .byline a{color:inherit; text-decoration:underline; text-underline-offset:2px}
.rpt .hero-foot{margin-top:26px; padding-top:20px; border-top:1px solid rgba(255,255,255,.22);
  display:flex; align-items:center; justify-content:flex-start; gap:12px; flex-wrap:wrap}
.rpt .statgrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:1px; background:rgba(255,255,255,.16); border:1px solid rgba(255,255,255,.16); margin:34px 0 0}
.rpt .stat{background:var(--navy); padding:18px 18px 16px}
.rpt .stat .n{display:block; font-family:var(--serif); font-size:32px; font-weight:700; letter-spacing:-.01em; line-height:1; color:#fff}
.rpt .stat .n.sea{color:#7fd1c4} .rpt .stat .n.coral{color:#f2a68f} .rpt .stat .n.gold{color:var(--gold)}
.rpt .stat .l{display:block; font-size:13.5px; color:var(--mist); line-height:1.45; margin-top:9px}
.rpt .stat .l b{color:#eaf1f4; font-weight:700}
/* One solid gold rule, co-branded or not. A bar split between two brand colours
   turns the masthead's closing gesture into a legend for whose report it is —
   the partner's mark above it already says that, and says it better. */
.rpt .accent-bar{height:6px; background:var(--gold);
  margin-left:calc(50% - 50vw); margin-right:calc(50% - 50vw)}
.rpt .resources{margin-top:22px; display:flex; flex-wrap:wrap; gap:10px}

/* ---------- BUTTONS ---------- */
.rpt .btn{display:inline-flex; align-items:center; gap:7px; font-family:var(--sans); font-size:12.5px; font-weight:800;
  letter-spacing:.02em; padding:9px 16px; border-radius:3px; border:1px solid transparent; cursor:pointer;
  text-decoration:none; transition:background .12s,color .12s,border-color .12s}
.rpt .btn-ghost{background:transparent; color:#fff; border-color:rgba(255,255,255,.34)}
.rpt .btn-ghost:hover{border-color:#fff}
.rpt .btn-gold{background:var(--gold); color:var(--navy); border-color:var(--gold)}
.rpt .btn-gold:hover{background:#ffd155; border-color:#ffd155}

/* ---------- SECTION NAV ----------
   Sticky jump-nav. Mode A: check it doesn't collide with the site
   header — if that header is itself sticky, set --nav-top to its
   height so this parks underneath it. */
.rpt .secnav{
  position:sticky; top:var(--nav-top, 0px); z-index:40;
  background:rgba(255,255,255,.94); backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
  margin-left:calc(50% - 50vw); margin-right:calc(50% - 50vw);
}
/* The 4px bottom padding is taken back out of the links' own bottom padding
   below, so the bar's height and the type's position are unchanged. It exists
   to lift the active entry's gold underline clear of the reading-progress bar,
   which runs along the bar's bottom edge — now navy, but still a second rule
   that should not touch the first. 4px of it is
   taken back out of the links below, so only the remaining 4px grows the bar;
   the gap wants to read as deliberate white, and 3px did not. Nav height is
   50px, which is what the scroll offset above is set against — change both
   together or jump links land under the bar. */
.rpt .secnav .in{display:flex; gap:4px; align-items:center; overflow-x:auto;
  max-width:var(--maxw); margin:0 auto; padding:0 var(--gutter) 8px; scrollbar-width:none}
.rpt .secnav .in::-webkit-scrollbar{display:none}
.rpt .secnav .lbl{flex:none; padding-right:12px; margin-right:4px; font-size:10.5px;
  font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--faint);
  border-right:1px solid var(--line)}
/* The active marker is a pseudo-element, not a border. A border spans the
   link's padded box, so it ran 10px past the label at each end and read as a
   rule hanging off the word; inset to the padding, it is exactly as wide as
   the text. The 9px bottom padding replaces the 7px + 2px border the rule used
   to occupy, so the bar's height is unchanged — see the note on .in above. */
.rpt .secnav a{flex:none; position:relative; padding:11px 10px 9px; font-size:12.5px;
  font-weight:800; color:var(--mut); text-decoration:none; white-space:nowrap;
  transition:color .15s}
.rpt .secnav a::after{content:""; position:absolute; left:10px; right:10px; bottom:3px;
  height:2px; background:var(--gold); opacity:0; transition:opacity .15s}
.rpt .secnav a:hover{color:var(--navy)}
.rpt .secnav a.on{color:var(--navy)}
.rpt .secnav a.on::after{opacity:1}

/* ---------- PAGE BODY ----------
   .rpt-main replaces the bare <main> selector so the sheet never
   claims the host site's <main> element. */
.rpt .rpt-main{max-width:var(--maxw); margin:0 auto; padding:0 var(--gutter)}
.rpt .read{max-width:var(--readw)}
.rpt section{padding:60px 0 0}
.rpt .opening{position:relative; padding-bottom:64px}
.rpt .findzone{position:relative; padding-bottom:64px}
.rpt .findzone > section:first-child,
.rpt .closing > section:first-child{padding-top:0}
.rpt .closing{position:relative; padding-bottom:64px}
.rpt .closing::before{content:""; position:absolute; z-index:0; top:0; bottom:0;
  left:calc(50% - 50vw); width:100vw; background:#eef2f4; border-top:1px solid var(--line)}
.rpt .closing > *{position:relative; z-index:1}

/* A pull-out is marked by contrast with its ground, so on the closing act's grey
   the whole family flips to white. Declared once here rather than per component:
   any new tinted block inherits the rule automatically. */
.rpt .closing .note::before{background:#fff}
.rpt .closing .pull,
.rpt .closing .recbox,
.rpt .closing .methods{background:#fff}
.rpt section > *:last-child{margin-bottom:0}
.rpt section > .read:last-child > *:last-child{margin-bottom:0}
.rpt .figure:last-child{margin-bottom:0}
.rpt .eyebrow-sec{font-size:11px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--aqua); margin-bottom:8px}

/* ---------- HEADINGS ----------
   Three ranks, mirroring the printed reports:
     · findings band  → caps, heavy sans, on navy
     · section head   → serif navy; numbered heads carry an aqua tile
                        seated on a full-width aqua rule, unnumbered
                        heads are smaller with a short aqua rule
     · h3             → aqua, sentence case
   Section heads sit OUTSIDE .read so they span the full 1040px frame
   while body copy stays in the 880px reading column. */
.rpt h2{font-family:var(--serif); font-weight:700; font-size:var(--headsize); line-height:1.3; letter-spacing:-.015em;
  margin:0; max-width:none; text-wrap:balance; color:var(--navy)}
/* Section heads run the full frame — a ~96px overhang past the body column,
   enough to read as deliberate without opening a gap. This only works while the
   frame stays near 1040: at 1220 the overhang becomes 276px and the page reads
   as shifted left. If --maxw changes, re-check this. */
/* A heading binds to what FOLLOWS it, so it carries more space above than below.
   Both ranks previously had none above at all — the only gap was the preceding
   paragraph's 16px bottom margin — which put ~28px above and ~40px below and read
   as lopsided. */
.rpt .sechead{margin:46px 0 28px; clear:both; max-width:none}
/* A section head's 46px top margin is spacing BETWEEN a section head and the
   copy above it. When the head is the first thing in its section there is no
   copy above it — the section's own 60px padding is already the separation —
   and the two stack. That only shows up where a navy band is followed straight
   away by a numbered head, which in this report is band 3 into 3.1: 106px
   against the 60px every other band gets. Zero it where it double-counts. */
   The sections sit inside .findzone / .closing wrappers, so this cannot be
   scoped to .rpt-main's direct children. It applies to whatever opens a
   section — a head, a figure, a callout — all of which otherwise add their own
   top margin on top of the padding. */
.rpt section > *:first-child{margin-top:0}
/* .rpt .sechead carries two classes and so outranks the rule above; the head
   needs its own, equally specific, reset or it keeps its 46px. */
.rpt section > .sechead:first-child, .rpt section > .figure:first-child{margin-top:0}
.rpt .finddiv + * .sechead:first-child,
.rpt section:first-child > .sechead:first-child{margin-top:0}
/* Section headlines FILL each line before wrapping. They inherit text-wrap:balance
   from .rpt h2, which equalises line lengths instead — on a head like "Modeling
   Clean Heat Technologies with Process Archetypes" that breaks it into two short
   lines with a third of the rule left empty, and reads as truncation. Balance
   still earns its keep on the masthead title and the act bands, which are short
   and centred in their own block. */
.rpt .sechead h2{margin:0; text-wrap:pretty}

/* numbered (finding) heads.
   The rule belongs to the HEADLINE (border on the h2), not to the heading block,
   so it starts at the headline's left edge, clears the number, and travels with
   the text when a headline wraps.

   THE TILE IS COMPUTED FROM THE HEADLINE, NOT HARD-CODED. Its top edge sits on
   the tallest ink in the headline and its bottom edge on the underside of the
   rule. Both ends are a function of the headline's font size:

     ink top     = size x ((lh - 1) / 2  +  g)          g = the face's gap from
     rule bottom = size x lh  +  padding-bottom  +  2       the line box top down
     tile side   = rule bottom - ink top                    to the tallest ink

   Only g depends on the typeface, and font metrics scale linearly with font
   size, so g is a ratio. For Georgia 700 it is 0.08125, from the one real-Georgia
   measurement on record (32px / 1.2 / 8px padding -> ink top 5.80; 5.80 - 3.20 of
   half-leading = 2.60; 2.60 / 32 = 0.08125). With lh 1.3 that gives
   0.15 + 0.08125 = 0.23125 for the top offset and 1.15 - 0.08125 = 1.06875 for
   the size-proportional part of the side.

   Writing those as calc() against --headsize is what keeps the tile aligned
   through the whole clamp() range. The old fixed pixel values were exact only at
   the clamp's maximum; between about 1000px and 1333px wide the headline is
   fluid and a fixed tile drifts out of alignment.

   "Tallest ink" means the ASCENDER (h, l, b, d, k, t) — not cap height. Every
   English headline has one, and round caps overshoot the cap line besides, so a
   tile set to cap height reads ~2px low against real copy.

   Georgia is NOT installed in Claude's cloud container and the metric-compatible
   stand-in does not settle this: measured side by side at 32px/1.3, Gelasio puts
   the tallest ink at 5.75 where real Georgia measured 7.40. So g above comes from
   the recorded Mac measurement, and any re-measurement has to happen on a machine
   that actually has Georgia.

   The tile aligns to the FIRST line. On a one-line headline it spans exactly from
   ink to rule; when a headline wraps it stays beside the line the reader starts
   on while the rule drops to the last line. Bottom-aligning instead would park
   the number beside the last line, where it looks like it numbers the wrong thing. */
.rpt .sechead.numbered .hrow{display:flex; gap:18px; align-items:flex-start}
.rpt .sechead.numbered h2,
.rpt .sechead.major h2{flex:1; border-bottom:2px solid var(--navy); padding-bottom:8px; color:var(--navy)}
.rpt .sechead.numbered .snum{
  flex:none; font-family:var(--sans); font-weight:800; color:#fff;
  background:var(--navy); border-radius:2px;
  /* 10px = padding-bottom 8 + border 2 */
  width:calc(1.06875 * var(--headsize) + 10px);
  height:calc(1.06875 * var(--headsize) + 10px);
  margin-top:calc(0.23125 * var(--headsize));
  font-size:calc(0.6 * var(--headsize));
  display:inline-flex; align-items:center; justify-content:center; line-height:1;
  font-variant-numeric:lining-nums tabular-nums;
}
@media (max-width:720px){
  .rpt .sechead.numbered h2{padding-bottom:7px}
  /* 9px = padding-bottom 7 + border 2 */
  .rpt .sechead.numbered .snum{
    width:calc(1.06875 * var(--headsize) + 9px);
    height:calc(1.06875 * var(--headsize) + 9px);
  }
  .rpt .sechead.numbered .hrow{gap:13px}
}

/* Sub-section heads — aqua, smaller, no tile and no rule. The absence of a rule
   is the rank signal: rules mark the two top ranks (numbered findings and the
   report's own major sections) and stop there. */
.rpt .sechead:not(.numbered):not(.major) h2{font-size:clamp(24px,2.5vw,29.5px); color:var(--aqua)}
/* The aqua rank sits inside a run of body copy rather than opening a section, so
   it takes a smaller version of the same above-over-below split. */
.rpt .sechead:not(.numbered):not(.major){margin:40px 0 20px}

.rpt .methods-details summary.mshow{cursor:pointer; list-style:none; display:inline-block;
  font-family:var(--sans); font-size:12.5px; font-weight:800; letter-spacing:.08em;
  text-transform:uppercase; color:var(--aqua); white-space:nowrap}
.rpt .methods-details summary.mshow::-webkit-details-marker{display:none}
.rpt .methods-details summary.mshow::before{content:"Show further detail \25BE"}
.rpt .methods-details[open] summary.mshow::before{content:"Hide further detail \25B4"}
.rpt .methods-details summary.mshow:hover{text-decoration:underline}

.rpt h3{font-family:var(--sans); font-size:19px; font-weight:800; letter-spacing:.01em;
  color:var(--aqua); margin:28px 0 8px}
/* The fourth rank inside the reading column — the draft's Heading 4, which sits
   under an aqua 3.3.1 head. Navy with a hairline under the text itself (not the
   column) so it separates from the body bold around it without competing with
   the 2px full-width rules that mark the two top ranks. */
.rpt .read h3{color:var(--navy); width:fit-content; max-width:100%;
  border-bottom:1.5px solid var(--navy); padding-bottom:5px; margin:30px 0 11px}
.rpt p{margin:0 0 16px; max-width:54em; text-wrap:pretty}
/* The lead keeps its 1.056x relationship to the body rather than a fixed px. */
.rpt p.lead{font-size:18.5px; line-height:1.64; color:var(--ink)}
.rpt ul{margin:0 0 16px 22px}
.rpt ul li{margin-bottom:6px}
/* Bold inside body copy is --navy, not --navy-ink. House decision, Oct 2026:
   a bold lead-in like “Electrode boilers” should read as part of the page's
   navy structure rather than as slightly darker body text. 12.4:1 on white,
   9.7:1 on the pull-out fill, 11.0:1 on the closing grey — clears AA on every
   ground it sits on. --navy-ink stays a token; nothing else used it. */
.rpt strong{font-weight:800; color:var(--navy)}
.rpt em{font-style:italic}
.rpt a{color:var(--sea); text-underline-offset:2px}

/* In-page cross-references. The body copy names its own sections in prose
   ("we discuss these policies in-depth in Section 4"); each name is a jump
   link, held on one line so a reference never breaks across a wrap.
   The scroll offset keeps whatever a jump lands on clear of the sticky
   jump-nav — it applies to every in-page target on the page, not just these,
   so the nav's own links and the endnote back-links land correctly too. */
.rpt .xref{white-space:nowrap}
.rpt section[id], .rpt .finddiv[id], .rpt .sechead[id], .rpt .callout[id],
.rpt .read h3[id], .rpt .read h4[id], .rpt .figure[id]{
  scroll-margin-top:calc(var(--nav-top, 0px) + 60px)}

/* CALLOUT — a whole sub-section set off from the flow as a filled box, with its
   own sub-sections behind disclosures.

   Built for 2.1.1, where the authors survey two technologies they state they do
   NOT model. That is a different kind of material from the sections around it:
   adjacent, worth knowing, not load-bearing for the results. The fill says so
   without adding a word of copy, and the disclosures let a reader take one
   technology, both, or neither without the page committing four screens of
   depth to something it has told them is out of scope.

   Marked by its FILL, per the house rule — no coloured stripe. Body copy on
   tint takes --mut-tint. The hairlines between rows are list dividers, the same
   device .kf-row uses, not an accent. */
.rpt .callout{max-width:var(--readw); margin:34px 0; background:var(--tint);
  padding:26px 30px 8px}
/* The box's heading is still a sub-section head and has to read as that rank:
   the same serif, weight and clamp as .sechead:not(.numbered):not(.major), so
   2.1.1 sits level with 3.3.1-3.3.4 rather than shrinking because it is in a
   box. Colour is the one deliberate difference — plain --aqua measures 3.83:1
   on this fill, under AA, which is exactly what --aqua-tint (4.64:1) exists
   for. */
.rpt .callout > h2{font-family:var(--serif); font-weight:700;
  font-size:clamp(24px, 2.5vw, 29.5px); line-height:1.3; letter-spacing:-.015em;
  color:var(--aqua-tint); margin:0 0 14px; text-wrap:pretty}
.rpt .callout > p{color:var(--mut-tint); margin:0 0 18px}
.rpt .callout > p:last-child{margin-bottom:18px}

/* one disclosure row */
.rpt .co-item{border-top:1px solid rgba(0,54,96,.15)}
.rpt .co-item summary{list-style:none; cursor:pointer; position:relative;
  padding:14px 38px 14px 0; outline:0}
.rpt .co-item summary::-webkit-details-marker{display:none}
/* Panel titles are the draft's own h3s, so they keep the h3 rank's size and
   weight. Aqua again drops to --aqua-tint on the fill; hover goes to navy,
   since a hover state that lands on the resting colour is no state at all. */
.rpt .co-item summary h3{margin:0; font-size:19px; line-height:1.35;
  color:var(--aqua-tint); font-weight:800}
.rpt .co-item summary:hover h3{color:var(--navy)}
.rpt .co-item summary:hover::before, .rpt .co-item summary:hover::after{
  background:var(--navy)}
.rpt .co-item summary:focus-visible{outline:2px solid var(--aqua); outline-offset:3px}
/* The +/− is drawn, not a glyph, so it cannot pick up a font's own metrics and
   drift off the heading's optical centre. */
.rpt .co-item summary::before, .rpt .co-item summary::after{
  content:''; position:absolute; right:4px; top:50%; background:var(--aqua-tint);
  transition:transform .18s ease, opacity .18s ease}
.rpt .co-item summary::before{width:15px; height:2.5px; margin-top:-1.25px}
.rpt .co-item summary::after{width:2.5px; height:15px; right:10.25px; margin-top:-7.5px}
.rpt .co-item[open] summary::after{transform:rotate(90deg); opacity:0}
/* A paragraph after the last disclosure closes the box and belongs to the
   section, not to the panel above it. Without this rule it butts straight
   against the last row and reads as that panel's own text. */
.rpt .callout > .co-item + p{border-top:1px solid rgba(0,54,96,.15);
  margin-top:0; padding-top:18px}
.rpt .co-body{padding:0 0 6px}
.rpt .co-body > p{color:var(--mut-tint)}
.rpt .co-body > p:last-child{margin-bottom:18px}
/* A figure inside the box is already inside the read column, so it must not
   re-apply that width or it overhangs the padding. */
.rpt .co-body .figure{max-width:none; margin:18px 0 20px}
@media(max-width:600px){
  .rpt .callout{padding:20px 20px 6px; margin:26px 0}
  .rpt .callout > h2{font-size:24px}   /* matches the plain rank's small end */
}

/* EQUIPMENT SLIDESHOW — 2.1, ported from the Pennsylvania page.
   Navy fill, by request. That is a departure from the house rule that pull-outs
   in the body take --tint and navy is reserved for page structure (masthead,
   bands, rules) — flagged, not silent. Everything inside is re-coloured for the
   dark ground: white title, --light-mist lead (9.69:1), gold accents, and the
   cards stay white so they read as objects sitting ON the band rather than
   holes punched in it. */
.rpt .eq-box{background:var(--navy); padding:28px 30px 10px; margin:26px 0 34px}
.rpt .eq-box > h2{color:#fff}
.rpt .eq-box .eq-lead{color:var(--light-mist); margin:0 0 20px; max-width:52em}
.rpt .eq-slides{overflow:hidden; background:transparent}
.rpt .eq-track{display:flex; transition:transform .38s cubic-bezier(.33,0,.15,1)}
@media (prefers-reduced-motion:reduce){ .rpt .eq-track{transition:none} }
.rpt .eq-card{flex:0 0 100%; margin:0; display:grid; grid-template-columns:44% 1fr;
  align-items:stretch; gap:0; min-height:262px; background:#fff}
.rpt .eq-shot{min-height:262px; background:var(--panel);
  display:flex; align-items:center; justify-content:center; overflow:hidden}
.rpt .eq-shot img{width:100%; height:100%; object-fit:cover; display:block}
/* A LABELLED placeholder, not a blank box — a missing photo has to be obvious
   in review. Never publish with one showing. */
.rpt .eq-shot.eq-missing img{display:none}
.rpt .eq-shot.eq-missing::after{content:'PHOTO TO ADD'; font-size:11px; font-weight:800;
  letter-spacing:.14em; color:#8a97a0; border:1px dashed #b9c4cb; padding:10px 14px}
.rpt .eq-text{padding:24px 28px; display:flex; flex-direction:column; justify-content:center}
.rpt .eq-badge{align-self:flex-start; font-size:10.5px; font-weight:800; letter-spacing:.12em;
  background:var(--tint); color:var(--navy); padding:4px 9px; margin-bottom:10px}
.rpt .eq-text h4{font-family:var(--sans); font-size:18px; font-weight:800; color:var(--navy);
  margin:0 0 8px; line-height:1.3}
.rpt .eq-text p{font-size:15px; line-height:1.6; color:var(--mut); margin:0}
.rpt .eq-text .eq-src{font-size:12.5px; color:var(--faint); margin-top:12px}
/* controls — on navy, so they invert */
.rpt .eq-nav{display:flex; align-items:center; justify-content:center; gap:14px;
  padding:16px 0 18px}
.rpt .eq-prev, .rpt .eq-next{width:34px; height:34px; border:1px solid rgba(255,255,255,.45);
  background:transparent; color:#fff; font-size:19px; line-height:1; cursor:pointer;
  border-radius:50%; display:flex; align-items:center; justify-content:center}
.rpt .eq-prev:hover, .rpt .eq-next:hover{border-color:var(--gold); color:var(--gold)}
.rpt .eq-prev:focus-visible, .rpt .eq-next:focus-visible,
.rpt .eq-dot:focus-visible{outline:2px solid var(--gold); outline-offset:2px}
.rpt .eq-dots{display:flex; gap:7px}
.rpt .eq-dot{width:9px; height:9px; border-radius:50%; border:0; padding:0; cursor:pointer;
  background:rgba(255,255,255,.4)}
.rpt .eq-dot[aria-current="true"]{background:var(--gold)}
@media(max-width:700px){
  .rpt .eq-box{padding:22px 20px 8px}
  .rpt .eq-card{grid-template-columns:1fr; min-height:0}
  .rpt .eq-shot{min-height:190px; height:190px}
  .rpt .eq-text{padding:18px 20px}
}

/* key findings — numbered rail */
.rpt .kf{margin:18px 0 6px}
.rpt .kf-row{display:grid; grid-template-columns:52px 1fr 26px; gap:14px; align-items:start;
  padding:14px 6px; border-top:1px solid var(--line); color:inherit; transition:background .15s;
  position:relative}
.rpt .kf-row:last-child{border-bottom:1px solid var(--line)}
/* The row highlights whenever its headline link is hovered or focused. The row
   itself is no longer the link — its body text cites endnotes, and an anchor
   cannot contain another anchor. */
.rpt .kf-row:hover, .rpt .kf-row:focus-within{background:var(--panel)}
/* The whole row already lights up on hover, so the whole row should click —
   the numeral, the arrow and the empty space beside them, not just the
   headline. The headline's own ::after is stretched over the row rather than
   wrapping the row in an anchor, because the body text cites endnotes and an
   anchor cannot contain another anchor. The body sits ABOVE that overlay
   (z-index:1), so its text stays selectable and its endnote links stay
   clickable; everything else in the row falls through to the headline. */
.rpt .kf-h::after{content:''; position:absolute; inset:0; z-index:0}
.rpt .kf-b{position:relative; z-index:1}
.rpt .kf-num{font-size:30px; font-weight:900; color:var(--mist); line-height:1; padding-top:2px; transition:color .15s}
/* A rail whose rows are a set rather than a sequence — the findings — drops the
   numerals and the column that held them. */
.rpt .kf.nonum .kf-row{grid-template-columns:1fr 26px}
@media(max-width:600px){.rpt .kf.nonum .kf-row{grid-template-columns:1fr 20px}}
.rpt .kf-row:hover .kf-num{color:var(--aqua)}
.rpt .kf-h{display:block; font-size:18.5px; font-weight:800; color:var(--navy);
  line-height:1.3; margin-bottom:3px; text-decoration:none}
.rpt .kf-row:hover .kf-h, .rpt .kf-h:focus-visible{text-decoration:underline;
  text-underline-offset:3px; text-decoration-thickness:1.5px}
.rpt .kf-h:focus-visible{outline:2px solid var(--aqua); outline-offset:3px}
.rpt .kf-b{display:block; font-size:15px; color:var(--mut); line-height:1.55}
/* pointer-events:none is what actually makes the arrow clickable, which reads
   backwards until you see why. The arrow and the numeral are decoration — the
   row's one real link is the headline, stretched across the row by .kf-h::after
   above. On hover the arrow takes transform:translateX(3px); a transformed
   element paints in the positioned layer and, coming after the headline in DOM
   order, lands ON TOP of that overlay. So the pointer was over the arrow, the
   row lit up, and the click hit a bare <span aria-hidden> that does nothing.
   Letting pointer events fall straight through puts every click on the link.
   Testing this needs a real hover first — elementFromPoint on an un-hovered
   row resolves to the overlay and reports a false pass. */
.rpt .kf-arrow{align-self:center; font-size:18px; color:var(--faint); transition:color .15s, transform .15s;
  pointer-events:none}
.rpt .kf-num{pointer-events:none}
.rpt .kf-row:hover .kf-arrow, .rpt .kf-row:focus-within .kf-arrow{
  color:var(--aqua); transform:translateX(3px)}
.rpt .kf-row:focus-within .kf-num{color:var(--aqua)}
@media(max-width:600px){.rpt .kf-row{grid-template-columns:40px 1fr 20px} .rpt .kf-num{font-size:24px}}

/* inline emphasis / equity stats — serif numerals, matching the masthead stats.
   Each figure is its OWN filled box. They are two separate facts about two
   different denominators, and one wide panel behind both made them read as a
   single split statistic. Same fill rules as every other pull-out, including the
   flip to white off a non-white ground. */
.rpt .eqstats{display:grid; grid-template-columns:1fr 1fr; gap:18px;
  margin:28px 0 4px; max-width:var(--readw)}
.rpt .eqstat{background:var(--tint); padding:24px 26px}
.rpt .closing .eqstat{background:#fff; border:1px solid var(--line)}
.rpt .eqstat .n{display:block; font-family:var(--serif); font-size:42px; font-weight:700;
  letter-spacing:-.01em; color:var(--navy); line-height:1.05}
.rpt .eqstat .l{display:block; font-size:16px; color:var(--mut-tint); line-height:1.55; margin-top:5px}
.rpt .eqsrc{font-size:13px; color:var(--faint); margin-top:12px}
.rpt .fnote{font-size:14.5px; color:var(--mut); line-height:1.55; max-width:44em; margin-top:10px}
@media(max-width:600px){.rpt .eqstats{grid-template-columns:1fr; gap:14px}
  .rpt .eqstat{padding:20px 22px}}

/* recommendations box */
.rpt .recbox{background:var(--tint); border:0; border-radius:0;
  padding:26px 30px; margin:28px 0; max-width:var(--readw)}
.rpt .recbox p{margin:0 0 16px; font-weight:600; color:var(--navy-ink)}
.rpt .recbox ol{list-style:none; counter-reset:rec; margin:0; padding:0}
.rpt .recbox ol li{counter-increment:rec; position:relative; padding-left:42px; margin-bottom:14px; line-height:1.55}
.rpt .recbox ol li::before{content:counter(rec); position:absolute; left:0; top:1px;
  width:27px; height:27px; border-radius:50%; background:var(--navy); color:#fff;
  font-weight:800; font-size:13.5px; display:flex; align-items:center; justify-content:center}
.rpt .recbox ol li:last-child{margin-bottom:0}

/* pull quote.
   Default is a BLOCK in the reading column, on the tint. It used to default to
   float:right with a gold bar down its left edge, and that lost twice: the bar
   was an accent stripe, and a float dropped in a spot with no body copy beside
   it (after a figure, at the end of a section) escaped its section and collided
   with the next headline. A block can't do that.

   .pull.side restores the float. Only use it INSIDE a run of body copy, with at
   least two paragraphs following it — it needs text to flow beside. */
.rpt .pull{max-width:var(--readw); margin:30px 0; background:var(--tint); padding:24px 30px;
  font-family:var(--serif); font-style:italic; font-weight:700; font-size:21px; line-height:1.45;
  color:var(--navy); text-wrap:balance}
.rpt .pull cite{display:block; margin-top:12px; font-family:var(--sans); font-style:normal;
  font-size:13.5px; font-weight:800; letter-spacing:.02em; color:var(--mut-tint)}
.rpt .pull.side{float:right; width:47%; max-width:400px; margin:6px 0 22px 34px; font-size:19.5px;
  padding:22px 24px}
@media (max-width:640px){
  .rpt .pull{padding:20px 22px; font-size:19px}
  .rpt .pull.side{float:none; width:auto; max-width:none; margin:26px 0}
}

/* callout / note — full-bleed tinted band.
   The band spans the viewport but its TEXT sits in the reading column: the note
   element must stay full width or the 100vw ::before mis-registers, so the
   measure is controlled by the inner .in wrapper instead. */
.rpt .note{position:relative; z-index:0; max-width:none;
  padding:28px 0 30px; margin:34px 0; font-size:17px; line-height:1.62; color:var(--mut-tint)}
.rpt .note .in{max-width:var(--readw)}
.rpt .note::before{content:""; position:absolute; z-index:-1; top:0; bottom:0;
  left:calc(50% - 50vw); width:100vw; background:var(--tint)}
.rpt .note b{color:var(--navy)}
.rpt .note .nl{display:block; font-size:11.5px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--navy); margin-bottom:6px}

/* methods box */
.rpt .methods{background:var(--tint); border:0; padding:26px 30px; margin:26px 0; max-width:var(--readw)}
.rpt .methods h3{margin:20px 0 8px; color:var(--navy)}
.rpt .methods h3:first-child{margin-top:0}
.rpt .methods p{font-size:16px; color:var(--mut-tint); max-width:none}
/* Summary methods are always visible; the disclosure holds FURTHER detail only —
   never the whole methods section. */
.rpt .methods .mextra{margin-top:4px}
.rpt .methods-details{margin-top:18px}

/* ---------- CARD SETS ----------
   Two families of pull-out, and the choice between them is structural:

     TINTED BLOCK (--tint fill, no border) — .note, .pull, .recbox, .methods,
       .eqstat. One continuous thing lifted out of the prose.
     WHITE CARD (white, 1px --line border) — .cards, .claims, .srcgrid. A SET
       of parallel items the reader compares across.

   Neither family uses an accent stripe. A card's colour, when it has one, is
   in a badge or a numeral — something carrying meaning, not decoration. */
.rpt .cards{display:grid; gap:18px; margin:26px 0 6px; max-width:var(--readw)}
.rpt .cards.c2{grid-template-columns:repeat(2,1fr)}
.rpt .cards.c3{grid-template-columns:repeat(3,1fr)}
/* A card is filled, and the fill always contrasts with its ground: --tint on the
   white body of the page, white on the grey ground of the closing act. An unfilled
   card outlined in a hairline reads as an empty box — the fill is what makes a set
   of them scan as objects. Text uses --mut-tint, which clears 4.5:1 on both fills,
   so the same markup works either side of the flip. */
.rpt .card{background:var(--tint); border:1px solid transparent; padding:20px 22px 22px;
  display:flex; flex-direction:column}
.rpt .closing .card{background:#fff; border-color:var(--line)}
/* Anything in a .foot is pushed to the bottom edge of the card, so a figure or a
   label lines up across a row whose descriptions are different lengths. Without
   this the numbers float at whatever height the prose above them ends. */
.rpt .card .foot{margin-top:auto; padding-top:16px}
.rpt .card .badge{align-self:flex-start}

/* ============================================================
   DATA TABLE — .dtable
   Added v1.1. Some reports carry real tables that are not charts and should
   not be forced into one: a health-benefits matrix, a load-by-scenario grid.
   Values a policy reader may quote belong in a table where they can be read
   exactly and copied, not estimated off a bar.
   The header rule is navy and 2px — the same rule .sechead.major uses, i.e.
   house heading vocabulary, not a decorative edge stripe. Row separators are
   hairline --line. Nothing here is marked with a coloured stripe.
   The wrapper scrolls horizontally rather than letting a wide table squeeze
   the type, since a 5-column table cannot reflow to 375px honestly.
   ============================================================ */
.rpt .dtable{margin:26px 0 6px; overflow-x:auto; -webkit-overflow-scrolling:touch}
.rpt .dtable table{border-collapse:collapse; width:100%; min-width:540px;
  font-family:var(--sans); font-size:15px; line-height:1.45;
  border:1px solid var(--navy)}
.rpt .dtable caption{caption-side:top; text-align:left; font-size:13.5px; font-weight:800;
  letter-spacing:.02em; text-transform:uppercase; color:var(--navy); padding-bottom:10px}
/* The header is a filled navy band — the printed reports set their tables this
   way, and it is the fill, not a stripe, that marks it. Cell dividers inside the
   band are a lightened navy so the band stays one object. */
.rpt .dtable thead th{text-align:left; vertical-align:bottom; color:#fff; font-weight:800;
  background:var(--navy); padding:11px 14px; border-right:1px solid rgba(255,255,255,.28)}
.rpt .dtable thead th:last-child{border-right:none}
/* Body-copy bold is --navy by house rule, which is invisible on the navy band —
   inside the header, bold and links take the band's own colour. */
.rpt .dtable thead th strong, .rpt .dtable thead th em,
.rpt .dtable thead th a{color:inherit}
.rpt .dtable thead th a{text-decoration-color:rgba(255,255,255,.6)}
/* A row header is a label, not a column head: it takes the row's hairlines, never
   the header's fill, or every row reads as a new table. */
.rpt .dtable tbody th{text-align:left; vertical-align:top; color:var(--navy); font-weight:800;
  padding:11px 14px; border-bottom:1px solid var(--line); border-right:1px solid var(--line)}
.rpt .dtable td{vertical-align:top; color:var(--ink); padding:11px 14px;
  border-bottom:1px solid var(--line); border-right:1px solid var(--line)}
.rpt .dtable tbody th:last-child, .rpt .dtable td:last-child{border-right:none}
.rpt .dtable tbody tr:last-child th, .rpt .dtable tbody tr:last-child td{border-bottom:none}
/* A cell that spans down into the last row sits in an earlier <tr>, so the
   rule above misses it and its pale hairline beats the table's navy border
   in the collapse, leaving that column with no visible bottom edge. The
   build marks any cell whose span reaches the final row. */
.rpt .dtable tbody td.btm{border-bottom:none}
/* Banding, not borders, is what keeps a wide row readable across the page. */
.rpt .dtable tbody tr:nth-child(even) th,
.rpt .dtable tbody tr:nth-child(even) td{background:var(--tint); color:var(--mut-tint)}
.rpt .dtable tbody tr:nth-child(even) th{color:var(--navy)}
/* A table with vertically merged cells cannot be banded: a stripe is per row,
   and a merged cell spans rows, so the stripes break across it and the merge
   stops reading as one cell. Those tables rely on their cell borders instead,
   and get a little more row padding to compensate. */
.rpt .dtable.spans tbody tr:nth-child(even) th,
.rpt .dtable.spans tbody tr:nth-child(even) td{background:#fff; color:var(--ink)}
.rpt .dtable.spans tbody tr:nth-child(even) th{color:var(--navy)}
.rpt .dtable.spans tbody th, .rpt .dtable.spans tbody td{padding:13px 14px}
.rpt .dtable.spans tbody td[rowspan]{vertical-align:middle; background:var(--tint)}
/* A row that states the universe the rest of the table is measured against. It
   sits in the thead, above the column heads, because it qualifies the whole
   table rather than any one column — so it is centred and reads as a standfirst
   to the navy band below it, not as a first data row. */
.rpt .dtable tr.univ td{background:var(--tint); color:var(--navy); font-weight:800;
  text-align:center; border-bottom:1px solid var(--navy); padding:10px 14px}
.rpt .dtable .num{font-variant-numeric:tabular-nums}
/* A definitional table whose cells hold lists rather than values — Table 1's
   subsectors. One body row, so banding has nothing to alternate with; the tint
   carries it instead. */
.rpt .dtable.listtable tbody td{background:var(--tint); color:var(--ink); width:33.33%}
.rpt .dtable.listtable ul{margin:0; padding-left:19px}
.rpt .dtable.listtable li{margin:0 0 5px; line-height:1.4}
.rpt .dtable.listtable li:last-child{margin-bottom:0}
.rpt .tsrc{font-size:12.5px; line-height:1.55; color:var(--faint); margin:12px 0 38px}
.rpt .tsrc:last-child{margin-bottom:0}

/* ============================================================
   ENDNOTES — sup.fnref + .endnotes
   Added v1.1. A report with 89 sources needs the citation apparatus intact:
   a reader has to be able to see how many sources sit behind a claim and get
   to them. Inline links alone lose that, and hiding them in the methods box
   files the record as an appendix. So: superscript numbers in the prose, a
   Sources section at the foot, and links both ways.
   :target tints the row you jumped to, because landing in a list of 89
   otherwise tells you nothing about which one you came for.
   ============================================================ */
/* CO2e, PM2.5 and NOx put a <sub> in the middle of a sentence. Left to the
   browser's default (vertical-align:sub, font-size:smaller) the subscript grows
   the line box it sits in, so that one line runs ~2.6px taller than the lines
   around it and a paragraph with several of them reads as unevenly leaded.
   Taking it out of the line box and offsetting it with position:relative puts
   the glyph in the same place visually and leaves the leading alone.
   sup.fnref is excluded — it has its own rule below and already does this. */
.rpt sub, .rpt sup:not(.fnref){font-size:.72em; line-height:0;
  position:relative; vertical-align:baseline}
.rpt sub{bottom:-.25em}
.rpt sup:not(.fnref){top:-.45em}

.rpt sup.fnref{font-size:.64em; line-height:0; font-weight:800}
.rpt sup.fnref a{color:var(--sea); text-decoration:none; padding:0 .08em}
.rpt sup.fnref a:hover{text-decoration:underline}
.rpt .endnotes{margin-top:8px}
.rpt .endnotes ol{margin:0; padding-left:2.1em; counter-reset:none}
.rpt .endnotes li{font-size:14.5px; line-height:1.5; color:var(--mut); margin:0 0 3px;
  scroll-margin-top:calc(var(--nav-top, 0px) + 78px); padding:3px 6px 3px 2px; border-radius:2px}
.rpt .endnotes li:target{background:var(--tint); color:var(--mut-tint)}
.rpt .endnotes li a{color:var(--sea)}
.rpt .endnotes .back{margin-left:6px; font-size:12.5px; text-decoration:none; color:var(--faint)}
.rpt .endnotes .back:hover{color:var(--sea)}
@media print{
  .rpt .endnotes li{page-break-inside:avoid}
  .rpt .endnotes .back{display:none}
  .rpt .dtable{overflow:visible}
}

/* A fourth rank inside the reading column, for reports whose source has one.
   Sans, bold, ink — deliberately quieter than the aqua h3 above it. */
.rpt .read h4{font-family:var(--sans); font-size:16.5px; font-weight:800; color:var(--navy-ink);
  margin:22px 0 6px; letter-spacing:.005em}
.rpt .card h4{font-family:var(--sans); font-size:17px; font-weight:800; color:var(--navy);
  line-height:1.34; margin:0 0 6px}
.rpt .card p{font-size:16px; line-height:1.55; color:var(--mut-tint); margin:0; max-width:none}
.rpt .card .k{display:block; font-size:11px; font-weight:800; letter-spacing:.12em;
  text-transform:uppercase; color:var(--mut-tint); margin-bottom:9px}
/* Second-rank kicker inside a card — an aqua label above a block of the card's body,
   e.g. "What we find" over a verdict. Distinct from .k, which labels the card itself. */
.rpt .card .fnd{display:block; font-size:10.5px; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--aqua-tint); margin:13px 0 5px}
.rpt .card .n{display:block; font-family:var(--serif); font-size:34px; font-weight:700;
  color:var(--navy); line-height:1.05; margin-bottom:2px}
.rpt .card .badge{display:inline-block; font-family:var(--sans); font-size:11px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; padding:3px 9px; border-radius:2px;
  margin-bottom:11px; background:var(--navy); color:#fff}
.rpt .card .badge.yes{background:var(--sea)}
.rpt .card .badge.no{background:var(--coral)}
@media (max-width:820px){ .rpt .cards.c2, .rpt .cards.c3{grid-template-columns:1fr} }

/* Chained cards — a set where each item leads to the next, and the connection
   between them is part of the argument. The connector is a real element in the
   grid, not a pseudo-element in the gap, so it survives the mobile reflow by
   rotating a quarter turn. Add .chain to .cards and put a .clink between the
   cards in source order. */
.rpt .cards.chain{gap:0 12px; align-items:stretch}
.rpt .cards.chain.c3{grid-template-columns:1fr 30px 1fr 30px 1fr}
.rpt .cards.chain.c2{grid-template-columns:1fr 30px 1fr}
.rpt .clink{display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:2px; color:var(--mist); line-height:1; align-self:center}
.rpt .clink em{font-family:var(--serif); font-style:italic; font-size:17px; color:var(--faint)}
.rpt .clink span{font-size:24px; font-weight:700}
@media (max-width:820px){
  .rpt .cards.chain.c2, .rpt .cards.chain.c3{grid-template-columns:1fr; gap:0}
  .rpt .clink{flex-direction:row; gap:8px; padding:10px 0}
  .rpt .clink span{transform:rotate(90deg); display:inline-block}
}

/* findings divider band — the top heading rank */
.rpt .finddiv{position:relative; text-align:left; margin:0; padding:36px 0 40px}
.rpt .finddiv::before{content:""; position:absolute; z-index:0; top:0; bottom:0;
  left:calc(50% - 50vw); width:100vw; background:var(--navy);
  border-bottom:5px solid var(--gold)}
.rpt .finddiv h2{position:relative; z-index:1; color:#fff; font-family:var(--sans); font-weight:900;
  text-transform:uppercase; letter-spacing:.015em;
  /* The band is rank 1 and the numbered head rank 2, so the band has to stay
     visibly larger. Sizing it off --headsize rather than its own clamp is what
     guarantees that: the two were independent, and raising the headline to 36px
     brought the numbered head's cap height (25px) level with the band's (26px),
     which read as the band shrinking. 1.06 restores the ~1.2x cap-height lead the
     band had before, at every width, because both now move together.
     Uppercase heavy sans has a taller cap-to-size ratio than the serif headline
     (0.79 against 0.70), so compare cap heights, not font sizes. */
  font-size:calc(1.06 * var(--headsize));
  margin:0; max-width:none}

/* figure frame. Figures align exactly with the body column — same left and right
   edges as the paragraphs above them. The card's own border and shadow already
   separate it from the text, so it doesn't need extra width to register as a
   distinct object; breaking it wider just fought the column.
   Alternative, if a figure should read as inset rather than aligned:
     max-width:calc(var(--readw) - 90px); margin-left:45px;   */
.rpt .figure{margin:26px 0; clear:both; max-width:var(--readw)}
.rpt .figframe{width:100%; border:0; display:block; background:transparent; overflow:hidden}

/* LAST-RESORT fallback: a chart supplied as a finished image instead of rebuilt.
   Use only when the figure genuinely cannot be remade — a partner's copyrighted
   graphic, or a map from a source that must be reproduced as published. A picture
   of a chart loses everything the built figures give you: it does not reflow on a
   phone, the type does not match the page, it prints at screen resolution, a
   corrected number means a new export from whoever made it, and a screen-reader
   user gets only the alt text. Rebuild from the numbers whenever the numbers exist.
   Always give the img real alt text describing the finding, not "chart". */
.rpt .figure img{display:block; width:100%; height:auto;
  border:1px solid var(--line); background:#fff}
.rpt .figure .figttl{font-family:var(--sans); font-size:19px; font-weight:800;
  color:var(--navy); line-height:1.35; margin:0 0 10px}
.rpt .figure .figsrc{font-size:13px; color:var(--faint); margin-top:10px}

/* end CTA */
.rpt .endcta{text-align:center; padding:24px 0 72px}
/* Back to top — navigation, not a third call to action, so it is a quiet link
   under the buttons rather than a button beside them. Navy reads 11.4:1 on the
   closing act's grey; aqua would be 4.39:1, under AA for text this size. */
.rpt .totop{margin:26px 0 0}
.rpt .totop a{font-family:var(--sans); font-size:14px; font-weight:800;
  letter-spacing:.02em; color:var(--navy); text-decoration:none;
  border-bottom:1px solid transparent; padding-bottom:2px}
.rpt .totop a:hover{border-bottom-color:var(--navy)}
.rpt .totop a:focus-visible{outline:2px solid var(--navy); outline-offset:3px}
@media print{ .rpt .totop{display:none} }
.rpt .btn-navy{background:var(--navy); color:#fff; border-color:var(--navy); font-size:13.5px; padding:11px 22px}
.rpt .btn-navy:hover{background:var(--aqua); border-color:var(--aqua); color:#fff}

@media (max-width:720px){
  .rpt{font-size:16px}
  .rpt .hero h1{font-size:28px}
  /* Set the token, not h2's font-size: the numbered tile is computed from
     --headsize, so overriding h2 directly would leave the tile behind. */
  .rpt{--headsize:25px}
  .rpt .sechead:not(.numbered):not(.major) h2{font-size:24px}
}

/* ---------- SCROLL BEHAVIOUR ----------
   A progress bar tracks reading position under the nav. That is all.

   The scroll-reveal that used to live here — each block fading up 16px as it
   entered the viewport — was removed by decision on 15 October. On a report
   this long it worked against the reader: everything below the fold started
   invisible, so skimming, dragging the scrollbar and Ctrl+F outran the
   animation and landed on blank space. The text is now simply present.

   Nothing replaces it, and nothing needs to: the .reveal class was only ever
   added by script, so removing the script (see build.py) leaves plain visible
   markup. Do not reintroduce an opacity:0 default here — a rule that hides
   content and waits for JS is one broken script away from an empty page. */

/* Navy, not gold. Gold measures 1.69:1 against the near-white nav — very faint
   for a mark carrying information — and it was the same colour as the active
   entry's underline 10px above it, so the two read as one smudged rule. Navy is
   12.38:1 here and says something different from the gold "you are here". */
.rpt .secnav .progress{position:absolute; left:0; bottom:-1px; height:2px;
  width:var(--read, 0%); background:var(--navy); transition:width .15s linear}
.rpt .secnav{position:sticky}

@media (prefers-reduced-motion:reduce){
  .rpt *{transition:none !important; animation:none !important; scroll-behavior:auto !important}
}

/* ---------- PRINT ----------
   Policy and legislative staff print these. Flatten the bands, drop
   the interactive chrome, keep figures and boxes off page breaks.
   Note: figures are iframes and print inconsistently across browsers —
   for a print-quality version, export the figures as images first. */
@media print{
  .rpt{font-size:10.5pt; color:#000; background:#fff}
  .rpt .secnav, .rpt .hero-foot, .rpt .endcta, .rpt .btn, .rpt .accent-bar{display:none !important}
  .rpt .masthead{background:#fff !important; color:#000; margin:0}
  .rpt .masthead .hero{padding:0 0 18pt}
  .rpt .hero h1, .rpt .hero .dek, .rpt .hero .authors, .rpt .hero .byline{color:#000}
  .rpt .eyebrow{color:#000}
  /* Reveal the print-only 2035 mark: a printed page has no site header. */
  .rpt .logo-print{display:block !important; width:auto; height:34pt; margin-bottom:14pt}
  .rpt .cobrand .cb-l{color:#444}
  .rpt .logo-partner{display:none !important}
  .rpt .cb-print{display:inline !important; font-size:10pt; font-weight:800;
    letter-spacing:.05em; text-transform:uppercase; color:#000}
  .rpt .hero-band{height:2in}
  /* Paper has no click. Every disclosure prints open, with its control gone,
     so nothing the authors wrote is lost off a printed copy. */
  .rpt .co-item summary::before, .rpt .co-item summary::after{display:none !important}
  .rpt .co-item summary{padding-right:0}
  .rpt .co-body{display:block !important}
  .rpt .callout{background:#fff; border:1pt solid #bbb; padding:10pt 12pt}
  .rpt .finddiv::before, .rpt .note::before, .rpt .closing::before{display:none !important}
  .rpt .finddiv{padding:18pt 0 10pt; border-bottom:2pt solid #000}
  .rpt .finddiv h2{color:#000}
  /* Tints don't survive most office printers, so tinted blocks fall back to a
     hairline box — the one place a border stands in for the fill. */
  .rpt .note{border:1pt solid #bbb; padding:10pt 12pt}
  .rpt .pull, .rpt .recbox, .rpt .methods, .rpt .eqstat{background:none !important;
    border:1pt solid #bbb; padding:10pt 12pt}
  .rpt .pull.side{float:none; width:auto; max-width:none}
  .rpt .card{background:none !important; border:1pt solid #bbb}
  .rpt .clink{display:none}
  .rpt .cards.chain.c2, .rpt .cards.chain.c3{grid-template-columns:1fr 1fr; gap:8pt}
  .rpt .rpt-main, .rpt .read, .rpt .sechead, .rpt .methods{max-width:none; width:auto}
  .rpt section{padding-top:16pt}
  .rpt .sechead{break-after:avoid}
  .rpt .figure, .rpt .recbox, .rpt .methods, .rpt .eqstat,
  .rpt .note, .rpt .card, .rpt .pull{break-inside:avoid}
  .rpt a{color:#000; text-decoration:underline}
  .rpt a[href^="http"]::after{content:" (" attr(href) ")"; font-size:8pt; color:#444; word-break:break-all}
}

/* ---------- SCENARIO KEY — CURRENTLY UNUSED ----------
   Superseded on 15 Oct: the definitions now sit on each scenario label INSIDE
   the figures (gen/add_scenario_tips.py), which is where the reader meets the
   name. These rules are kept because _scen_block() in build.py is kept — the
   single-panel form is one line away if the per-label tips read as too busy.

   Six figures plot the technology scenarios by name — "Baseline", "Drop-In
   Electrification", "Adv Elec (EE+)" — and a reader who meets one of those
   charts before Table 2, or who arrives on a deep link, has no way to know what
   they mean without scrolling off to find the table. This puts the authors'
   own definitions one hover away, beside the figure that needs them.

   The copy is Table 2 verbatim; build.py reads it out of the draft, so it
   cannot drift from the table printed in §2.2.

   Hover alone is not an affordance — it does not exist on touch and cannot be
   reached from the keyboard — so the control is a real <button> that toggles,
   and hover is an extra on pointer devices only. */
.rpt .scen{position:relative; display:flex; justify-content:flex-end; margin:10px 0 0}
.rpt .scen-btn{font:inherit; font-size:13.5px; font-weight:800; letter-spacing:.01em;
  color:var(--aqua-tint); background:none; border:0; padding:5px 3px; cursor:pointer;
  border-radius:3px; text-underline-offset:3px}
.rpt .scen-btn:hover, .rpt .scen.open .scen-btn{text-decoration:underline}
.rpt .scen-btn::before{content:'\24D8'; margin-right:6px; font-weight:400; font-size:15px;
  line-height:1; vertical-align:-1px}
.rpt .scen-panel{display:none; position:absolute; right:0; top:100%; z-index:30;
  width:min(640px, 100%); background:var(--tint); color:var(--mut-tint);
  padding:16px 20px 18px; border-radius:3px; box-shadow:0 12px 34px rgba(0,16,32,.18);
  font-size:14px; line-height:1.5; text-align:left;
  /* Five scenarios with the authors' notes runs ~800px, taller than a lot of
     windows. Cap it and let the panel scroll rather than running off-screen;
     overscroll-behavior keeps that scroll from carrying on into the page. */
  max-height:min(62vh, 540px); overflow-y:auto; overscroll-behavior:contain}
.rpt .scen.open > .scen-panel{display:block}
/* Pointer devices get hover as a shortcut; touch and keyboard use the button. */
@media (hover:hover) and (pointer:fine){ .rpt .scen:hover > .scen-panel{display:block} }
.rpt .scen-panel .scen-lede{font-size:12.5px; font-weight:800; letter-spacing:.07em;
  text-transform:uppercase; color:var(--navy); margin:0 0 10px}
.rpt .scen-panel dl{margin:0}
.rpt .scen-panel dt{font-weight:800; color:var(--navy); font-size:14.5px; margin-top:13px}
.rpt .scen-panel dl > dt:first-child{margin-top:0}
.rpt .scen-panel dd{margin:3px 0 0}
/* The authors' column headers run long, so each spec sits on its own row with
   the label in its own column rather than wrapping around a middot. */
.rpt .scen-panel .scen-spec{display:grid; grid-template-columns:max-content 1fr;
  gap:1px 14px; margin:2px 0 5px}
.rpt .scen-panel .scen-k{font-weight:800; color:var(--navy)}
/* Narrow screens: the overlay has nowhere to go, so it becomes a block in flow. */
@media (max-width:760px){
  .rpt .scen{display:block}
  .rpt .scen-panel{position:static; width:auto; box-shadow:none; margin-top:8px}
}
/* Table 2 is in the printed document a few pages earlier; six copies of it
   under six figures is not. */
@media print{ .rpt .scen{display:none} }
