/* Article furniture for the authority layer, added 2026-08-30.
   Kept out of content.css so the prose system stays readable on its own.
   One locked light theme, same as everything else: no dark mode block here.

   The rail reuses the margin technique already applied to .jump-rail: that
   rule set does not live in content.css (it has no jump-rail rule at all),
   it lives in landing.css, lines 756-879. Its numbers are used here rather
   than invented ones: the reserved column is 220px wide, the gap between
   the column and the prose measure is 56px, the breakpoint is 1080px, and
   the sticky offset is 104px, chosen there to clear the 80px fixed topbar. */

.ref { font-size: 0.72em; line-height: 0; }
.ref a {
  display: inline-grid; place-items: center;
  width: 15px; height: 15px; border-radius: 999px;
  background: var(--flash); color: #fff;
  font-weight: 800; font-size: 10px; text-decoration: none;
  vertical-align: super;
}
.ref a:hover, .ref a:focus-visible { background: var(--flash-deep); }

.receipts { border-left: 2px solid var(--flash-soft); padding-left: var(--s4); }
.receipts-title {
  font-size: 11px; font-weight: 800; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); margin-bottom: var(--s3);
}
.receipt-list { list-style: decimal; padding-left: var(--s4); margin: 0; }
.receipt-list li { margin-bottom: var(--s3); font-size: 14px; line-height: 1.45; }
.receipt-list b { display: block; font-weight: 800; }
.receipt-list span { display: block; color: var(--muted); }
.receipt-list a { display: inline-block; margin-top: 2px; color: var(--flash-deep); }

/* The rail is a sibling of the sections, not a child of one, so above the jump
   rail's breakpoint it can leave the flow and cover the whole article zone the way
   .jump-rail already does on the left. Width (220px) and gap (56px) match the
   column .jump-rail carves out of the left margin; the sticky top (104px) matches
   the jump nav's own offset, clearing the fixed topbar the same way.

   The float this replaced could not work. A float is bounded by nothing, so the
   rail hung out of whichever section hosted it and painted down beside the FAQ,
   and a height cap only shortened the overhang: the cap scales with the viewport
   while the article's tail does not, so it got worse on a taller monitor. Here the
   containing block is .rail-scope, the hero plus every section, so sticky can carry
   the rail no further than the bottom of the article. The overhang is not tuned
   out, it is unrepresentable. */
@media (min-width: 1080px) {
  .rail-scope { position: relative; }
  /* Still in the flow at this width, as a block at the end of the article. Match
     the prose column's own axis so it does not sit in a different place. */
  .receipt-rail > .wrap.narrow {
    max-width: 1280px;
    padding-left: calc(clamp(20px, 5vw, 48px) + 220px + 56px);
  }
}

/* Below 1280 there is not 220px of clear band to the right of the measure, so the
   rail stays in the flow rather than sitting on top of the prose. The reduced-motion
   half is the same decision: a reader who has asked for less movement gets the rail
   in the flow, at full height, with nothing capped and nothing behind a scrollbar. */
