/* ==========================================================================
   report.css — company report page (/company/{slug})
   --------------------------------------------------------------------------
   Loaded AFTER landing.css, via the 'styles' slot in layouts/landing.php, and
   ONLY on this page. The report page is still wrapped in .landing, so every
   token in landing.css (colours, type scale, spacing unit, --lp-nav-h) plus the
   whole header / CTA / footer stylesheet already apply here — this file only
   adds the report-specific `rp-` layer on top.

   Conventions carried over from landing.css, deliberately:
     - prefix by page: lp- shared/landing, cp- companies listing, rp- report
     - spacing as calc(var(--spacing-padding-inline) * N), where N * 4 = px
     - NEVER redeclare a token that already exists in landing.css
   ========================================================================== */

/* --- report-scoped tokens ---
   Values the shared scale has no entry for, stepped over the same breakpoint
   ladder landing.css uses for its type and padding tokens so the report scales
   with the rest of the site rather than against it.

   --rp-hero-pad-top / -bottom come straight from the reference (120 / 160 at
   1920). They are the hero's padding ON TOP OF the header's height — see the
   .rp-hero rule below for why that addition is needed.

   --rp-font-lead is 32px in the reference. --alpha-body-large is 30px and
   nothing else is close, so it gets its own ladder. Two things are this size by
   design and share the token: the hero dek and the Insights card title.

   --rp-toc-w / --rp-chapter-gap are the reference's 323px + 129px, which with the
   888px content column sum to exactly the 1340px wrap. Because the sum is fixed,
   the content column is NOT given a width — it takes the remainder, so these two
   tokens are the only ones that need stepping. */
.landing {
  --rp-hero-pad-top: 120px;
  --rp-hero-pad-bottom: 160px;
  --rp-font-lead: 32px;
  --rp-toc-w: 323px;
  --rp-chapter-gap: 129px;
  --rp-chapter-space: 160px;
  --rp-chart-h: 366px;
  /* Taller canvas for charts that need to stay roughly square (the radar) —
     the reference's card is 745px tall against ~466-541px for the line/bar
     cards, and a hexagon squeezed into --rp-chart-h would read as flattened.
     Trimmed from 620 to 520: at 620 the radar's own legend-to-polygon gap
     (fixed by the legend sitting at top:0, the polygon's radius scaling off
     this height) read as too much empty space above the chart; 520 is still
     tall enough to keep the hexagon from flattening. */
  --rp-chart-h-square: 520px;

  /* Two greys the shared palette has no entry for. landing.css has --lp-border
     (#E0E0E0) and --lp-muted (#888) either side of both, but the reference is
     specific: "Neutrals/200" for an idle TOC label, "Neutrals/150" for the rule
     under an insight heading. */
  --rp-toc-idle: #C2C2C2;
  --rp-rule: #D1D1D1;

   /* Nature-of-evidence key for the Verify chapter's table — how a claim was
     established, which is a THIRD axis alongside the claim and its verification
     status, so it is carried by dot colour rather than by a column of its own.
     Three categories, so the lime/orange pair the rest of this file uses for
     two-way legends no longer covers it. Deliberately outside the brand palette:
     these read as a data key, not as page furniture, and orange is already the
     page's accent (a brand-orange dot would look like emphasis rather than a
     category). Used by BOTH .rp-verify-dot--* and the matching
     .rp-chart-legend-dot--* modifiers, so the key and the rows cannot drift. */
  --rp-evidence-self: #F97316;
  --rp-evidence-measured: #3B82F6;
  --rp-evidence-third: #22C55E;

  /* Table body/header type. The reference sets both report tables at 12.5-13.5px
     — denser than anything on the shared scale (--alpha-body-xs bottoms out at
     16px), because these tables carry 11 rows of three-to-four columns and only
     fit on one line each at that size. Rounded to 14px rather than copied at
     12.5px: the reference's value is uncomfortably small on a modern display,
     and 14px still keeps every row single-line at the reference's column
     proportions. */
  --rp-font-table: 14px;

  /* Timeline row spacing and date column. --rp-tl-gap is the reference's 96px
     marker pitch minus the 26px row content height; --rp-tl-date-w places the
     event text at 168px from the list's left edge against the reference's
     169px. */
  --rp-tl-gap: 70px;
  --rp-tl-date-w: 100px;

  /* Gap either side of each meta-row dot separator (list gap before the item,
     item gap after the dot) — shrinks with the rest of the hero type so the
     three items don't read as far-flung once the dots themselves are small. */
  --rp-meta-gap: 24px;

  /* Gap between top-level report sections (hero excluded — its own
     --rp-hero-pad-* tokens already carry a deliberately different value).
     NOT --section-pad-block: that shared token is tuned for the marketing
     page's rhythm and only reaches 200px above 1800px, dropping to 160/100/60
     in between — measured on this page, that put the chapters→references gap
     at 160px on a 1440px laptop and 60px around 1366-1280px, well under the
     reference's flat 200px. This is its own token instead, on report.css's own
     breakpoint ladder, so every width gets the same 200px the reference
     specifies rather than whatever the landing page's ladder happens to give. */
  --rp-section-gap: 200px;
}
/* The hero padding is unchanged in this band (the reference's 120/160 holds from
   1400px up), so only the type steps here. */
@media (max-width: 1799px) {
  .landing { --rp-font-lead: 30px; --rp-font-table: 13.5px; --rp-tl-gap: 64px; --rp-tl-date-w: 96px; --rp-section-gap: 180px; --rp-meta-gap: 22px; }
}
@media (max-width: 1399px) {
  .landing {
    --rp-hero-pad-top: 80px;
    --rp-hero-pad-bottom: 120px;
    --rp-font-lead: 26px; --rp-font-table: 13px; --rp-tl-gap: 56px; --rp-tl-date-w: 92px;
    --rp-meta-gap: 18px;
    --rp-toc-w: 260px;
    --rp-chapter-gap: 72px;
    --rp-chapter-space: 128px;
    --rp-chart-h: 320px;
    --rp-chart-h-square: 460px;
    --rp-section-gap: 140px;
  }
}
@media (max-width: 1024px) {
  .landing {
    --rp-hero-pad-top: 64px;
    --rp-hero-pad-bottom: 96px;
    --rp-font-lead: 24px; --rp-font-table: 13px; --rp-tl-gap: 48px; --rp-tl-date-w: 88px;
    --rp-meta-gap: 16px;
    --rp-chapter-space: 104px;
    --rp-chart-h: 280px;
    --rp-chart-h-square: 380px;
    --rp-section-gap: 110px;
  }
}
@media (max-width: 767px) {
  .landing {
    --rp-hero-pad-top: 48px;
    --rp-hero-pad-bottom: 72px;
    --rp-font-lead: 20px; --rp-font-table: 12px; --rp-tl-gap: 36px; --rp-tl-date-w: 88px;
    --rp-meta-gap: 12px;
    --rp-chapter-space: 80px;
    --rp-chart-h: 240px;
    --rp-chart-h-square: 280px;
    --rp-section-gap: 90px;
  }
}
@media (max-width: 479px) {
  .landing {
    --rp-hero-pad-top: 40px;
    --rp-hero-pad-bottom: 56px;
    --rp-font-lead: 18px; --rp-font-table: 12px; --rp-tl-gap: 28px; --rp-tl-date-w: 88px;
    --rp-meta-gap: 10px;
    --rp-chapter-space: 64px;
    --rp-chart-h: 210px;
    --rp-chart-h-square: 240px;
    --rp-section-gap: 64px;
  }
}

/* Visually hidden but reachable by a screen reader. */
.rp-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- hero ---
   The dark band the report opens on. Two things about the padding:

   1. The extra --lp-nav-h on top is not optional. The header is position:fixed
      and transparent here, so it floats OVER this section instead of taking
      space above it; without it the breadcrumb sits under the logo. --lp-nav-h
      is the RESTING header height, which is the correct one — the header is
      only un-scrolled while the top of the hero is in view. Same reasoning as
      .lp-hero and .cp-section in landing.css.

   2. The side padding lives on the SECTION and .lp-wrap's own 24px is zeroed
      below. This is the pattern #company-profile / #stories / #cta already use:
      leaving both in place stacks the gutters (80 + 24 = 104px). It also lands
      the reference geometry for free — at >=1800px --section-pad-inline is
      120px, which is more than the 290px the centred 1340px wrap needs at
      1920px wide, so the column is exactly 1340px with exactly 290px gutters. */
