/* ============================================================
   GISTIL — THE BLOG
   Loaded ON TOP OF main.css, which supplies the palette, the
   three faces, the nav and the footer. Nothing below re-declares
   any of that.

   DIRECTION. The landing measures one video against a gold axis.
   The legal pages are that instrument at rest — a document with a
   spine and a numbered tick per section. The blog is the third
   state: the instrument's FIELD NOTES. So its one structural
   device is the RUNTIME RULE — a video's duration drawn as a
   measured bar, shaded where the padding is and ticked in gold at
   the second the useful part begins. It appears at three sizes
   (inside a ranked row, inside a verdict card, and as the page's
   own summary) and it is built from exactly the three numbers we
   publish. Nothing else is invented: no new palette, no new
   geometry, no ornament that does not carry a number.

   Prose is set in the serif at a real reading size, data is set
   in the mono, and the two never trade places — on this site
   mono means "this is measured".

   Everything is scoped under .blog-body so this file can never
   reach the landing or the legal pages, and so it can out-specify
   main.css's bare element selectors without a single !important.
   ============================================================ */

/* ------------------------------------------------------------
   1. UNDO THE LANDING'S STAGE GRID
   main.css styles the bare <main> ELEMENT as the landing's axis
   grid. These pages share that stylesheet, so their <main> would
   inherit it and auto-place every direct child as a grid cell.
   Same one-line fix the legal pages use.
   ------------------------------------------------------------ */
.blog-body main{display:block;column-gap:normal}

.blog-body{
  --measure:660px;        /* reading column — ~74 characters at 19px serif */
  --wide:1080px;          /* lists and shelves, which are scanned not read */
  --rail:64px;            /* hanging numerals and the hairline live here */
  --stack:52px;           /* vertical rhythm between blocks */
  background:var(--bg);
  color:var(--bone-dim);
}

.blog-body .wrap{
  max-width:calc(var(--measure) + var(--rail) + var(--gutter)*2);
  margin:0 auto;
  padding-left:calc(var(--gutter) + var(--rail));
  padding-right:var(--gutter);
}
/* Collections and the shelf hub are scanned, so they get the wide track. The
   blog hub is a list of headlines and standfirsts — it is read, and on the wide
   track it stranded the whole column against the left edge. */
.blog-body .coll .wrap,
.blog-body .hub--wide .wrap{
  max-width:calc(var(--wide) + var(--rail) + var(--gutter)*2);
}

/* ------------------------------------------------------------
   2. MASTHEAD
   One faint radial behind the title — the only atmosphere on the
   page, and it is the same gold the numbers are set in.
   ------------------------------------------------------------ */
.blog-body .post__head,
.blog-body .coll__head,
.blog-body .hub__head{
  position:relative;isolation:isolate;
  padding:calc(64px + 56px) 0 40px;   /* 64px clears the fixed nav */
  border-bottom:1px solid var(--edge);
  overflow:hidden;
}
.blog-body .post__head::before,
.blog-body .coll__head::before,
.blog-body .hub__head::before{
  content:'';position:absolute;inset:auto auto 0 0;width:min(760px,90%);height:340px;
  background:radial-gradient(120% 90% at 12% 100%,color-mix(in srgb,var(--gold) 11%,transparent),transparent 70%);
  z-index:-1;pointer-events:none;
}

.blog-body .crumbs ol{list-style:none;margin:0 0 22px;padding:0;display:flex;flex-wrap:wrap;gap:8px;
  font:500 11.5px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--mute2)}
.blog-body .crumbs li+li::before{content:'/';margin-right:8px;color:var(--edge2)}
.blog-body .crumbs a{color:var(--mute)}
.blog-body .crumbs a:hover{color:var(--gold-bright)}
.blog-body .crumbs [aria-current]{color:var(--bone-dim);
  /* An article title can be a sentence; the crumb showing it is a wayfinding
     label, so it is clipped rather than allowed to wrap to three lines. */
  display:inline-block;max-width:46ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  vertical-align:bottom}

/* NAME COLLISION, handled explicitly. main.css already owns `.kicker` (the
   landing's italic serif standfirst) and sets `max-width:30ch` on it. Scoping
   under .blog-body wins the properties this rule DECLARES, but a property it
   never mentions keeps leaking through — which is what was folding this label
   onto two lines. Anything the landing sets and we do not want is reset here by
   name. Same trap applies to `.faq`, whose margin and max-width we do declare. */
.blog-body .kicker{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:0 0 18px;
  max-width:none;
  font:500 11.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--mute);
  /* Each part stays on one line — a two-word label broken across two lines
     reads as a layout fault, not as an eyebrow. */
  white-space:nowrap}
.blog-body .kicker b{color:var(--gold);font-weight:500;white-space:nowrap}
.blog-body .kicker i{display:block;width:22px;height:1px;background:var(--edge2)}

.blog-body h1{
  font:800 clamp(32px,4.6vw,52px)/1.06 var(--display);
  letter-spacing:-.028em;color:var(--bone);margin:0;max-width:17ch;
}
.blog-body .coll h1,
.blog-body .hub h1{max-width:20ch}
.blog-body .post__dek,
.blog-body .hub__dek{
  margin:20px 0 0;max-width:56ch;
  font:400 19.5px/1.6 var(--serif);color:var(--bone-dim);
}