@media (min-width: 1280px) and (prefers-reduced-motion: no-preference) {
  /* a click-through layer: without pointer-events:none it would cover the article
     and eat every link, exactly as the note on .jump-rail says */
  .receipt-rail {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
  .receipt-rail > .wrap.narrow {
    height: 100%;
    padding-left: clamp(20px, 5vw, 48px);   /* drop the in-flow rule's left tax */
    /* The eyebrow offset is padding here, not a margin on the rail itself. As a
       margin it collapsed straight through this wrapper, moving the sticky
       containing block down 135px and pushing its bottom edge 135px PAST the end
       of the article, which is exactly the overhang the hoist exists to remove.
       Measured before this line: containing block 244..7035 against a .rail-scope
       of 109..6900. With box-sizing: border-box the padding comes out of the 100%
       rather than adding to it, so the box still ends where the article does. */
    padding-top: clamp(96px, 15vh, 150px);  /* start level with the eyebrow, like .jump */
  }
  /* Reserve the rail's column on the right, the way landing.css already reserves
     the jump nav's on the left. As a float the rail sat in the flow and the prose
     wrapped around it; as a layer nothing wraps, so without this the rail paints
     straight over anything that runs the full column. The hero illustration was the
     first casualty, with two of the four dials behind the citations. Running text is
     already capped at 40rem and barely notices; this is for the art, the tables and
     the evidence bars, which are meant to run the whole column. */
  main:has(.receipt-rail) .rail-scope section > .wrap.narrow,
  main:has(.receipt-rail) .rail-scope section.tool > .wrap {
    padding-right: calc(clamp(20px, 5vw, 48px) + 220px + 56px);
  }

  .receipts {
    position: sticky;
    top: 104px;
    width: 220px;
    margin-left: auto;                      /* park it on the wrap's right edge */
    pointer-events: auto;
    border-left-width: 2px;
    /* One viewport at most, then scroll inside. The hoist removes the overhang;
       this keeps a very long rail usable rather than running off the screen. */
    max-height: calc(100vh - 104px - var(--s5));
    overflow-y: auto;
  }
}

/* The four domain colours leave the score bars here, by owner ruling on
   2026-08-30. The argument that carried: an evidence bar is data, not
   decoration, which is the distinction PRODUCT.md's rule is actually drawing.
   ev-none is deliberately --muted: no evidence is not a fifth domain. */
.evidence { margin: var(--s5) 0; }
.evidence-row + .evidence-row { margin-top: var(--s3); }
.ev-label {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--muted); margin-bottom: var(--s1);
}
.ev-label b { color: var(--ink); font-weight: 800; }
.ev-track {
  height: 8px; border-radius: var(--radius-pill);
  background: var(--paper-2); overflow: hidden;
}
.ev-fill { height: 100%; border-radius: var(--radius-pill); }
/* Measured against the track (--paper-2, #fbe8e4), the 3:1 AA bar a bar
   graphic is held to: psych 5.45:1, phys 3.84:1, sexual 4.84:1, none 4.88:1
   all clear it as-is. --vaso (#ef5d3d) measured 2.82:1 and failed, so this
   is a bar-only darkening of that data-series token, not a change to
   --vaso itself in tokens.css. #d6522e measures 3.48:1 against the track
   and 4.11:1 against white. */