.rp-hero {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* Vertically centers the .lp-wrap flex item within the 100vh box — same
     approach .lp-hero uses. The padding above still does its job: it's what
     keeps the content optically centered in the visible area rather than the
     full 100vh, since the fixed transparent header covers --lp-nav-h of the
     top. */
  justify-content: center;
  background: var(--lp-black);
  color: #fff;
  padding: calc(var(--lp-nav-h) + var(--rp-hero-pad-top))
           var(--section-pad-inline)
           var(--rp-hero-pad-bottom);
}
.rp-hero > .lp-wrap { padding-inline: 0; }

/* Children keep the default align-items:stretch so the headline, dek and meta row
   are exactly as wide as the column and wrap against it. Only the breadcrumb pill
   needs to hug its own text, so it opts out individually below — doing it on the
   CONTAINER instead (align-items:flex-start) would switch every child to
   fit-content sizing, which is a reliable source of narrow-viewport overflow. */
.rp-hero .lp-wrap {
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing-padding-inline) * 10);
}

/* --- breadcrumb ---
   A dark-glass pill. Reuses the two nav-pill tokens rather than repeating their
   rgba values, so a change to the glass treatment moves both together. Note
   this is the DARK counterpart of .cp-breadcrumb (which sits on a light page
   and uses --lp-tag-bg); the two are intentionally separate rules. */
.rp-breadcrumb {
  display: inline-flex;
  align-self: flex-start; /* hug the crumbs instead of stretching to the column */
  align-items: center;
  gap: calc(var(--spacing-padding-inline) * 2);
  padding: calc(var(--spacing-padding-inline) * 2) calc(var(--spacing-padding-inline) * 6);
  background: var(--lp-nav-pill-bg);
  border: 1px solid var(--lp-nav-pill-border);
  border-radius: 100px;
  font-size: var(--alpha-body-xs);
  line-height: 1.3;
  color: #fff;
}
/* Needs the element prefix to out-specify `.landing a { color: inherit }`. The
   reference keeps all three crumbs white — the current page is NOT muted. */
.rp-breadcrumb a { color: #fff; }
.rp-breadcrumb a:hover,
.rp-breadcrumb a:focus-visible { text-decoration: underline; }
.rp-caret { flex: none; width: 16px; height: 16px; }

/* --- headline ---
   max-width is the reference's 1239px measure: it forces the same two-line
   break as the design without a hardcoded <br>, so a longer or shorter
   headline still wraps sensibly. */
.rp-hero h1 {
  max-width: 1000px;
  margin: 0;
  font-size: var(--alpha-heading-h0);
  font-weight: var(--font-weight-medium);
  line-height: 1.1;
  letter-spacing: -0.01em;
}
@media (max-width: 1399px) {
  .rp-hero h1 { max-width: 900px; }
}
@media (max-width: 1230px) {
  .rp-hero h1 { max-width: 800px; }
}
@media (max-width: 1024px) {
  .rp-hero h1 { max-width: 700px; }
}
@media (max-width: 767px) {
  .rp-hero h1 { max-width: 600px; }
}
/* .accent is scoped to .lp-hero h1 in landing.css, so it has to be restated
   here rather than inherited. */
.rp-hero h1 .accent { color: var(--lp-orange); }

/* --- dek --- */
.rp-dek {
  max-width: 1210px;
  margin: 0;
  font-size: var(--rp-font-lead);
  font-weight: var(--font-weight-regular);
  line-height: 1.3;
  color: #fff;
}

/* --- meta row ---
   The 5px dots are pseudo-elements on every item but the first, and the gap is
   declared on BOTH the list and the items via --rp-meta-gap (24px at base,
   stepping down with the rest of the hero type). That puts an equal gap on
   each side of every dot (list gap before the item, item gap after the dot)
   matching the reference, while keeping the markup three real list items for
   assistive tech instead of interleaved separator spans. */
.rp-meta {
  display: flex;
  align-items: center;
  gap: var(--rp-meta-gap);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--alpha-body-small);
  line-height: 1.3;
  color: var(--lp-bg-light);
}
.rp-meta li {
  display: flex;
  align-items: center;
  gap: var(--rp-meta-gap);
}
.rp-meta li + li::before {
  content: '';
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--lp-bg-light);
}
.rp-meta-lead { font-weight: var(--font-weight-medium); }

/* Not in the reference (which is desktop-only): let the three items reflow
   rather than overflow once the column gets narrow. */
   @media (width: 768px) {
         .rp-meta { flex-wrap: wrap;}
   }
@media (max-width: 767px) {
  .rp-meta {
    flex-wrap: wrap;
    row-gap: calc(var(--spacing-padding-inline) * 2);
  }
}

/* --- floating chatbot link ---
   Moved to assets/css/report-chat.css: the companies list ("Reports") and stories list
   ("Insights") pages now use this same .rp-chatbot-fab image button (see report-chat.css
   for the rule and app/views/companies.php / stories/index.php for the markup), and those
   pages don't load this file. report.js's `.is-hidden` scroll toggle (hero/CTA boundary)
   still only runs on this page — see report-chat.css for the class it toggles. */

/* --- nav anchor targets ---
   The header nav links to these four sections by id. The header is fixed
   (landing.css .lp-nav), so without an offset the jump lands with the section's
   top tucked underneath it. landing.css does the same for its own sections on
   line 5; these are the report's, which that selector never covered. Same
   formula as .rp-chapter below, so a section jump and a TOC chapter jump clear
   the nav by the same amount. --lp-nav-h-scrolled is stepped per breakpoint in
   landing.css, so this follows the header down as it shrinks. */
.rp-overview, .rp-stats, .rp-chapters, .rp-refs {
  scroll-margin-top: calc(var(--lp-nav-h-scrolled) + calc(var(--spacing-padding-inline) * 8));
}

/* --- overview (company card) ---
   Reference vertical padding is 200/200 at 1920 — --rp-section-gap, the
   report's own inter-section token (see the definition up top for why this
   isn't --section-pad-block). Side padding uses the same zero-the-wrap
   technique as .rp-hero. */
.rp-overview { padding: var(--rp-section-gap) var(--section-pad-inline); }
.rp-overview > .lp-wrap {
  padding-inline: 0;
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing-padding-inline) * 6);
}

.rp-overview-head {
  display: flex;
  align-items: center;
  gap: calc(var(--spacing-padding-inline) * 8);
}
.rp-overview-head h2 {
  margin: 0;
  font-size: var(--alpha-heading-h1);
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--lp-black);
}
/* Not in the reference (static there): a hover nudge so the link affords being
   clickable, consistent with the lift/fill treatment other buttons on the site
   use on hover. */
/* Same size ladder as .rp-chatbot-fab (64 -> 56 -> 48 -> 44), via its own token
   rather than sharing --fab-size — the two are unrelated elements that merely
   happen to agree on size at every breakpoint today. */
.rp-external-link {
  --link-size: 64px;
  flex: none;
  width: var(--link-size);
  height: var(--link-size);
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  transition: transform 0.2s ease;
}
@media (max-width: 1024px) { .rp-external-link { --link-size: 48px; } .rp-overview-head{gap: calc(var(--spacing-padding-inline) * 4);} }
@media (max-width: 767px)  { .rp-external-link { --link-size: 48px; } }
@media (max-width: 479px)  { .rp-external-link { --link-size: 38px; } }
.rp-external-link:hover, .rp-external-link:focus-visible { transform: scale(1.06); }
.rp-external-link img { width: 100%; height: 100%; object-fit: cover; display: block; }

.rp-overview-body {
  display: flex;
  align-items: center;
  gap: calc(var(--spacing-padding-inline) * 20);
}
.rp-overview-text {
  flex: 1 1 0%;
  min-width: 0;
  margin: 0;
  font-size: var(--alpha-body-medium);
  font-weight: var(--font-weight-regular);
  line-height: 1.3;
  color: var(--lp-black);
}
/* Fixed brand colour (InstaAgent's own magenta), not a site token — this square
   is per-company art, not shared chrome. Sized with clamp rather than the
   breakpoint ladder so it scales continuously instead of jumping; the two
   images inside are positioned by percentage of THIS box so they stay in
   proportion at every size instead of needing their own breakpoints. */
.rp-overview-mark {
  flex: none;
  position: relative;
  width: clamp(180px, 22vw, 323px);
  aspect-ratio: 1;
  border-radius: 40px;
  background: #B83587;
  overflow: hidden;
}
.rp-overview-mark img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.rp-overview-mark-glow { width: 60.3%; height: 58.1%; }
.rp-overview-mark-logo { width: 40.3%; height: 38.7%; }

@media (max-width: 1024px) {
  .rp-overview-mark{width: 100%; border-radius: 0px;}
  .rp-overview-body{gap: calc(var(--spacing-padding-inline) * 14); flex-direction: column;}
}