/* ------------------------------------------------------------
   3. THE MEASUREMENT STAMP
   On every editorial page, and doing three jobs: it says what the
   piece rests on, it dates the numbers, and it is the line a
   scraped copy cannot keep true — ours moves with the library,
   the copy freezes.
   ------------------------------------------------------------ */
.blog-body .stamp{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:28px 0 0;
  font:500 12px/1.5 var(--mono);letter-spacing:.02em;color:var(--mute2);
}
.blog-body .stamp b{color:var(--gold);font-weight:500}
.blog-body .stamp__k{color:var(--mute2)}
.blog-body .stamp i{display:block;width:1px;height:11px;background:var(--edge2);margin:0 4px}

/* ------------------------------------------------------------
   4. THE RUNTIME RULE — the signature
   A duration drawn to scale. The shaded block is the padding
   share, the gold tick is the second the useful part starts.
   Three numbers, no more, and the same shape everywhere it
   appears. Never the labelled value curve — that is the product.
   ------------------------------------------------------------ */
.blog-body .rule{display:flex;align-items:center;gap:10px;margin:15px 0 0;
  /* Bounded on purpose. Stretched across a full text column the bar stopped
     reading as a measurement of one video and started reading as a divider. */
  max-width:360px}
.blog-body .rule__z{font:500 11px/1 var(--mono);color:var(--mute2);letter-spacing:.02em;
  white-space:nowrap;min-width:4ch}
.blog-body .rule__z--end{text-align:right}
.blog-body .rule__track{
  position:relative;flex:1;height:11px;border-radius:2px;
  background:var(--panel2);border:1px solid var(--edge2);overflow:hidden;
}
.blog-body .rule__water{
  position:absolute;inset:0 auto 0 0;display:block;border-radius:1px;
  /* Padding reads as texture, not as a second data colour: a 45° hatch in the
     same near-neutral as the track, so it stays legible with colour vision
     deficiency and in forced-colours mode. */
  background:repeating-linear-gradient(135deg,
    color-mix(in srgb,var(--mute2) 52%,transparent) 0 2px,
    transparent 2px 6px);
}
.blog-body .rule__tick{
  position:absolute;top:-2px;bottom:-2px;width:2px;display:block;
  background:var(--gold-bright);box-shadow:0 0 0 1px color-mix(in srgb,var(--bg) 80%,transparent);
}
.blog-body .rule__label{font:500 11.5px/1 var(--mono);color:var(--mute2);white-space:nowrap}

/* ------------------------------------------------------------
   5. STAT TILES
   Four values with no trend and no series is a reading task, not
   a plotting one — so it is a row of numbers, not a chart.
   ------------------------------------------------------------ */
.blog-body .tiles{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));
  gap:1px;margin:34px 0 0;padding:0;background:var(--edge);
  border:1px solid var(--edge);border-radius:3px;overflow:hidden;
}
.blog-body .tiles .tile{background:var(--panel);padding:18px 20px;margin:0}
.blog-body .tiles dt{font:500 11px/1.3 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--mute2)}
.blog-body .tiles dd{margin:8px 0 0;font:500 27px/1 var(--mono);color:var(--gold);letter-spacing:-.02em}
.blog-body .tiles dd i{font-style:normal;font-size:15px;color:var(--mute2);margin-left:2px}

/* ------------------------------------------------------------
   6. PROSE
   The serif is the argument and it gets a real reading size.
   Data inside prose is pulled out to the rail as a hanging mono
   figure — the note in the margin of a field notebook.
   ------------------------------------------------------------ */
/* padding-top/bottom ONLY. These elements also carry .wrap, which sets the
   left/right padding that aligns the column with its own masthead — and a
   `padding:` shorthand here (equal specificity, declared later) silently reset
   both sides to 0, sliding every article 128px left of its own headline. */
.blog-body .post__body,
.blog-body .coll__body,
.blog-body .hub__body{padding-top:var(--stack);padding-bottom:96px}

.blog-body .prose{font:400 19px/1.72 var(--serif);color:var(--bone-dim);max-width:var(--measure)}
.blog-body .prose > *+*{margin-top:1.15em}
.blog-body .prose h2{
  position:relative;margin:2.4em 0 .7em;
  font:800 27px/1.2 var(--display);letter-spacing:-.02em;color:var(--bone);
}
.blog-body .prose h2::before{
  content:'';position:absolute;left:calc(var(--rail)*-1);top:.62em;
  width:38px;height:1px;background:var(--gold);
}
.blog-body .prose h3{margin:2em 0 .5em;font:700 20px/1.35 var(--display);color:var(--bone);letter-spacing:-.01em}
.blog-body .prose a{color:var(--bone);text-decoration:underline;text-decoration-color:var(--gold-deep);
  text-underline-offset:3px;text-decoration-thickness:1px}