.ev-vaso   { background: #d6522e; }
.ev-psych  { background: var(--psych); }
.ev-phys   { background: var(--phys); }
.ev-sexual { background: var(--sexual); }
.ev-none   { background: var(--muted); }

.pullquote {
  border-top: 2px solid var(--ink);
  padding-top: var(--s4); margin: var(--s6) 0;
}
.pullquote p {
  font-family: var(--serif); font-style: italic; font-weight: 500;
  font-size: clamp(21px, 3.4vw, 27px); line-height: 1.3;
  max-width: 26ch; margin: 0 0 var(--s2);
}
.pullquote cite {
  font-style: normal; font-size: 13px; font-weight: 700;
  color: var(--muted); letter-spacing: 0.02em;
}

.crumbs { font-size: 13px; color: var(--muted); padding-top: var(--s4); }
.crumbs a { color: var(--flash-deep); text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }
.crumb-sep { padding: 0 var(--s2); opacity: 0.5; }

.hub-rows { list-style: none; margin: var(--s5) 0 0; padding: 0; }
.hub-row {
  display: grid; grid-template-columns: 32px 1fr 190px;
  gap: var(--s4); align-items: start;
  padding: var(--s4) 0; border-top: 1px solid var(--line);
}
.hub-row:first-child { border-top: none; }
.hub-rank { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.hub-name { font-size: 18px; font-weight: 800; letter-spacing: -0.01em; margin-bottom: 2px; }
.hub-name a { color: inherit; }
.hub-verdict { color: var(--muted); margin-bottom: var(--s2); }
.hub-tags { display: flex; gap: var(--s1); flex-wrap: wrap; list-style: none; padding: 0; }
.hub-tags li {
  font-size: 11px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 3px 9px; border-radius: var(--radius-pill); background: var(--paper-2);
}
.hub-src { font-size: 12px; color: var(--muted); margin-top: var(--s1); line-height: 1.35; }

/* The section that an advertising-funded competitor cannot publish. Dimmed, not
   hidden: it has to be legible or it is not doing its job. */
.hub-rows.no-evidence .hub-name { font-weight: 700; color: var(--muted); }
.hub-rows.no-evidence .hub-verdict { color: var(--muted); }

@media (max-width: 820px) {
  .hub-row { grid-template-columns: 28px 1fr; }
  .hub-ev { grid-column: 2; }
}

/* ---------- fix round, 2026-08-30 ----------

/* 2. The visible breadcrumb rendered underneath the fixed topbar on all 17
   generated pages, overlapping the topnav links.

   <main> carries no top offset: .page-hero's own clamp(96px, 15vh, 150px) top
   padding is what clears the 80px fixed .topbar. crumbs() puts this nav above the
   hero, so it inherited none of that clearance and painted into the 0 to 80px band.
   The clearance moves onto the crumbs, and the hero below drops to the gap it
   actually needs under a breadcrumb rather than under a topbar.

   The jump nav's margin-top has to move with it. landing.css starts it at the same
   clamp precisely so it sits level with the eyebrow, and leaving it alone would
   strand it ~110px below the headline it is supposed to align with. */
.crumbs { padding-top: calc(80px + var(--s2)); }
main:has(.crumbs) .page-hero { padding-top: clamp(20px, 3vh, 32px); }
@media (min-width: 1080px) {
  main:has(.crumbs) .jump { margin-top: clamp(20px, 3vh, 32px); }
}
/* Same --topbar-h-mobile as content.css's mobile .page-hero (defined once, in
   tokens.css): below 880px .topbar can run to three rows, and this is the
   crumbs' own clearance for it, not the hero's, since a page with a
   breadcrumb hands its own clearance off to the crumbs and gives the hero
   underneath only the small gap above.

   This rule used to hardcode 205px, ten pixels short of the bar's real
   214.8px height across 641-879px: the crumbs' link painted 0.8px under the
   bar the whole way through that band, the exact bug this fix round already
   fixed once above, just re-opened by the nav restructure that made the bar
   taller. Consuming the shared property instead of a fourth hardcoded copy
   is what keeps that from happening a third time. */
@media (max-width: 879px) {
  .crumbs { padding-top: calc(var(--topbar-h-mobile) + var(--s2)); }
}

/* Setting overflow-y above makes overflow-x compute to auto rather than visible, so
   a DOI, which has no space to break at, clipped inside the 220px column instead of
   spilling out of it. Breaking mid-token is right for this content either way: the
   rail is citations, and a citation is the one place a reader expects an identifier
   to wrap wherever it must. */
.receipt-list li { overflow-wrap: anywhere; }

/* ---------- the money layer ---------- */

/* The disclosure runs above the table it describes, not down in the footer fine
   print. A reader who never scrolls past the first row still has to have been
   told which rows pay us. */
.disclosure {
  border: 1.5px solid var(--flash); background: var(--flash-soft);
  border-radius: var(--radius-lg); padding: var(--s4) var(--s5); margin: var(--s5) 0;
  max-width: 44em;
}
.note-title { font-weight: 800; margin-bottom: var(--s2); }
.disclosure p, .safety-note p { margin-bottom: var(--s2); }
.disclosure p:last-child, .safety-note p:last-child { margin-bottom: 0; }

.paid {
  display: inline-grid; place-items: center; width: 16px; height: 16px;
  border-radius: var(--radius-pill); background: var(--flash); color: #fff;
  font-size: 10px; font-weight: 800;
}
.unpaid {
  display: block; font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  color: var(--muted); margin-top: 2px;
}
/* The unpaid rows are tinted so the eye finds them first. Deliberate: they are the
   two options most women should take, and they earn nothing. */
.compare tr.free th, .compare tr.free td {
  background: color-mix(in oklab, var(--ok) 7%, var(--card));
}
/* Six columns do not fit a phone, and squeezing them turns every cell into a
   one-word-per-line column. The floor forces the overflow into .table-scroll,
   where it scrolls sideways on its own instead of dragging the page with it.

   36rem, not more: at 1440 the prose measure is 632px, because the layout reserves
   a 220px gutter on each side for the jump rail and the receipt rail, and the
   narrowest the six columns will pack is 613px. A wider floor would make this the
   only table on the site that scrolls sideways on a desktop monitor, and it is the
   page a reader is most likely to be comparing rows across. */
.compare { min-width: 36rem; }
.compare th, .compare td { padding: 12px 10px; }
.compare th[scope="row"] { min-width: 7rem; }
/* The opinion column carries a sentence or two rather than a value, so it takes the
   slack the four short factual columns do not need. Squeezed to the same width as
   them it laid the verdict out four words to a line and made every row 300px tall. */
.compare th:last-child, .compare td:last-child { min-width: 13rem; }
/* The uppercase header, not the content, was setting the floor on the four short
   factual columns. */
.compare thead th { font-size: 0.74rem; letter-spacing: 0.02em; }

/* The same block, deliberately not the same box. On this page a coral border means
   money, and the one note that must never read as commercial is the red-flag one,
   so it takes an ink rule and no fill. */
.safety-note {
  border-left: 3px solid var(--ink); padding-left: var(--s4);
  margin: var(--s6) 0; max-width: 44em;
}