@media (max-width: 767px) {
  /* Centred, not full-bleed — stretching to 100% distorted the mark since its
     two SVGs are sized by percentage of a square box; keep the original clamp
     dimensions and just centre the stack. */
  .rp-overview-body { flex-direction: column; align-items: center; gap: calc(var(--spacing-padding-inline) * 12); }
}

/* --- stats ("Five numbers behind the pitch") ---
   No top padding: the reference relies on .rp-overview's own bottom padding
   for the gap above this heading, so the two sections together read as one
   200px gap rather than 400px. */
.rp-stats { padding: 0 var(--section-pad-inline) var(--rp-section-gap); }
.rp-stats > .lp-wrap {
  padding-inline: 0;
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing-padding-inline) * 20);
}
.rp-stats-heading {
  margin: 0;
  text-align: center;
  font-size: var(--alpha-heading-h1);
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--lp-black);
}
.rp-stats-heading .accent { color: var(--lp-orange); }

/* 6 columns reproduces the reference's 3-then-2 layout: cards 1-3 span 2 of 6
   (three across), cards 4-5 span 3 of 6 (two across). align-items:stretch keeps
   every card in a row sharing that row's tallest height, same as the flex rows
   this replaced. */
.rp-stats-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: calc(var(--spacing-padding-inline) * 4);
  align-items: stretch;
}
.rp-stat-card:nth-child(-n+3) { grid-column: span 2; }
.rp-stat-card:nth-child(n+4)  { grid-column: span 3; }
.rp-stat-card {
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 40px;
  padding: calc(var(--spacing-padding-inline) * 10);
}
.rp-stat-index {
  margin: 0 0 calc(var(--spacing-padding-inline) * 10);
  font-size: var(--alpha-body-medium);
  line-height: 1.35;
  color: var(--lp-muted);
}
.rp-stat-value {
  margin: 0 0 calc(var(--spacing-padding-inline) * 6);
  font-size: var(--alpha-heading-h0);
  font-weight: var(--font-weight-medium);
  line-height: 1.1;
  color: var(--lp-black);
}
.rp-stat-caption {
  margin: 0;
  font-size: var(--alpha-body-medium);
  line-height: 1.35;
  color: var(--lp-black);
}

/* Reference is a fixed 3-then-2 grid on a 1920 canvas; not viable once cards
   get narrower than their content. The nth-child spans above must be reset to
   `auto` at each step below or they keep fighting the new column count. */
@media (max-width: 1024px) {
  .rp-stats-grid { grid-template-columns: repeat(2, 1fr); gap: 16px; }
  .rp-stat-card:nth-child(-n+3), .rp-stat-card:nth-child(n+4) { grid-column: auto; }
  /* An odd card count leaves the last card alone in its 2-col row — stretch it
     across both columns. nth-child(odd) keeps even counts as a clean 2-up. */
  .rp-stat-card:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .rp-stat-card { padding: 32px; border-radius: 20px; }
}
@media (max-width: 767px) {
  .rp-stat-card { padding: 28px; }
}
@media (max-width: 600px) {
  .rp-stats-grid { grid-template-columns: 1fr; gap: 16px; }
  .rp-stats > .lp-wrap{ gap: calc(var(--spacing-padding-inline) * 10);}
}
@media (max-width: 479px) {
  .rp-stats-grid { gap: 10px; }
  .rp-stat-card  { padding: 24px; }
}

/* ==========================================================================
   CHAPTERS
   Two columns: a sticky TOC and the chapter body. The reference's 323 + 129 + 888
   sums to exactly the 1340px wrap, so the body column is given no width at all —
   it takes whatever the TOC and gap leave, which keeps the three numbers in sync
   automatically when the two tokens step down.
   ========================================================================== */
.rp-chapters { padding: 0 var(--section-pad-inline) var(--rp-section-gap); }
.rp-chapters > .lp-wrap { padding-inline: 0; }

.rp-chapters-layout {
  display: flex;
  align-items: flex-start; /* required: a stretched TOC cannot be sticky */
  gap: var(--rp-chapter-gap);
}

/* --- sticky TOC --- */
/* The reference row is: 3px track | 24px gap | 256px labels | 40px right padding.
   Sticky offset is the scrolled header height plus a breathing gap, so the list
   never tucks under the fixed nav. */
.rp-toc {
  position: sticky;
  top: calc(var(--lp-nav-h-scrolled) + calc(var(--spacing-padding-inline) * 8));
  flex: none;
  width: var(--rp-toc-w);
  padding-right: calc(var(--spacing-padding-inline) * 10);
  display: flex;
  align-items: stretch;
  gap: calc(var(--spacing-padding-inline) * 6);
}
/* The track is a plain vertical bar. The reference draws it as a 528x3 rect with
   rotate(90deg), which is just how Figma expresses a vertical bar — rotating here
   would take it out of flow for no reason, so it is simply 3px wide instead. Its
   height comes from align-items:stretch on the row, which ties it to the label
   list's height exactly as the reference's matching 528px values do. */
.rp-toc-track {
  flex: none;
  width: 3px;
  border-radius: 2px;
  background: var(--lp-border);
  overflow: hidden;
}
.rp-toc-fill {
  width: 100%;
  height: 0;
  border-radius: 2px;
  background: var(--lp-orange);
  transition: height 0.18s linear; /* smooths rAF-quantised jumps while scrolling */
}
.rp-toc-list {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing-padding-inline) * 10);
  /* When the chapter list is taller than the sticky pane's viewport slot, scroll
     it in place rather than letting it run off-screen. The cap mirrors the sticky
     top offset (.rp-toc) plus a matching bottom gap. */
  max-height: calc(100vh - var(--lp-nav-h-scrolled) - calc(var(--spacing-padding-inline) * 16));
  overflow-y: auto;
  padding-right: calc(var(--spacing-padding-inline) * 2);
}
.rp-toc-item {
  font-size: var(--alpha-body-medium);
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--rp-toc-idle);
  transition: color 0.2s ease;
}
.rp-toc-item.is-active { color: var(--lp-black); }
/* Element-prefixed to out-specify `.landing a { color: inherit }` — the anchor
   must take the item's state colour, not its own. */
.rp-toc-item a { color: inherit; display: block; }
.rp-toc-item:not(.is-active) a:hover { color: var(--lp-muted); }
/* Chapters that do not exist yet: visible so the track's fill percentage reads
   correctly against all 8, but clearly not yet reachable. */
.rp-toc-item--pending { opacity: 0.45; cursor: default; }

/* --- chapter body --- */
.rp-chapters-body {
  /* No width: takes the remainder of the wrap. min-width:0 stops a wide child
     (a chart, a long unbroken string) from pushing the column past its share. */
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--rp-chapter-space);
}
.rp-chapter {
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing-padding-inline) * 16);
  /* Offsets the fixed header when a TOC link jumps here, so the chapter numeral
     is not hidden behind the nav on arrival. */
  scroll-margin-top: calc(var(--lp-nav-h-scrolled) + calc(var(--spacing-padding-inline) * 8));
}

.rp-chapter-head {
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing-padding-inline) * 4);
}
.rp-chapter-numeral {
  margin: 0;
  font-size: var(--alpha-body-medium);
  font-weight: var(--font-weight-medium);
  line-height: 1;
  color: var(--lp-orange);
}
.rp-chapter-head h2 {
  margin: 0;
  /* Narrower than the 888px column on purpose: at the full column width these
     headings wrap to lines with very uneven measure, and several leave a
     single short word orphaned on its own last line. A flat 640px (rather
     than a stepped token) is deliberate — it's already narrower than every
     breakpoint's column, INCLUDING the ~928px the column widens to once the
     TOC drops out at 1024px, so it keeps doing the same job there; and below
     767px the column itself falls under 640px, so this stops constraining
     anything and the heading just fills its container as before. */
  max-width: 800px;
  font-size: var(--alpha-heading-h2);
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--lp-black);
}

/* The reference sets prose to #000 while everything around it is #0A0A0A. Using
   the token instead — the 5/255 difference is invisible and not worth a
   one-off literal. */
.rp-prose {
  margin: 0;
  font-size: var(--alpha-body-medium);
  font-weight: var(--font-weight-regular);
  line-height: 1.3;
  color: var(--lp-black);
}
/* Back-to-back paragraphs (chapters 4, 5, 6 and 7 each run two or three in a
   row) sit closer together than everything else in the chapter: 24px instead
   of .rp-chapter's normal 64px gap. A single flex `gap` can't carry two
   magnitudes, so a run of consecutive paragraphs is wrapped in one
   .rp-prose-group. That group is a SINGLE child of .rp-chapter, so it keeps
   the chapter's normal 64px gap to the heading/charts on either side, while
   the tighter 24px paragraph rhythm lives inside it as an ordinary positive
   gap — no negative margins. The 24px is the constant --spacing-padding-inline
   (never stepped), so it holds at every breakpoint without its own ladder. */