.blog-body .prose a:hover{text-decoration-color:var(--gold-bright)}
.blog-body .prose strong{color:var(--bone);font-weight:600}
.blog-body .prose ul,
.blog-body .prose ol{padding-left:1.15em;margin-top:1.1em}
.blog-body .prose li+li{margin-top:.5em}
.blog-body .prose li::marker{color:var(--gold-deep)}
.blog-body .prose blockquote{
  margin:1.6em 0;padding:2px 0 2px 22px;border-left:1px solid var(--gold-deep);
  font-style:italic;color:var(--bone);
}
.blog-body .prose code{font:500 .87em/1 var(--mono);color:var(--gold-bright);
  background:var(--panel2);border:1px solid var(--edge);border-radius:3px;padding:2px 5px}
.blog-body .prose hr{border:0;border-top:1px solid var(--edge);margin:2.4em 0}
/* A figure pulled into the rail: the number lives in the margin, the sentence
   stays in the column. */
.blog-body .prose .fig{
  margin:1.9em 0;padding:18px 20px;background:var(--panel);
  border:1px solid var(--edge);border-left:2px solid var(--gold);border-radius:3px;
  font:400 16.5px/1.6 var(--serif);color:var(--bone-dim);
}
/* kramdown writes ** ** as <strong>, not <b>. Naming only `b` here meant the
   one device the whole figure exists for — the number, large, on its own line —
   silently rendered as a bold word inside the sentence. */
.blog-body .prose .fig b,
.blog-body .prose .fig strong{display:block;font:500 30px/1 var(--mono);color:var(--gold);
  font-weight:500;letter-spacing:-.02em;margin-bottom:8px}

/* ------------------------------------------------------------
   7. CONTENTS
   ------------------------------------------------------------ */
.blog-body .toc{margin:0 0 var(--stack);padding:0 0 0 20px;border-left:1px solid var(--edge);max-width:var(--measure)}
.blog-body .toc h2{font:500 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--mute2);margin:0 0 14px}
.blog-body .toc ol{list-style:none;margin:0;padding:0}
.blog-body .toc li+li{margin-top:9px}
.blog-body .toc a{display:flex;gap:14px;align-items:baseline;font:400 16px/1.4 var(--serif);color:var(--bone-dim)}
.blog-body .toc a b{font:500 11px/1 var(--mono);color:var(--gold-deep);font-weight:500;min-width:2ch}
.blog-body .toc a:hover{color:var(--bone)}
.blog-body .toc a:hover b{color:var(--gold)}

/* ------------------------------------------------------------
   8. VERDICT CARD — the public cut of a measurement
   ------------------------------------------------------------ */
.blog-body .cards{margin:calc(var(--stack)*1.2) 0 0;max-width:var(--wide)}
.blog-body .cards__h{font:500 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--mute2);margin:0 0 20px}
.blog-body .cards__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));gap:16px}

.blog-body .vcard{margin:0;padding:20px 22px 18px;background:var(--panel);border:1px solid var(--edge);border-radius:3px}
.blog-body .vcard__head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.blog-body .vcard__meta{font:500 11.5px/1 var(--mono);color:var(--mute2);letter-spacing:.02em}
.blog-body .vcard__title{margin:0;font:700 18px/1.35 var(--display);color:var(--bone);letter-spacing:-.01em}
.blog-body .vcard__title a{color:var(--bone)}
.blog-body .vcard__title a:hover{color:var(--gold-bright)}
.blog-body .vcard__nums{display:flex;flex-wrap:wrap;gap:22px;margin:16px 0 0}
.blog-body .vcard__nums dt{font:500 10.5px/1.2 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--mute2)}
.blog-body .vcard__nums dd{margin:5px 0 0;font:500 21px/1 var(--mono);color:var(--gold)}
.blog-body .vcard__nums dd i{font-style:normal;font-size:12px;color:var(--mute2)}
.blog-body .vcard__why{margin:14px 0 0;font:400 15.5px/1.58 var(--serif);color:var(--bone-dim)}
.blog-body .vcard__foot{display:flex;flex-direction:column;gap:8px;margin:16px 0 0;padding-top:14px;border-top:1px solid var(--edge)}
.blog-body .vcard__foot a{font:500 12.5px/1 var(--mono);color:var(--gold-bright)}
.blog-body .vcard__disc{font:400 11px/1.45 var(--mono);color:var(--mute2)}

/* Verdict chip. A status colour NEVER carries meaning alone — the word is
   always there, and the chip keeps its border in forced-colours mode. */
.blog-body .vd{display:inline-block;padding:5px 10px;border-radius:2px;border:1px solid var(--edge2);
  font:500 10.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--mute)}
.blog-body .vd--watch{color:var(--worth);border-color:color-mix(in srgb,var(--worth) 45%,transparent);
  background:color-mix(in srgb,var(--worth) 9%,transparent)}
.blog-body .vd--skim{color:var(--gold-bright);border-color:color-mix(in srgb,var(--gold) 45%,transparent);
  background:color-mix(in srgb,var(--gold) 9%,transparent)}
.blog-body .vd--skip{color:var(--skip);border-color:color-mix(in srgb,var(--skip) 45%,transparent);
  background:color-mix(in srgb,var(--skip) 9%,transparent)}

/* ------------------------------------------------------------
   9. THE RANKED SHELF
   Hanging mono numerals in the rail. The number is information
   here — this list IS an order — which is the only reason it is
   numbered at all.
   ------------------------------------------------------------ */
.blog-body .coll__intro{margin-bottom:calc(var(--stack)*1.1)}
.blog-body .ranked{list-style:none;margin:0;padding:0;counter-reset:rank}
.blog-body .rank{position:relative;display:grid;grid-template-columns:var(--rail) 1fr;
  padding:26px 0;border-top:1px solid var(--edge)}
.blog-body .rank:first-child{border-top:1px solid var(--edge2)}
.blog-body .rank__n{font:500 13px/1 var(--mono);color:var(--gold-deep);padding-top:6px;letter-spacing:.04em}
.blog-body .rank__body{min-width:0}
.blog-body .rank__title{margin:0;font:700 21px/1.3 var(--display);letter-spacing:-.015em;color:var(--bone)}
.blog-body .rank__title a{color:var(--bone)}
.blog-body .rank__title a:hover{color:var(--gold-bright)}
.blog-body .rank__meta{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:11px 0 0;
  font:500 11.5px/1 var(--mono);color:var(--mute2);letter-spacing:.02em}
.blog-body .rank__lvl{text-transform:uppercase;letter-spacing:.1em;color:var(--mute2)}
.blog-body .rank__nums{display:flex;flex-wrap:wrap;gap:20px;margin:14px 0 0}
.blog-body .rank__nums dt{font:500 10.5px/1.2 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--mute2)}
.blog-body .rank__nums dd{margin:5px 0 0;font:500 17px/1 var(--mono);color:var(--gold)}
.blog-body .rank__why{margin:14px 0 0;font:400 16.5px/1.6 var(--serif);color:var(--bone-dim);max-width:62ch}
.blog-body .rank__go{margin:14px 0 0}
.blog-body .rank__go a{font:500 12.5px/1 var(--mono);color:var(--gold-bright)}
.blog-body .rank__break{list-style:none;padding:26px 0;border-top:1px solid var(--edge)}

.blog-body .disc{margin:26px 0 0;font:400 11.5px/1.6 var(--mono);color:var(--mute2);max-width:70ch}

/* ------------------------------------------------------------
   10. SHELVES (the /best hub)
   One bar per shelf on one shared 0–100 scale, single hue,
   direct-labelled by the number above it. A shelf's bar is
   comparable to its neighbour's and to nothing else.
   ------------------------------------------------------------ */
/* Real gaps and a border per card, NOT a painted grid background: with 9 or 13
   shelves the last row is short, and a container that paints its own gaps fills
   the empty tracks with a slab that reads as a broken cell. */
.blog-body .shelves{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(268px,1fr));gap:12px}
.blog-body .shelf{background:var(--panel);margin:0;border:1px solid var(--edge);border-radius:3px;overflow:hidden}
.blog-body .shelf a{display:block;padding:22px 24px 24px;height:100%}
.blog-body .shelf a:hover{background:var(--panel2)}
.blog-body .shelf h2{font:700 19px/1.25 var(--display);color:var(--bone);letter-spacing:-.015em;margin:0}
.blog-body .shelf a:hover h2{color:var(--gold-bright)}
.blog-body .shelf__nums{display:flex;flex-wrap:wrap;gap:18px;margin:16px 0 0}
.blog-body .shelf__nums dt{font:500 10px/1.2 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--mute2)}
.blog-body .shelf__nums dd{margin:5px 0 0;font:500 16px/1 var(--mono);color:var(--gold)}
.blog-body .shelf__bar{margin:18px 0 0;height:4px;border-radius:2px;background:var(--panel2);
  border:1px solid var(--edge);overflow:hidden}
.blog-body .shelf__bar i{display:block;height:100%;border-radius:2px;background:var(--gold)}

/* ------------------------------------------------------------
   11. POST CARDS
   ------------------------------------------------------------ */
.blog-body .posts{list-style:none;margin:0;padding:0}
.blog-body .pcard{border-top:1px solid var(--edge)}
.blog-body .pcard:first-child{border-top:1px solid var(--edge2)}
.blog-body .pcard a{display:block;padding:26px 0}
.blog-body .pcard__k{display:flex;flex-wrap:wrap;align-items:center;gap:9px;margin:0 0 12px;
  font:500 11px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--mute2)}
.blog-body .pcard__k b{color:var(--gold);font-weight:500}
.blog-body .pcard__k i{display:block;width:1px;height:10px;background:var(--edge2)}
.blog-body .pcard h2{font:800 25px/1.22 var(--display);letter-spacing:-.02em;color:var(--bone);max-width:30ch;margin:0}
.blog-body .pcard a:hover h2{color:var(--gold-bright)}
.blog-body .pcard__d{margin:11px 0 0;font:400 17px/1.6 var(--serif);color:var(--mute);max-width:62ch}
.blog-body .pcard--lead h2{font-size:clamp(27px,3.2vw,34px);max-width:24ch}
.blog-body .pcard--lead .pcard__d{font-size:18.5px;color:var(--bone-dim)}