.rp-prose-group {
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing-padding-inline) * 6);
}

/* --- pull quote ---
   The reference's "Pull Quote 01" component: no side rule, just a 1px top divider
   (the same "Neutrals/150" as the insight headings, hence --rp-rule again) with
   40px above and below it before the text. */
.rp-pullquote {
  margin: 0;
  padding-top: calc(var(--spacing-padding-inline) * 10);
  border-top: 1px solid var(--rp-rule);
}
.rp-pullquote p {
  margin: 0;
  font-size: var(--rp-font-lead);
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--lp-black);
}
/* .accent is scoped per-section throughout this file (see .rp-hero h1 .accent,
   .rp-stats-heading .accent) rather than declared once globally — restated here
   for the same reason. */
.rp-pullquote .accent { color: var(--lp-orange); }

/* --- charts ---
   White card holding a title, the echarts canvas, and a caption. The reference
   absolutely positions all three inside a fixed-height card; in flow they stack,
   which lets a longer title or a two-line caption grow the card instead of
   colliding. --rp-chart-h is the canvas only, so the card height follows. */
.rp-chart {
  margin: 0;
  background: var(--lp-panel);
  border-radius: 24px;
  padding: 40px;
}
@media (max-width: 1024px) { .rp-chapter{gap: calc(var(--spacing-padding-inline) * 10);}}
@media (max-width: 768px) { .rp-chart { padding: 24px; } }
.rp-chart-title {
  margin: 0 0 28px;
  font-size: var(--alpha-body-medium);
  font-weight: var(--font-weight-medium);
  line-height: 1.35;
  color: var(--lp-black);
}
/* The reference gives this exact chart's title a muted grey (#525252) instead of
   the near-black every other chart title uses — a deliberate one-off in the
   source, not a token, so it gets its own modifier rather than changing the
   shared rule above. */
.rp-chart-title--muted { color: #525252; }
/* Chapter 8's summary table titles itself in orange rather than the near-black
   every other card uses — the report's concluding exhibit, called out as such
   in the reference. */
.rp-chart-title--accent { color: var(--lp-orange); }
/* echarts measures its container on init, so this needs a resolved height before
   JS runs — hence a token height rather than an aspect-ratio or intrinsic sizing. */
.rp-chart-canvas { width: 100%; height: var(--rp-chart-h); }
.rp-chart-canvas--square { height: var(--rp-chart-h-square); }
/* Held slightly narrower than the card so the note reads as a caption under the
   chart rather than as a full-width paragraph. A percentage rather than a ch
   measure because it should track the card's width at every breakpoint, and the
   card is already the thing setting the measure here. */
.rp-chart-note {
  margin: 32px 0 0;
  max-width: 90%;
  font-size: var(--alpha-body-small);
  font-weight: var(--font-weight-regular);
  line-height: 1.3;
  color: var(--lp-black);
}

/* --- chart legend (static) ---
   The scatter chart's reference legend is 10 names for what is, colour-wise,
   only 2 categories — every point but InstaAgent's shares one orange, so the
   legend can't be used to pick out any ONE competitor's dot by colour, only to
   confirm the two-category read (InstaAgent vs the field). Given that, this is
   plain markup rather than an interactive echarts legend: there is nothing
   real for a click-to-toggle affordance to do here, since 9 of the 10 entries
   are visually identical anyway. Hover-for-name still works via the chart's
   own tooltip. */
.rp-chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--spacing-padding-inline) * 2) calc(var(--spacing-padding-inline) * 5);
  margin: 0 0 calc(var(--spacing-padding-inline) * 6);
  padding: 0;
  list-style: none;
  max-width: 90%;
}
/* --alpha-body-xs is the report's chart-key size, shared with the echarts-drawn
   legends in report.js (legend().textStyle reads the same token via
   chartKeyFont()) so a hand-written key and a generated one are the same size
   at every breakpoint. The 12px dot matches those legends' itemWidth/itemHeight
   for the same reason. */
.rp-chart-legend li {
  display: flex;
  align-items: center;
  gap: calc(var(--spacing-padding-inline) * 1.5);
  font-size: var(--alpha-body-xs);
  color: var(--lp-black);
}
.rp-chart-legend-dot {
  flex: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--lp-orange);
}
.rp-chart-legend-dot--lead { background: #B8FD15; }
/* The Verify chapter's key is three-way, not the lime/orange pair above — same
   tokens the table's own dots take, so the key always matches the rows. */
.rp-chart-legend-dot--self     { background: var(--rp-evidence-self); }
.rp-chart-legend-dot--measured { background: var(--rp-evidence-measured); }
.rp-chart-legend-dot--third    { background: var(--rp-evidence-third); }


/* --- chart quadrant captions ---
   The four corner labels ("Category Leaders" etc.) sit in the chart's own
   margin, not tied to a specific data coordinate — they're chrome around the
   plot, not an annotation ON it. Plain absolutely-positioned text over the
   canvas is simpler and more robust than asking echarts' graphic layer to
   convert a data point to pixels for a label that isn't really data-anchored. */
.rp-chart-quadrant-wrap { position: relative; }
.rp-chart-quadrant {
  position: absolute;
  font-size: 12px;
  line-height: 1.3;
  color: var(--lp-black);
  pointer-events: none;
}
.rp-chart-quadrant--tl { top: 0; left: 8px; }
.rp-chart-quadrant--tr { top: 0; right: 8px; text-align: right; font-weight: var(--font-weight-medium); }
.rp-chart-quadrant--bl { bottom: 0; left: 8px; letter-spacing: 0.02em; }
.rp-chart-quadrant--br { bottom: 0; right: 8px; text-align: right; letter-spacing: 0.02em; }

/* --- callout (single always-visible highlight, no toggle) ---
   Replicates .table-verdict ("What we'd do:") from
   immigration.alphaventure.com/best-immigration-case-management-software:
   a rounded 8px orange bar down the left edge, orange H4 title, dark body.
   Sizes ride the same --alpha-* tokens as the reference, so the responsive
   ladder matches without media queries here. */
.rp-callout {
  position: relative;
  padding-left: 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.rp-callout::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 8px;
  background: var(--lp-orange); /* #F06731, same hex the reference hardcodes */
  border-radius: 999px;
}
.rp-callout-head {
  margin: 0;
  font-size: var(--alpha-heading-h4);
  font-weight: var(--font-weight-medium);
  line-height: 130%;
  color: var(--lp-orange);
}
.rp-callout-text {
  margin: 0;
  font-size: var(--alpha-body-medium);
  font-weight: var(--font-weight-regular);
  line-height: 130%;
  color: #141414; /* reference hardcodes this, not our --lp-black (#0A0A0A) */
}

/* --- timeline ---
   The reference's "Domain timeline vs Stated founding" chart isn't a numeric
   chart at all — every value in it is a literal date/label/source, not a
   pixel-derived quantity — so it's plain HTML/CSS rather than an echarts
   instance. It sits inside the ordinary .rp-chart card (white, radius 24, with
   a .rp-chart-title) like every other exhibit, so this block styles ONLY the
   list: a dot-and-halo marker per row, a date, the event text, and a coloured
   source pill, with a spine connecting the markers.

   Row geometry comes from the reference's 96px marker pitch: the row content is
   26px tall (the pill, the tallest child) and --rp-tl-gap supplies the other
   70px. That is what makes the card as airy as the reference rather than the
   tight stack a padding-per-row approach produced.

   The spine is drawn per-row (::after on every row but the last) rather than as
   one bar on the list. Two reasons: it is anchored to the SAME origin as the
   marker it must line up with — the row's left edge — so the two cannot drift
   apart, which is exactly the bug a list-level bar had; and its length follows
   --rp-tl-gap automatically instead of needing hand-computed end insets. */
.rp-timeline {
  margin: 0;
  /* Indents the markers past the card title, as the reference does (title at
     the card's padding edge, markers 26px inside it). */
  padding: 0 0 0 calc(var(--spacing-padding-inline) * 8);
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--rp-tl-gap);
}
.rp-timeline-row {
  position: relative;
  display: flex;
  /* Centred, so the 20px halo, the 21px text line and the 26px pill share a
     midline — matching the reference, where all three centre within ~2px of
     each other. Row height therefore equals its tallest child (26px), which is
     what makes `top: 50%` below land exactly on the marker's centre. */
  align-items: center;
  gap: calc(var(--spacing-padding-inline) * 6);
  opacity: 1;
  transition: opacity 0.4s ease;
}
/* From this row's marker centre to the next row's marker centre: 50% of this
   row + the gap + 50% of the next = calc(100% + gap), since every row is the
   same height. */