.blog-body .pager{display:flex;gap:6px;margin:38px 0 0}
.blog-body .pager a,
.blog-body .pager span{display:grid;place-items:center;min-width:38px;height:38px;
  border:1px solid var(--edge);border-radius:3px;font:500 13px/1 var(--mono);color:var(--mute)}
.blog-body .pager a:hover{border-color:var(--gold-deep);color:var(--gold-bright)}
.blog-body .pager [aria-current]{border-color:var(--gold-deep);color:var(--gold);background:var(--panel)}

/* ------------------------------------------------------------
   12. CALL TO ACTION
   Bone is this site's action colour. One button, no second
   competing ask, and nothing about the subscription — a person
   who met the product ninety seconds ago is not being sold to.
   ------------------------------------------------------------ */
.blog-body .cta{margin:calc(var(--stack)*1.3) 0 0;max-width:var(--wide)}
.blog-body .cta--inline{margin:0}
.blog-body .cta__in{padding:30px 32px;background:var(--panel);border:1px solid var(--edge);
  border-top:2px solid var(--gold-deep);border-radius:3px}
.blog-body .cta__eyebrow{margin:0 0 12px;font:500 11px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--gold)}
.blog-body .cta__h{font:800 24px/1.25 var(--display);letter-spacing:-.02em;color:var(--bone);margin:0;max-width:26ch}
.blog-body .cta__p{margin:12px 0 0;font:400 17px/1.6 var(--serif);color:var(--bone-dim);max-width:58ch}
.blog-body .cta__row{display:flex;flex-wrap:wrap;align-items:center;gap:16px;margin:22px 0 0}
.blog-body .cta__btn{display:inline-block;padding:13px 22px;border-radius:3px;
  background:var(--bone);border:1px solid var(--bone);color:#0A0803;
  font:600 13px/1 var(--mono);letter-spacing:.03em}
.blog-body .cta__btn:hover{background:var(--gold-bright);border-color:var(--gold-bright);color:#0A0803}
.blog-body .cta__note{font:500 12px/1 var(--mono);color:var(--mute2)}

/* ------------------------------------------------------------
   13. TAIL BLOCKS
   ------------------------------------------------------------ */
.blog-body .method{margin:calc(var(--stack)*1.2) 0 0;padding:24px 26px;background:var(--panel);
  border:1px solid var(--edge);border-radius:3px;max-width:var(--wide)}
.blog-body .method h2{font:500 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--mute2);margin:0 0 12px}
.blog-body .method p{font:400 16.5px/1.65 var(--serif);color:var(--bone-dim);max-width:70ch}
.blog-body .method a{color:var(--gold-bright);font-weight:600}

.blog-body .faq{margin:calc(var(--stack)*1.2) 0 0;max-width:var(--measure)}
.blog-body .faq > h2{font:500 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--mute2);margin:0 0 20px}
.blog-body .faq__q{padding:18px 0;border-top:1px solid var(--edge)}
.blog-body .faq__q h3{margin:0 0 8px;font:700 17px/1.35 var(--display);color:var(--bone)}
.blog-body .faq__q p{margin:0;font:400 16.5px/1.62 var(--serif);color:var(--bone-dim);max-width:64ch}

.blog-body .onward{margin:calc(var(--stack)*1.2) 0 0;max-width:var(--wide)}
.blog-body .onward h2{font:500 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--mute2);margin:0 0 16px}
.blog-body .onward ul{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px}
.blog-body .onward li{background:var(--panel);border:1px solid var(--edge);border-radius:3px;overflow:hidden}
.blog-body .onward a{display:block;padding:18px 20px;height:100%;font:700 17px/1.35 var(--display);color:var(--bone)}
.blog-body .onward a:hover{background:var(--panel2);color:var(--gold-bright)}
.blog-body .onward__k{display:block;margin-bottom:8px;font:500 10.5px/1 var(--mono);
  letter-spacing:.12em;text-transform:uppercase;color:var(--mute2)}

.blog-body .upto{margin:38px 0 0}
.blog-body .upto a{font:500 12.5px/1 var(--mono);color:var(--mute)}
.blog-body .upto a:hover{color:var(--gold-bright)}

.blog-body .empty{padding:40px 0;font:400 18px/1.6 var(--serif);color:var(--mute);max-width:54ch}

/* ------------------------------------------------------------
   14. NARROW SCREENS
   The rail collapses: hanging numerals move inline and the
   reading column takes the full width. Over half the traffic on
   the pain-point articles will be a phone.
   ------------------------------------------------------------ */
@media (max-width:900px){
  .blog-body{--rail:0px;--stack:40px}
  .blog-body .wrap{padding-left:var(--gutter);padding-right:var(--gutter)}
  .blog-body .prose h2::before{display:none}
  .blog-body .rank{grid-template-columns:1fr;gap:0}
  .blog-body .rank__n{padding:0 0 10px}
  .blog-body .prose{font-size:17.5px;line-height:1.68}
  .blog-body .post__dek,
.blog-body .hub__dek{font-size:17.5px}
  .blog-body .post__head,
.blog-body .coll__head,
.blog-body .hub__head{padding-top:calc(64px + 34px);padding-bottom:32px}
  .blog-body .cta__in,
.blog-body .method{padding:22px 20px}
  .blog-body .vcard{padding:18px}
  .blog-body .tiles dd{font-size:23px}
}