.rp-timeline-row:not(:last-child)::after {
  content: '';
  position: absolute;
  /* Half the halo (10px) minus half the spine (1.5px) — this is the centring
     the old list-level rule got wrong by 3.5px. */
  left: 8.5px;
  top: 50%;
  width: 3px;
  height: calc(100% + var(--rp-tl-gap));
  border-radius: 2px;
  background: #FCE1D6;
  /* Growing down from the marker, not up: this segment connects THIS row's dot
     to the NEXT one, so it should draw from this row's own centre downward. */
  transform-origin: top;
  transform: scaleY(1);
  transition: transform 0.4s ease;
}
/* Rows render fully visible by default — required so a JS-off visit still
   shows the whole timeline, same reasoning as .rp-insights-toggle staying
   hidden until report.js confirms it can act. report.js opts a timeline INTO
   the hidden starting state only once it has an IntersectionObserver wired up
   to bring rows back one at a time; see report.js's timeline reveal. */
.rp-timeline--interactive .rp-timeline-row { opacity: 0; }
.rp-timeline--interactive .rp-timeline-row.is-shown { opacity: 1; }
.rp-timeline--interactive .rp-timeline-row:not(:last-child)::after { transform: scaleY(0); }
.rp-timeline--interactive .rp-timeline-row.is-shown:not(:last-child)::after { transform: scaleY(1); }
@media (prefers-reduced-motion: reduce) {
  .rp-timeline--interactive .rp-timeline-row,
  .rp-timeline--interactive .rp-timeline-row:not(:last-child)::after {
    opacity: 1; transform: none; transition: none;
  }
}
.rp-timeline-marker {
  position: relative;
  z-index: 1; /* over the spine, so the pale bar doesn't cross the dot */
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Halo colour follows the dot: orange for every source but the one Wayback
     Machine row, which is lime — see .rp-timeline-marker--alt. The CMS preview
     injects --rp-tl-halo / --rp-tl-dot inline for arbitrary colours; the live
     page sets neither, so these fall back to the reference orange unchanged. */
  background: var(--rp-tl-halo, rgba(240, 103, 49, 0.18));
}
.rp-timeline-marker::before {
  content: '';
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--rp-tl-dot, var(--lp-orange));
}
.rp-timeline-marker--alt { background: rgba(184, 253, 21, 0.18); }
.rp-timeline-marker--alt::before { background: #B8FD15; }

/* 16px in the reference, not the 20px --alpha-body-small this used to take —
   --alpha-body-xs is the 16px step. The fixed date column is what lines the
   event text up into a column across all five rows. */
.rp-timeline-date {
  flex: none;
  width: var(--rp-tl-date-w);
  font-size: var(--alpha-body-xs);
  line-height: 1.3;
  color: var(--lp-black);
}
.rp-timeline-event {
  flex: 1 1 auto; /* the grow is also what pushes the pill to the right edge */
  min-width: 0;
  font-size: var(--alpha-body-xs);
  line-height: 1.3;
  color: var(--lp-black);
}
.rp-timeline-source {
  flex: none;
  padding: calc(var(--spacing-padding-inline) * 1.25) calc(var(--spacing-padding-inline) * 3);
  border-radius: 100px;
  /* Inherits --rp-tl-dot from the row so the pill matches the marker dot's
     per-item colour; falls back to orange when the item has no colour. */
  background: var(--rp-tl-dot, var(--lp-orange));
  color: #fff;
  font-size: 12px;
  font-weight: var(--font-weight-regular);
  line-height: 1.3;
  white-space: nowrap;
}
/* The one lime source pill needs black rather than white text to stay
   readable against the lighter fill — same reasoning as the timeline marker. */
.rp-timeline-source--alt { background: #B8FD15; color: var(--lp-black); }

/* Narrow: the four columns stop fitting, so the pill drops to its own line.
   Once rows wrap they are no longer all one height, which breaks `top: 50%` —
   so the row switches to top alignment and the spine is anchored at the
   marker's centre (10px) instead. calc(100% + gap) still spans centre to
   centre, because that offset is now identical on both rows. */
@media (max-width: 767px) {
  .rp-timeline { padding-left: 0; }
  .rp-timeline-row {
    align-items: flex-start;
    flex-wrap: wrap;
    gap: calc(var(--spacing-padding-inline) * 3);
  }
  .rp-timeline-row:not(:last-child)::after { top: 10px; }
  .rp-timeline-date { width: auto; }
  /* Zero flex-basis: without this the event's hypothetical size is its own
     max-content width, so the ROW breaks before the event ever gets a chance
     to shrink — pushing .rp-timeline-source (flex:none, nowrap) onto its own
     line instead. A zero basis keeps the row on one flex line and makes the
     event's own text wrap to a second line in its place, leaving the source
     pill on line 1 where it belongs. */
  .rp-timeline-event { flex: 1 1 0%; }
  .rp-timeline-source {
    margin-left: calc(20px + var(--spacing-padding-inline) * 3);
  }
}

/* 600px and below: the row becomes a stack — date beside the marker, then the
   event on its own line, then the source pill on a third, both indented to sit
   under the date. At this width the one-line arrangement above has the event
   squeezed to a couple of words per line while the pill still holds its full
   nowrap width, so giving each part its own line reads better than compressing
   all three.

   One declaration does it, because the 767px block above already supplies
   everything else this tier needs: the row is top-aligned, the spine is anchored
   at the marker's centre, the date's fixed width is released, and the pill
   carries the 32px indent. Forcing the event to a full-width line pushes the
   pill onto a third line, where that existing margin lines it up for free.

   flex-basis 100% plus padding-left is safe here: `* { box-sizing: border-box }`
   in site.css keeps the indent inside the 100% instead of overflowing it. The
   32px matches the pill's own indent — marker (20px) + the row gap (12px) — so
   the event, the pill and the date above them share one left edge. */
@media (max-width: 600px) {
  .rp-timeline-event {
    flex: 0 0 100%;
    padding-left: calc(20px + var(--spacing-padding-inline) * 3);
  }
}

/* --- insights (collapsible) --- */
.rp-insights {
  background: var(--lp-panel);
  border-radius: 24px;
  padding: 40px 50px 50px 40px;
}
/* The reference absolutely positions the toggle over the title and vertically
   centres it by eye. A flex row gets the same result without the two having to
   agree on a magic offset, and the toggle stays centred if the title wraps.
   min-height is the reference's 85px title box — generous on purpose, and
   consistent across all five text nodes in this card. */
.rp-insights-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--spacing-padding-inline) * 6);
  min-height: 55px;
  /* Title-to-first-divider spacing, explicitly requested at 32px. */
  margin-bottom: 32px;
}
@media (max-width: 767px) {
  .rp-insights-header { margin-bottom: 28px; }
}
.rp-insights-title {
  margin: 0;
  font-size: var(--rp-font-lead);
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--lp-black);
}

.rp-insights-toggle {
  flex: none;
  width: 33px;
  height: 33px;
  padding: 0;
  border: 0;
  border-radius: 100px;
  background: var(--lp-black);
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: box-shadow 0.18s ease;
}
.rp-insights-toggle:hover { box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12); }
/* Only shown once report.js has taken over — a button that cannot do anything is
   worse than no button. */
.rp-insights:not(.rp-insights--interactive) .rp-insights-toggle { display: none; }
/* The glyph is drawn from the state rather than swapped in JS, so markup and
   appearance cannot drift apart: minus when open, plus when closed. */
.rp-insights-glyph::before {
  content: '+';
  font-size: 20px;
  font-weight: var(--font-weight-bold);
  line-height: 1;
}
.rp-insights.is-open .rp-insights-glyph::before { content: '\2212'; }

/* Gap between one insight's text and the NEXT insight's divider — explicitly
   requested at 40px. */
.rp-insights-body {
  display: flex;
  flex-direction: column;
  gap: 40px;
}
/* Gap between the insight-head and its own text — explicitly requested at 8px. */
.rp-insight {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
/* padding-top (not centred min-height any more): the divider-to-heading gap is
   now an explicit, requested 8px rather than derived from box centring. */
.rp-insight-head {
  margin: 0;
  padding-top: 8px;
  border-top: 1px solid var(--rp-rule);
  font-size: var(--alpha-body-medium);
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--lp-black);
}
.rp-insight-text {
  margin: 0;
  font-size: var(--alpha-body-small);
  font-weight: var(--font-weight-regular);
  line-height: 1.3;
  color: var(--lp-black);
}
.rp-insight-text + .rp-insight-text { margin-top: 15px; }

/* Collapsed: the bodies go, the headings and rules stay — which is what makes the
   collapsed card read as a summary. Only the paragraphs are hidden, so .rp-insight
   keeps its own gap collapsed to nothing via :empty-like behaviour below.
   Scoped away from --accordion (the per-item shape below), where the card has no
   .is-open of its own and this would hide every body permanently. This pair still
   serves company/show.php's original hardcoded card. */
.rp-insights--interactive:not(.rp-insights--accordion):not(.is-open) .rp-insight-text { display: none; }
.rp-insights--interactive:not(.rp-insights--accordion):not(.is-open) .rp-insight { gap: 0; }

/* --- per-item accordion (.rp-insights--accordion, from report.php) -----------------
   One toggle per insight, one open at a time. The heading row IS the button: full width,
   no chrome of its own, inheriting the h4's type so it reads as a heading rather than a
   control. outline:none per the brand rules — the glyph and the open body are the state. */
.rp-insight-toggle {
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  cursor: pointer;
  outline: none;
}
/* The open row's title goes orange, matching the glyph, so which insight is open stays
   legible from the headings alone once the body scrolls past. Faded over the same 0.28s as
   the panel so colour and opening move together rather than the title snapping ahead.
   Deliberately NOT in the reduced-motion block below - a colour fade carries no motion.
   Scoped to --accordion so show.php's card-level version is untouched. */
.rp-insight-head-text { flex: 1; min-width: 0; transition: color 0.28s ease; }
.rp-insights--accordion .rp-insight.is-open .rp-insight-head-text { color: var(--lp-orange); }
/* Same +/− drawn-from-state convention as .rp-insights-glyph, so markup and appearance
   cannot drift: minus when this insight is open, plus when it is closed. */
.rp-insight-glyph { flex: none; }
.rp-insight-glyph::before {
  content: '+';
  font-size: 22px;
  color: var(--lp-orange);
  font-weight: var(--font-weight-medium);
  line-height: 1;
}
.rp-insight.is-open .rp-insight-glyph::before { content: '\2212'; }
/* Only a control once report-cms.js has taken over — before that every panel is open, so
   a +/− would advertise a state change that cannot happen. */
.rp-insights--accordion:not(.rp-insights--interactive) .rp-insight-toggle { cursor: default; }
.rp-insights--accordion:not(.rp-insights--interactive) .rp-insight-glyph { display: none; }

/* Smooth open/close. grid-template-rows 0fr -> 1fr is the trick that makes this animate to
   the content's OWN height with no measured pixel value and no JS: 1fr resolves to exactly
   what the inner box needs. `display: none` — the obvious way to collapse — is not
   animatable, which is why the panel is a grid rather than simply hidden.

   The inner box carries overflow:hidden (so the text is clipped while the row shrinks) and
   visibility, which is the accessibility half: a panel left at zero height with visible
   content is still in the accessibility tree and its links are still tabbable, so a screen
   reader would read a section the eye cannot see. visibility:hidden removes it from both,
   and its transition is delayed by the full duration so it only disappears once the row has
   finished closing — and returns instantly on the way open. */
.rp-insights--accordion.rp-insights--interactive .rp-insight-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.28s ease;
}
.rp-insights--accordion.rp-insights--interactive .rp-insight.is-open .rp-insight-panel {
  grid-template-rows: 1fr;
}
.rp-insights--accordion.rp-insights--interactive .rp-insight-panel-inner {
  overflow: hidden;
  min-height: 0; /* without this a grid item refuses to shrink below its content */
  visibility: hidden;
  transition: visibility 0s linear 0.28s;
}
.rp-insights--accordion.rp-insights--interactive .rp-insight.is-open .rp-insight-panel-inner {
  visibility: visible;
  transition-delay: 0s;
}
/* gap is animatable, so the 8px heading-to-body space closes with the row instead of
   snapping shut a beat early. */
.rp-insights--accordion.rp-insights--interactive .rp-insight { transition: gap 0.28s ease; }
.rp-insights--accordion.rp-insights--interactive .rp-insight:not(.is-open) { gap: 0; }

@media (prefers-reduced-motion: reduce) {
  .rp-insights--accordion.rp-insights--interactive .rp-insight-panel,
  .rp-insights--accordion.rp-insights--interactive .rp-insight-panel-inner,
  .rp-insights--accordion.rp-insights--interactive .rp-insight { transition: none; }
}

/* --- verification table ---
   The reference's "Trust, but verify" data is literal source-attribution, not
   a chart — same reasoning as .rp-timeline. Reuses .rp-chart's card shell,
   .rp-chart-title, and .rp-chart-legend (the identical lime/orange dot
   convention already used for the chapter 5 scatter and chapter 6 survival
   chart) rather than duplicating them; only the table markup itself is new.
   A real <table> rather than a flex-row rebuild of the reference's layout,
   since this data genuinely has rows and columns — a screen reader gets
   header associations for free that a div grid would have to fake. */
/* Scrollbar geometry stays reserved at all times (5px, not none) — only its
   colour animates on interaction. Toggling display/width instead would reflow
   the table on every hover on platforms with classic space-taking scrollbars.
   Deliberately NOT setting scrollbar-width/scrollbar-color here: Chromium gives
   those standard properties precedence over ::-webkit-scrollbar-* on the same
   element, which silently disabled the thumb-colour rules below at every
   state, hover included — the earlier attempt at this looked like the
   scrollbar had been removed entirely. */
.rp-verify-scroll { overflow-x: auto; }
.rp-verify-scroll::-webkit-scrollbar { height: 5px; }
.rp-verify-scroll::-webkit-scrollbar-track { background: transparent; }
.rp-verify-scroll::-webkit-scrollbar-thumb {
  background: transparent;
  border-radius: 100px;
  transition: background-color 0.2s ease;
}
/* :focus-within covers keyboard scrolling (Tab into the table, arrow keys);
   :active covers a drag that leaves the box before release. #BFBFBF matches
   the table's own row-border colour below rather than introducing a new one. */