@media (max-width:560px){
  .blog-body .tiles{grid-template-columns:repeat(2,1fr)}
  .blog-body .cards__grid{grid-template-columns:1fr}
  .blog-body .vcard__nums,
.blog-body .rank__nums{gap:16px}
}

@media (prefers-reduced-motion:reduce){
  .blog-body *{transition:none!important;animation:none!important}
}

/* ------------------------------------------------------------
   15. BAR ROWS (data reports)
   A magnitude comparison across categories: horizontal bars,
   sorted, on ONE shared 0–100% scale, single hue. Every bar is
   direct-labelled with its value and its n, so the figure is
   readable without the geometry — and there is no second y-axis,
   no stacking, and no colour carrying a second variable.
   ------------------------------------------------------------ */
.blog-body .prose .bars{margin:1.9em 0;padding:20px 22px 16px;background:var(--panel);
  border:1px solid var(--edge);border-radius:3px}
.blog-body .bars__row{display:grid;grid-template-columns:minmax(96px,1.35fr) minmax(90px,3fr) 54px 44px;
  align-items:center;gap:12px;padding:6px 0}
.blog-body .bars__k{font:400 14.5px/1.35 var(--serif);color:var(--bone-dim)}
.blog-body .bars__t{position:relative;height:9px;border-radius:2px;background:var(--panel2);
  border:1px solid var(--edge);overflow:hidden}
.blog-body .bars__t i{display:block;height:100%;border-radius:2px;background:var(--gold-deep)}
.blog-body .bars__v{font:500 13px/1 var(--mono);color:var(--gold);text-align:right}
.blog-body .bars__n{font:500 11.5px/1 var(--mono);color:var(--mute2);text-align:right}
.blog-body .bars__cap{margin:14px 0 0;padding-top:12px;border-top:1px solid var(--edge);
  font:400 12.5px/1.55 var(--mono);color:var(--mute2)}
@media (max-width:640px){
  .blog-body .bars__row{grid-template-columns:1fr 48px 40px;gap:8px}
  .blog-body .bars__t{grid-column:1/-1;order:2;margin-top:2px}
  .blog-body .bars__k{order:1}
  .blog-body .bars__v{order:3}
  .blog-body .bars__n{order:4}
}

/* ------------------------------------------------------------
   16. FIGURES — charts, comparison tables, sources
   The drawing is inline SVG rendered on the server (see
   Blog::ChartRenderer), so there is no chart library, no JS and
   no raster to re-export when a figure is corrected.

   The one rule that shapes everything here: the SVG has NO
   viewBox. A viewBox would scale the type along with the bars
   and leave 7px labels on a phone. Instead the drawing is given
   a pixel height, every horizontal position is a percentage,
   and the sizes below are real CSS pixels that never scale —
   the same 13px label at 360px wide and at 1080px.

   Palette: the plan's validated set, not a library default.
   One gold for a single series; a single-hue gold ramp for
   ordered parts; the four-hue categorical set is the ceiling,
   because a fifth hue drops the worst colour-vision pair under
   the separation threshold.
   ------------------------------------------------------------ */
.blog-body .chart{
  margin:2em 0;padding:20px 22px 16px;background:var(--panel);
  border:1px solid var(--edge);border-radius:3px;
}
.blog-body .chart__head{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px;margin:0 0 4px}
.blog-body .chart__title{font:700 16px/1.3 var(--display);color:var(--bone);letter-spacing:-.01em}
.blog-body .chart__unit{font:500 11px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--mute2)}
/* Dots and the rounded end of a bar sit exactly on 0% and 100%; the padding
   gives them the half-mark of room a percentage cannot express. */
.blog-body .chart__plot{padding:14px 7px 2px}
.blog-body .chart__plot svg{display:block;overflow:visible}

.blog-body .chart .cv-lbl{font:400 13.5px/1 var(--serif);fill:var(--bone-dim)}
.blog-body .chart .cv-val{font:500 12.5px/1 var(--mono);fill:var(--gold)}
.blog-body .chart .cv-n{font-size:11px;fill:var(--mute2)}
.blog-body .chart .cv-axis-lbl{font:500 11px/1 var(--mono);fill:var(--mute2)}
.blog-body .chart .cv-in{font:500 11.5px/1 var(--mono)}
.blog-body .chart .cv-track{fill:var(--panel2);stroke:var(--edge);stroke-width:1}
.blog-body .chart .cv-axis{stroke:var(--edge);stroke-width:1}
.blog-body .chart .cv-grid{stroke:var(--edge);stroke-width:1;opacity:.62}
.blog-body .chart .cv-dot{stroke:var(--panel);stroke-width:2}
.blog-body .chart .cv-range{stroke-width:2;opacity:.4;stroke-linecap:round}
.blog-body .chart .cv-line{stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.blog-body .chart .cv-band{opacity:.13}
/* The separator between two fills is a gap in the SURFACE colour, never a
   stroke drawn round the mark: a stroke is ink that carries no data and it
   reads as a border on the smallest segment. */
.blog-body .chart .cv-gap{fill:var(--panel)}

/* Hover is the whole row, not the painted bar. The title inside each mark is
   the tooltip; the table under the drawing is the version that needs no
   pointer at all. */
.blog-body .chart .cv-hit{fill:transparent}
.blog-body .chart .cv-m .cv-fill,
.blog-body .chart .cv-m .cv-dot{transition:filter .12s ease}
.blog-body .chart .cv-m:hover .cv-fill,
.blog-body .chart .cv-m:hover .cv-dot{filter:brightness(1.22)}
.blog-body .chart .cv-m:hover .cv-lbl{fill:var(--bone)}

.blog-body .chart__key{list-style:none;display:flex;flex-wrap:wrap;gap:6px 20px;margin:14px 0 0;padding:0}
.blog-body .chart__key li{display:flex;align-items:center;gap:8px;margin:0;
  font:400 13.5px/1.3 var(--serif);color:var(--bone-dim)}
.blog-body .chart__key i{width:11px;height:11px;border-radius:2px;flex:none}
.blog-body .chart__key b{font:500 12.5px/1 var(--mono);color:var(--gold);font-weight:500}

.blog-body .chart__note{margin:14px 0 0;padding-top:12px;border-top:1px solid var(--edge);
  font:400 12.5px/1.55 var(--mono);color:var(--mute2)}
.blog-body .chart__src{margin:10px 0 0;font:500 11px/1.5 var(--mono);letter-spacing:.04em;color:var(--mute2)}

/* The table view. Not a courtesy — it is the accessible twin of every drawing
   and the version that survives if the SVG never paints. */
.blog-body .chart__t{margin:12px 0 0}
.blog-body .chart__t summary{display:inline-block;cursor:pointer;
  font:500 11px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--mute2);
  padding:6px 0}
.blog-body .chart__t summary:hover{color:var(--gold-bright)}
.blog-body .chart__t[open] summary{margin-bottom:6px}
.blog-body .chart__t table,
.blog-body .cmp table{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums}
.blog-body .chart__t th,
.blog-body .chart__t td,
.blog-body .cmp th,
.blog-body .cmp td{text-align:left;padding:8px 14px 8px 0;border-top:1px solid var(--edge);
  font:400 13.5px/1.4 var(--serif);color:var(--bone-dim)}
.blog-body .chart__t thead th,
.blog-body .cmp thead th{border-top:0;font:500 10.5px/1.3 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--mute2)}
.blog-body .chart__t td,
.blog-body .cmp td{font:500 13px/1.4 var(--mono);color:var(--gold)}
.blog-body .chart__t tbody th,
.blog-body .cmp tbody th{font-weight:400;color:var(--bone-dim)}

/* ------------------------------------------------------------
   17. COMPARISON TABLE
   Comparing named things across named properties is a reading
   task, not a plotting one — so it stays a table.
   ------------------------------------------------------------ */
.blog-body .cmp{margin:2em 0;padding:20px 22px 16px;background:var(--panel);
  border:1px solid var(--edge);border-radius:3px}
.blog-body .cmp__head{margin:0 0 4px}
.blog-body .cmp__head b{font:700 16px/1.3 var(--display);color:var(--bone);letter-spacing:-.01em}
/* A four-column comparison cannot reflow into 320px, so it scrolls sideways
   inside its own card rather than pushing the whole page wider.
   
   A clipped column with no affordance reads as a broken layout, so the edges
   carry the classic CSS-only scroll shadow: two panel-coloured layers pinned to
   the CONTENT (background-attachment:local) sit on top of two shadow layers
   pinned to the VIEWPORT, so a shadow is only visible on the side that still
   has table left to reach. No JavaScript, and nothing to show when the table
   fits. */
.blog-body .cmp__scroll{
  overflow-x:auto;margin-top:10px;scrollbar-width:thin;
  background:
    linear-gradient(90deg,var(--panel) 40%,color-mix(in srgb,var(--panel) 0%,transparent)) left / 36px 100% no-repeat local,
    linear-gradient(270deg,var(--panel) 40%,color-mix(in srgb,var(--panel) 0%,transparent)) right / 36px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,rgba(201,196,186,.26),transparent) left / 20px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%,rgba(201,196,186,.26),transparent) right / 20px 100% no-repeat scroll;
}
.blog-body .cmp__scroll:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.blog-body .cmp__scroll table{min-width:min(100%,460px)}
.blog-body .cmp td{color:var(--bone-dim)}
.blog-body .cmp__note{margin:14px 0 0;padding-top:12px;border-top:1px solid var(--edge);
  font:400 12.5px/1.55 var(--mono);color:var(--mute2)}

/* ------------------------------------------------------------
   18. CITATIONS AND SOURCES
   A number in the prose, the publisher at the foot. The
   superscript is a link, and it is the only place on this site
   where a digit is not set in the mono face — inside a serif
   sentence a mono superscript reads as a code span.
   ------------------------------------------------------------ */