.rp-verify-scroll:hover::-webkit-scrollbar-thumb,
.rp-verify-scroll:focus-within::-webkit-scrollbar-thumb,
.rp-verify-scroll:active::-webkit-scrollbar-thumb { background: #BFBFBF; }
/* Touch scrolling never fires :hover or :active, so a finger-drag on mobile
   would otherwise never reveal the thumb at all — report.js toggles this
   class for the duration of an actual scroll. */
.rp-verify-scroll.is-scrolling::-webkit-scrollbar-thumb { background: #BFBFBF; }
.rp-verify-table {
  width: 100%;
  min-width: 640px;
  border-collapse: collapse;
  /* Fixed layout: without it, the browser sizes columns by content and the
     long, barely-breakable "Not independently confirmed" verification text
     squeezes Nature enough to wrap "Self-reported" — the nth-child widths
     below only take effect once column sizing stops following content. */
  table-layout: fixed;
}
.rp-verify-table th {
  text-align: left;
  padding: 0 calc(var(--spacing-padding-inline) * 4) calc(var(--spacing-padding-inline) * 3);
  font-size: var(--rp-font-table);
  font-weight: var(--font-weight-medium);
  letter-spacing: 0.06em;
  color: var(--lp-black);
  white-space: nowrap;
}
.rp-verify-table thead tr th{
   text-transform: uppercase;
}

.rp-verify-table td {
  padding: calc(var(--spacing-padding-inline) * 3) calc(var(--spacing-padding-inline) * 4);
  border-top: 1px solid #BFBFBF;
  font-size: var(--rp-font-table);
  line-height: 1.35;
  color: var(--lp-black);
  vertical-align: middle;
}
/* The th cells carry no border, so the line under the header IS the first data
   row's border-top — drawn orange to separate the header from the body. */
.rp-verify-table tbody tr:first-child td { border-top-color: var(--lp-orange); }
/* Column proportions from the reference's 260/170/138/190 split (claim's 260
   folds in the 28px dot column the reference draws separately — here the dot
   sits inside the claim cell instead, so the two are combined). */
.rp-verify-table th:nth-child(1), .rp-verify-table td:nth-child(1) { width: 34%; }
.rp-verify-table th:nth-child(2), .rp-verify-table td:nth-child(2) { width: 20%; }
.rp-verify-table th:nth-child(3), .rp-verify-table td:nth-child(3) { width: 20%; }
.rp-verify-table th:nth-child(4), .rp-verify-table td:nth-child(4) { width: 26%; }
.rp-verify-claim {
  display: flex;
  align-items: center;
  gap: calc(var(--spacing-padding-inline) * 3);
}
.rp-verify-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--lp-orange);
}
.rp-verify-dot--verified { background: #B8FD15; }
/* How the claim was established. Replaces the old verified/not-verified pair on
   this table: that axis now lives entirely in the Verification column's badge,
   leaving the dot free to carry nature instead. */
.rp-verify-dot--self     { background: var(--rp-evidence-self); }
.rp-verify-dot--measured { background: var(--rp-evidence-measured); }
.rp-verify-dot--third    { background: var(--rp-evidence-third); }
.rp-verify-badge { font-size: 12px; }
.rp-verify-badge--high { color: var(--lp-orange); }

/* Verification outcome, as a traffic light: stands / partial / does not stand.
   Darker than the dot key's mid-tones on purpose — these are 12px TEXT on white,
   where #22C55E lands around 2:1 contrast, while the dots are shapes and carry no
   reading burden. The hues still read green / amber / red against each other. */
.rp-verify-badge--stands  { color: #15803D; }
.rp-verify-badge--partial { color: #B45309; }
.rp-verify-badge--fails   { color: #B91C1C; }

/* Chapter 7's summary table: same shell, 3 columns instead of 4 and no dot
   column, so the widths are restated rather than inherited.
   The split is lopsided because the columns are: a short label, a single figure,
   and the comparison behind it. That last one carries whole clauses ("Marketing
   tag, 2006–21 (n=109): 32% acquired / 25% inactive / 43% active") while the
   middle one never exceeds "9 staff, 92 visits" — an even split would wrap the
   third column to three lines while the second sat half empty. */
.rp-verify-table--summary th:nth-child(1),
.rp-verify-table--summary td:nth-child(1) { width: 20%; }
.rp-verify-table--summary th:nth-child(2),
.rp-verify-table--summary td:nth-child(2) { width: 17%; }
.rp-verify-table--summary th:nth-child(3),
.rp-verify-table--summary td:nth-child(3) { width: 63%; }

/* A dark orange, distinct from --lp-orange: the reference uses #C05227 for this
   column specifically (against the card title's brighter #F06731), so it is a
   one-off literal rather than a token. NOT struck through — confirmed against
   the CSS export, which carries no text-decoration here.
   Needs the `td` prefix: `.rp-verify-table td` above sets colour and, being
   class-plus-element, out-specifies a bare `.rp-verify-stronger` class. */
.rp-verify-table td.rp-verify-stronger { color: var(--lp-black); }


/* Chapter 8's evidence table: two columns, because Nature is now the dot's
   COLOUR rather than a column of text (see .rp-verify-dot--* above), and Source
   is folded into the claim text itself.
   Its claim cells run to several lines each, unlike the one-line rows the base
   table's `vertical-align: middle` and 12px block padding were written for — so
   this variant top-aligns both the cell and the dot, and opens the rows up. A
   badge centred against a five-line claim reads as attaching to the middle of
   it rather than to the row. */
.rp-verify-table--evidence th:nth-child(1),
.rp-verify-table--evidence td:nth-child(1) { width: 70%; }
.rp-verify-table--evidence th:nth-child(2),
.rp-verify-table--evidence td:nth-child(2) { width: 30%; }
.rp-verify-table--evidence td {
  vertical-align: top;
  padding-block: calc(var(--spacing-padding-inline) * 4);
}
.rp-verify-table--evidence .rp-verify-claim { align-items: flex-start; }
/* Centres the dot on the first LINE rather than on the cell: half the difference
   between that line's box (--rp-font-table x the 1.35 line-height set on td) and
   the dot's own 9px. */
.rp-verify-table--evidence .rp-verify-dot {
  margin-top: calc((var(--rp-font-table) * 1.35 - 9px) / 2);
}

/* Even split, for a two-column --evidence table whose SECOND column is prose too.
   --evidence's own 70/30 above assumes a claim beside a short badge; the
   limitations table has a sentence on both sides, so neither earns the extra
   room. Rides alongside --evidence rather than replacing it, since everything
   else that variant does (top-aligned cells, opened-up rows) still applies.
   Must stay AFTER the 70/30 rules: same specificity, so source order is what
   makes this win. */
.rp-verify-table--evidence-2 th:nth-child(1),
.rp-verify-table--evidence-2 td:nth-child(1),
.rp-verify-table--evidence-2 th:nth-child(2),
.rp-verify-table--evidence-2 td:nth-child(2) { width: 50%; }

/* --- reveal-on-scroll text ---
   Chapter 8's closing statement starts grey and turns black word by word as the
   reader scrolls through it. report.js splits the paragraph into one span per
   word and adds .is-lit to each as the reading line passes it; the transition
   is what keeps that from looking like a hard flicker.

   The grey is --rp-toc-idle, the token already used for unreached TOC labels —
   the same "not there yet" state, so it reads consistently. */
.rp-reveal-word {
  color: var(--rp-toc-idle);
  transition: color 0.25s ease;
}
.rp-reveal-word.is-lit { color: var(--lp-black); }
/* Reduced-motion: the colour change IS the content cue here, so it is kept —
   only the easing is dropped, so words switch instantly instead of fading. */
@media (prefers-reduced-motion: reduce) {
  .rp-reveal-word { transition: none; }
}
@media (prefers-reduced-motion: reduce) {
  .rp-progress-fill { transition: none; }
  .rp-progress { transition: none; }
}

/* The report's final paragraph: the reference gives it the same 40px of air
   above as the closing statement, but no top rule. */
.rp-closing { padding-top: 0px; }

/* ==========================================================================
   REFERENCES
   An appendix to the whole report, spanning the full wrap rather than the
   chapter column. Every size here maps onto an existing token (24/20/16px are
   --alpha-body-medium / -small / -xs), so this block declares none of its own.
   ========================================================================== */
/* No top padding: .rp-chapters' own 200px bottom padding is the gap above this
   section, exactly as .rp-stats leans on .rp-overview's. Keeping the
   reference's 200px top here as well would stack the two into 400px. */
.rp-refs { padding: 0 var(--section-pad-inline) var(--rp-section-gap); }
.rp-refs > .lp-wrap {
  padding-inline: 0;
  display: flex;
  flex-direction: column;
  gap: calc(var(--spacing-padding-inline) * 10);
}

/* Black hairline above the heading; the note at the bottom gets a lighter one
   (--lp-border) — the reference deliberately weights the two differently, so
   the appendix opens on a firm rule and closes on a soft one. */
.rp-refs-head {
  border-top: 1px solid var(--lp-black);
  padding-top: calc(var(--spacing-padding-inline) * 5);
}
.rp-refs-head h2 {
  margin: 0;
  font-size: var(--alpha-body-medium);
  font-weight: var(--font-weight-medium);
  line-height: 1.45;
  color: var(--lp-black);
}

/* Two independent columns, each an <ol> that stacks its own entries and grows
   as tall as it needs — no fixed row cap. The second column is optional; when
   absent, .rp-refs-cols--single collapses to one column. Numbering is applied
   server-side (column 2 continues from column 1), so each list just stacks. */
.rp-refs-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: calc(var(--spacing-padding-inline) * 10);
  align-items: start;
}
.rp-refs-cols--single {
  grid-template-columns: minmax(0, 1fr);
}
.rp-refs-list {
  margin: 0;
  padding: 0;
  list-style: none; /* the bracketed orange marker is drawn as a span instead */
  display: flex;
  flex-direction: column;
  row-gap: calc(var(--spacing-padding-inline) * 8);
}
.rp-ref {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--spacing-padding-inline) * 3);
}
.rp-ref-marker {
  flex: none;
  font-size: var(--alpha-body-small);
  font-weight: var(--font-weight-medium);
  /* 1.5 against the text's 1.3, per the reference — the marker sits in a
     slightly taller line box than the first line of its entry. */
  line-height: 1.5;
  color: var(--lp-orange);
}
.rp-ref-text {
  margin: 0;
  font-size: var(--alpha-body-small);
  font-weight: var(--font-weight-regular);
  line-height: 1.3;
  color: var(--lp-black);
}
/* Links inside a reference (linkable_text in app/helpers.php): orange, no underline.
   The colour alone marks them, matching the bracketed [n] marker's accent. */
.rp-ref-text a,
.rp-refs-note a {
  color: var(--lp-orange);
  text-decoration: none;
}

.rp-refs-note {
  border-top: 1px solid var(--lp-border);
  padding-top: calc(var(--spacing-padding-inline) * 6);
}
.rp-refs-note p {
  margin: 0;
  font-size: var(--alpha-body-xs);
  font-weight: var(--font-weight-regular);
  line-height: 1.55;
  color: var(--lp-black);
}

/* One column below 767px: two columns of ~330px is too narrow for 20px text to
   set well, and the row pairing that justifies the grid stops helping once each
   entry is only a few words wide. */
@media (max-width: 767px) {
  .rp-refs-cols {
    grid-template-columns: 1fr;
    row-gap: calc(var(--spacing-padding-inline) * 8);
  }
}

/* --- author box (section 9) ---
   Design carried from av_codebase post.php's .av-single-author-box: a white
   40px-radius card on the page's grey ground, 64px round avatar, orange
   designation line, black pill button that hovers orange, stacking to a column
   under 768px. Values that were hardcoded there (#fff card, #F06831 accents,
   the 24/16/20px type steps) map onto this file's tokens — --lp-panel,
   --lp-orange, and the --alpha-body-* ladder, which already steps those same
   sizes down per breakpoint, so no extra responsive rules are needed for type. */
.rp-author-section { padding: 0 var(--section-pad-inline) var(--rp-section-gap); }
.rp-author-section > .lp-wrap { padding-inline: 0; }
.rp-author {
  background: var(--lp-panel);
  border-radius: 40px;
  padding: 32px;
  display: flex;
  gap: 20px;
  align-items: flex-start;
}
.rp-author-avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
/* No avatar URL: the author's initial in a 10%-orange disc (the reference's
   rgba(240,104,49,.1) treatment, on our own orange). */
.rp-author-initial {
  background: rgba(240, 103, 49, 0.1);
  color: var(--lp-orange);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: var(--font-weight-bold);
}
.rp-author-body { min-width: 0; }
.rp-author-name {
  font-size: var(--alpha-body-medium);
  font-weight: var(--font-weight-bold);
  line-height: 1.3;
  color: var(--lp-black);
}
.rp-author-role {
  font-size: var(--alpha-body-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--lp-orange);
}
.rp-author-bio {
  margin: 14px 0 0;
  font-size: var(--alpha-body-small);
  line-height: 1.5;
  color: var(--lp-black);
  max-width: 850px;
}
/* Two class levels on purpose — `.landing a { color: inherit }` (one class plus an
   element) would otherwise out-specify a lone .rp-author-btn and force the label
   back to black-on-black. Same trap .cp-filter-header documents in landing.css. */
.rp-author .rp-author-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  padding: 14px 28px;
  background: var(--lp-black);
  color: #fff;
  font-size: 16px;
  line-height: 150%;
  border-radius: 100px;
  text-decoration: none;
  transition: background-color 0.3s ease;
}
.rp-author .rp-author-btn:hover { background: var(--lp-orange); }
/* The reference stacks the card at its phone breakpoint (767px), same one the
   refs columns collapse at above. */