.blog-body .prose .ref{font-size:.62em;line-height:0;vertical-align:super}
.blog-body .prose .ref a{color:var(--gold);text-decoration:none;padding:0 1px}
.blog-body .prose .ref a:hover{color:var(--gold-bright);text-decoration:underline}

.blog-body .sources{margin:calc(var(--stack)*1.1) 0 0;max-width:var(--measure)}
.blog-body .sources h2{font:500 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--mute2);margin:0 0 14px}
.blog-body .sources ol{margin:0;padding-left:1.4em}
.blog-body .sources li{font:400 15px/1.6 var(--serif);color:var(--bone-dim);padding:5px 0}
.blog-body .sources li::marker{color:var(--gold-deep);font:500 12px var(--mono)}
.blog-body .sources li:target{color:var(--bone)}
.blog-body .sources a{color:var(--bone);text-decoration:underline;
  text-decoration-color:var(--gold-deep);text-underline-offset:3px}
.blog-body .sources a:hover{text-decoration-color:var(--gold-bright)}
.blog-body .sources__m{color:var(--mute2);font:400 12.5px/1.5 var(--mono)}

/* ------------------------------------------------------------
   19. THE ILLUSTRATION
   One per piece, in the masthead, decorative and uncaptioned:
   on this site everything that carries a number is a figure
   inside the text, so the picture is not allowed to look like
   one. Width and height are on the tag so the masthead does not
   jump when it loads.
   ------------------------------------------------------------ */
.blog-body .post__hero{margin:34px 0 0;max-width:var(--wide)}
.blog-body .post__hero img{display:block;width:100%;height:auto;border-radius:3px;
  border:1px solid var(--edge);background:var(--panel)}
.blog-body .prose figure{margin:1.9em 0}
.blog-body .prose figure img,
.blog-body .prose > img{display:block;width:100%;height:auto;border-radius:3px;border:1px solid var(--edge)}
.blog-body .prose figure figcaption{margin:12px 0 0;font:400 12.5px/1.55 var(--mono);color:var(--mute2)}

/* The two halves of a column chart. Only one is ever in the layout; the
   narrow one is aria-hidden, so a screen reader meets the numbers once. */
.blog-body .chart__plot--narrow{display:none}
@media (max-width:620px){
  .blog-body .chart__plot--wide{display:none}
  .blog-body .chart__plot--narrow{display:block}
}

@media (max-width:640px){
  .blog-body .chart{padding:16px 14px 14px}
  .blog-body .cmp{padding:16px 14px 14px}
  .blog-body .chart .cv-lbl{font-size:13px}
  .blog-body .chart .cv-val{font-size:12px}
  .blog-body .chart__key{gap:4px 14px}
}

/* Below this width a long subject name and its value are the two things that
   have to survive on one line, so the sample size steps out of the drawing.
   It is still in the tooltip and still in the table view. */
@media (max-width:560px){
  .blog-body .chart .cv-n{display:none}
}

/* SVG cannot wrap or measure text, so a long category name on a phone runs
   through the value and out of the card. Where the author gave a short form,
   the two swap here. The table view always carries the full name. */
.blog-body .chart .cv-lbl--short{display:none}
@media (max-width:640px){
  .blog-body .chart .cv-lbl--long{display:none}
  .blog-body .chart .cv-lbl--short{display:block}
}

/* On paper the surface inverts. The gold ink darkens to hold its contrast on
   white, and the gaps between fills become white rather than panel — without
   this the separators disappear and a stack prints as one block. */
@media print{
  .blog-body .chart,
  .blog-body .cmp{background:#fff;border-color:#C9C4BA}
  .blog-body .chart .cv-lbl,
  .blog-body .chart__t th,
  .blog-body .chart__t td{fill:#1A1C20;color:#1A1C20}
  .blog-body .chart .cv-val{fill:#6B5200}
  .blog-body .chart .cv-axis-lbl,
  .blog-body .chart .cv-n{fill:#5A6068}
  .blog-body .chart .cv-track{fill:#EFEAE0;stroke:#D6D0C4}
  .blog-body .chart .cv-axis,
  .blog-body .chart .cv-grid{stroke:#B9B2A4}
  .blog-body .chart .cv-gap,
  .blog-body .chart .cv-dot{fill:#fff;stroke:#fff}
  .blog-body .chart__t[open] summary,
  .blog-body .chart__t summary{color:#5A6068}
  .blog-body .chart__t{display:block}
  .blog-body .chart__t table{display:table}
}

/* Where the operating system replaces colour outright, the marks keep their
   shape by taking the system's own ink. Nothing here encodes meaning in hue
   alone, so losing the hue loses nothing but the pleasure. */
@media (forced-colors:active){
  .blog-body .chart .cv-fill,
  .blog-body .chart .cv-dot{fill:CanvasText;forced-color-adjust:none}
  .blog-body .chart .cv-gap{fill:Canvas}
  .blog-body .chart .cv-track{fill:Canvas;stroke:CanvasText}
}