@media (max-width: 767px) {
  .rp-author { flex-direction: column; }
}

/* --- chapters: narrow layouts --- */
/* Below 1024 the TOC is dropped rather than restyled. At 260px it is already a
   third of the usable width, and its whole purpose — a progress rail read
   alongside the prose — stops working once it has to sit above the content. The
   chapter headings carry the structure instead. */
.rp-mtoc, .rp-progress { display: none; }

@media (max-width: 1024px) {
  .rp-toc { display: none; }
  .rp-chapters-layout { gap: 0; }

  /* Whole-page progress. Lives INSIDE .rp-mtoc (last child), pinned to the
     box's bottom edge, so it rides along with the sticky bar instead of
     floating at the top of the header. Hidden by default: report.js only adds
     .is-visible for the range .rp-mtoc is actually stuck to the top for (see
     the "Sticky chapter TOC" IIFE). opacity+visibility, not display, so the
     transition can animate and .rp-progress-fill's own width isn't reset by
     display:none while hidden. z-index 1 keeps the line painted over the
     opened panel's top seam (both are positioned children of .rp-mtoc). */
  .rp-progress {
    display: block;
    position: absolute; left: 0; right: 0; bottom: 0;
    height: 3px; z-index: 1;
    background: var(--lp-border);
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s ease, visibility 0.25s ease;
  }
  .rp-progress.is-visible {
    opacity: 1;
    visibility: visible;
  }
  .rp-progress-fill {
    width: 0; height: 100%;
    background: var(--lp-orange);
    transition: width 0.18s linear; /* same easing as .rp-toc-fill */
  }

  /* Collapsible chapter bar, replacing the sidebar exactly where it hides.
     z-index 70: above the FAB (60), below the nav's mobile overlay (90). */
  .rp-mtoc {
    display: block;
    position: sticky;
    top: var(--lp-nav-h-scrolled);
    z-index: 70;
    /* Full-bleed: cancels .rp-chapters' own --section-pad-inline gutter,
       since .rp-chapters > .lp-wrap has already zeroed its own padding. */
    margin-inline: calc(var(--section-pad-inline) * -1);
    margin-bottom: calc(var(--spacing-padding-inline) * 8);
    background: var(--lp-panel);
    border-bottom: 1px solid var(--rp-rule);
  }
  .rp-mtoc-bar {
    width: 100%; border: 0; background: none; cursor: pointer;
    display: flex; align-items: center;
    gap: calc(var(--spacing-padding-inline) * 3);
    padding: calc(var(--spacing-padding-inline) * 4) var(--section-pad-inline);
    font-size: var(--alpha-body-medium);
    font-weight: var(--font-weight-medium);
    color: var(--lp-black);
  }
  /* Plain 3-bar hamburger — no dots, unlike a bulleted-list glyph. */
  .rp-mtoc-icon {
    flex: none; width: 20px; height: 20px;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Crect x='32' y='56' width='192' height='16' rx='8'/%3E%3Crect x='32' y='120' width='192' height='16' rx='8'/%3E%3Crect x='32' y='184' width='192' height='16' rx='8'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Crect x='32' y='56' width='192' height='16' rx='8'/%3E%3Crect x='32' y='120' width='192' height='16' rx='8'/%3E%3Crect x='32' y='184' width='192' height='16' rx='8'/%3E%3C/svg%3E") center / contain no-repeat;
  }
  .rp-mtoc-label {
    flex: 1 1 auto; text-align: left;
    /* Explicit: the bar is a <button>, and buttons don't inherit the page font. */
    font-family: "Satoshi", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  }
  /* +/x drawn from state, same convention as .rp-insights-glyph above.
     display:none for now (was flex) — the sizing/centering rules are kept so
     restoring it is a one-word change. */
  .rp-mtoc-glyph {
    flex: none; width: 34px; height: 34px; border-radius: 50%;
    border: 1px solid var(--rp-rule);
    display: none; align-items: center; justify-content: center;
  }
  .rp-mtoc-glyph::before { content: '+'; font-size: 20px; line-height: 1; }
  .rp-mtoc-bar[aria-expanded="true"] .rp-mtoc-glyph::before { content: '\00D7'; }

  /* Absolute, not in flow — the panel overlays the chapters instead of
     shoving them down as it opens. */
  .rp-mtoc-panel {
    display: none;
    position: absolute; left: 0; right: 0; top: 100%;
    max-height: calc(100vh - var(--lp-nav-h-scrolled) - 60px);
    overflow-y: auto;
    background: var(--lp-panel);
    border-bottom: 1px solid var(--rp-rule);
    padding: 0 var(--section-pad-inline) calc(var(--spacing-padding-inline) * 5);
  }
  .rp-mtoc-panel.is-open { display: block; }
  .rp-mtoc-list { margin: 0; padding: 0; list-style: none; }
  .rp-mtoc-item {
    font-size: var(--alpha-body-small);
    color: var(--rp-toc-idle);
    transition: color 0.2s ease;
  }
  .rp-mtoc-item.is-active { color: var(--lp-orange); }
  .rp-mtoc-item a {
    color: inherit; display: flex;
    gap: calc(var(--spacing-padding-inline) * 4);
    padding: calc(var(--spacing-padding-inline) * 3) 0;
  }
  .rp-mtoc-num { flex: none; color: var(--lp-muted); }
  .rp-mtoc-item.is-active .rp-mtoc-num { color: var(--lp-orange); }

  /* The bar now covers part of the anchor target too, so a chapter jump must
     clear both the header and the bar, or the heading lands underneath it. */
  .rp-chapter { scroll-margin-top: calc(var(--lp-nav-h-scrolled) + 56px + calc(var(--spacing-padding-inline) * 8)); }
}
@media (max-width: 767px) {
  .rp-chapter { gap: calc(var(--spacing-padding-inline) * 10); }
  .rp-insights {
    border-radius: 28px;
    padding: calc(var(--spacing-padding-inline) * 6);
  }
  .rp-chart { border-radius: 20px; }
}
