/* ==========================================================================
   post.css — shared by post-toc.html, post-series.html, post-wide.html
   and post-minimal.html. Article-page components only; everything else
   comes from styles.css and css/vc.css.
   ========================================================================== */

/* ---------- Reading progress (all four pages) ---------- */
.rprog{position:fixed;top:0;left:0;right:0;height:2px;z-index:130;pointer-events:none;background:transparent}
.rprog i{display:block;height:100%;width:0;background:var(--accent);transform-origin:0 50%}
/* Framed on its own, there is no page to scroll. .rprog.inline drops it into
   the flow so the component can be seen at all — documentation only, never on
   a live page. */
.rprog.inline{position:static;height:2px;background:var(--border)}
@media (prefers-reduced-motion:reduce){.rprog i{transition:none}}

/* ---------- Article header ---------- */
.art-head{padding:48px var(--pad) 40px;border-bottom:1px solid var(--border)}
.art-badges{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:20px}
.art-head h1{font-family:var(--font-body);font-weight:600;text-transform:none;
  font-size:40px;line-height:44px;letter-spacing:0;max-width:22ch}
.art-head .dek{color:var(--muted);font-size:20px;line-height:30px;margin-top:20px;max-width:62ch}
.art-meta{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:24px;
  font-family:var(--font-mono);font-size:12px;line-height:16px;color:var(--muted-2)}
.art-meta .sep{opacity:.5}

/* ---------- Byline / author block ---------- */
.byline{display:flex;align-items:center;gap:12px;margin-top:28px}
.byline img{width:40px;height:40px;border-radius:0;object-fit:cover;flex:none;
  background:none;border:1px solid rgba(250,250,249,.22)}
.byline .nm{font-size:15px;line-height:20px;color:var(--text)}
.byline .nm:hover{text-decoration:underline;text-underline-offset:3px}
.byline .rl{color:var(--muted-2);font-size:13px;line-height:18px;margin-top:1px}

.authorbox{display:grid;grid-template-columns:72px minmax(0,1fr);gap:20px;align-items:start;
  border:1px solid var(--border);border-radius:0;padding:24px;background:var(--card)}
.authorbox img{width:72px;height:72px;border-radius:0;object-fit:cover;
  background:none;border:1px solid rgba(250,250,249,.22)}
.authorbox h3{font-size:16px;line-height:24px;font-weight:600}
.authorbox .rl{color:var(--muted-2);font-size:13px;line-height:18px;margin-top:2px}
.authorbox p{color:var(--muted);font-size:15px;line-height:23px;margin-top:12px;max-width:62ch}
.authorbox .links{display:flex;gap:16px;margin-top:14px;font-size:14px;line-height:20px}
.authorbox .links a{color:var(--text);text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--faint)}
.authorbox .links a:hover{text-decoration-color:var(--text)}

/* LinkedIn mark, in the byline and in the author box. Two shapes, because the
   two rows are doing different jobs. In the byline it is a bare glyph after the
   name, so it carries its own 28px hit area rather than inheriting the 16px of
   the icon. In the author box it sits in the .links row beside worded links, so
   it pairs the glyph with the word and takes that row's underline. */
.byline .li{display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;flex:none;color:var(--muted-2);transition:color .18s}
.byline .li svg{width:16px;height:16px;display:block}
.byline .li:hover{color:var(--text)}
.byline .li:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.authorbox .links a.li{display:inline-flex;align-items:center;gap:7px}
.authorbox .links a.li svg{width:15px;height:15px;flex:none}

/* ---------- Share row ---------- */
.share{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.share .lbl{font-family:var(--font-mono);font-size:12px;line-height:16px;color:var(--muted-2);
  margin-right:4px;white-space:nowrap}
.sbtn{display:inline-flex;align-items:center;gap:8px;height:34px;padding:7px 14px;border-radius:0;
  background:var(--chip);border:1px solid var(--border-2);color:var(--muted);
  font-size:13px;line-height:20px;font-weight:500;transition:color .18s,border-color .18s,background .18s}
.sbtn:hover{color:var(--text);border-color:var(--muted-2)}
.sbtn svg{width:14px;height:14px;flex:none}
.sbtn.ok{color:var(--accent);border-color:rgba(255,246,149,.4)}

/* ---------- Subscribe block ---------- */
.subs{border:1px solid var(--border);border-radius:0;background:var(--card);padding:28px;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,360px);gap:32px;align-items:center}
.subs h3{font-size:20px;line-height:28px;font-weight:600}
.subs p{color:var(--muted);font-size:15px;line-height:23px;margin-top:10px;max-width:46ch}
.subs .srow{display:flex;gap:10px;align-items:flex-end}
.subs .srow .field{flex:1;min-width:0}
.subs .ok{display:none;color:var(--accent);font-size:14px;line-height:20px;margin-top:12px}
.subs .ok.on{display:block}
.subs .fine{color:var(--muted-2);font-size:12px;line-height:18px;margin-top:12px}

/* ---------- Related posts ---------- */
.rel-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.post-card,.article-card{display:flex;flex-direction:column;min-width:0;
  border:1px solid var(--border);border-radius:0;padding:20px;background:var(--card);
  transition:border-color .2s,background .2s}
.post-card:hover,.article-card:hover{border-color:var(--border-2);background:#191512}
/* Cover art, when the card has any. Its own hairline inside the card's padding,
   matching how the writing index draws covers (.srow .cover, blogidx.css). */
.post-card > .cover,.article-card > .cover{border-radius:0;overflow:hidden;
  border:1px solid var(--border);background:#141210;margin-bottom:16px}
.post-card > .cover svg,.article-card > .cover svg{display:block;width:100%;height:auto}
/* A pill is as wide as its label. The card is a flex column, so a bare
   .badge-pill inherited align-items:stretch and ran the full width of the card,
   reading as a header bar rather than a tag. The 14px under it was only ever set
   on .series, so a card whose pill carried no .series had its title sitting hard
   against the pill. Both fixed here, for any pill in either card. */
.post-card > .badge-pill,.article-card > .badge-pill{align-self:flex-start;margin-bottom:14px}
.post-card .series,.article-card .series{margin-bottom:14px}
.post-card h3,.article-card h3{font-size:16px;line-height:24px;font-weight:600}
.post-card h3 a:hover,.article-card h3 a:hover{opacity:.75}
.post-card p,.article-card p{color:var(--muted);font-size:14px;line-height:22px;margin-top:8px}
.post-card .foot,.article-card .foot{display:flex;align-items:center;gap:8px;margin-top:auto;padding-top:16px;
  font-family:var(--font-mono);font-size:11px;line-height:16px;color:var(--muted-2)}

/* ---------- Article furniture shared by toc/series ---------- */
.art-body{padding:40px var(--pad) 56px}
.art-foot{padding:40px var(--pad);border-top:1px solid var(--border)}
.art-foot + .art-foot{border-top:1px solid var(--border)}
.prose h4{font-size:15px;line-height:22px;font-weight:600;color:var(--text);margin-top:24px}
.prose h2{scroll-margin-top:96px}
.prose h3,.prose h4{scroll-margin-top:96px}
.prose .kicker{font-family:var(--font-mono);font-size:12px;line-height:16px;color:var(--muted-2);
  letter-spacing:.04em;text-transform:uppercase}

/* ==========================================================================
   post-toc.html — side navigation
   ========================================================================== */
.post-grid{display:grid;grid-template-columns:264px minmax(0,1fr)}
.post-grid > .post-aside{border-right:1px solid var(--border);min-width:0}
.post-grid > .post-main{min-width:0}

.toc-wrap{position:sticky;top:calc(var(--nav-h) + 24px);padding:32px 24px 32px var(--pad)}
.toc-disc > summary{list-style:none;cursor:pointer}
.toc-disc > summary::-webkit-details-marker{display:none}
.toc-sum{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;
  font-size:14px;line-height:20px;font-weight:500;color:var(--text);
  border:1px solid var(--border-2);border-radius:0;padding:11px 14px;background:var(--chip)}
.toc-sum .cnt{font-family:var(--font-mono);font-size:11px;color:var(--muted-2)}
.toc-sum .chv{width:14px;height:14px;color:var(--muted);transition:transform .2s}
.toc-disc[open] .toc-sum .chv{transform:rotate(180deg)}

.toc-t{font-size:12px;line-height:16px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted-2);margin-bottom:14px}
.toc-nav{display:block;max-height:calc(100vh - 260px);overflow-y:auto;
  border-left:1px solid var(--border);scrollbar-width:thin}
.toc-nav a{display:block;color:var(--muted-2);font-size:13px;line-height:19px;
  padding:6px 0 6px 14px;margin-left:-2px;border-left:2px solid transparent;
  transition:color .18s,border-color .18s}
.toc-nav a:hover{color:var(--text)}
.toc-nav a.l3{padding-left:28px;font-size:13px}
.toc-nav a.on{color:var(--text);border-left-color:var(--accent)}
.toc-nav a.on.l3{border-left-color:var(--accent)}

.toc-prog{display:flex;align-items:center;gap:10px;margin-top:18px;
  font-family:var(--font-mono);font-size:11px;line-height:16px;color:var(--muted-2)}
.toc-prog .track{flex:1;height:2px;background:var(--border-2);border-radius:0;overflow:hidden}
.toc-prog .track i{display:block;height:100%;width:0;background:var(--accent)}
.toc-prog .pct{width:34px;text-align:right;white-space:nowrap}

.toc-top{display:inline-flex;align-items:center;gap:8px;margin-top:18px;
  font-size:13px;line-height:20px;color:var(--muted-2);transition:color .18s}
.toc-top:hover{color:var(--text)}

/* ==========================================================================
   post-series.html — series navigation
   ========================================================================== */
.series-head{padding:28px var(--pad);border-bottom:1px solid var(--border);background:var(--chip)}
.series-top{display:flex;align-items:baseline;justify-content:space-between;gap:20px;flex-wrap:wrap}
.series-top .nmz{font-size:16px;line-height:24px;font-weight:600}
.series-top .nmz .pre{color:var(--muted-2);font-weight:400;font-size:13px;display:block;margin-bottom:4px}
.series-top .pos{font-family:var(--font-mono);font-size:12px;line-height:16px;color:var(--muted)}
.series-bar{display:flex;gap:6px;margin-top:16px}
.series-bar span{flex:1;height:4px;border-radius:0;background:var(--border-2)}
.series-bar span.done{background:var(--muted-2)}
.series-bar span.now{background:var(--accent)}

.series-parts{display:flex;flex-direction:column;border-top:1px solid var(--border);margin:0 -12px}
.part{display:grid;grid-template-columns:56px minmax(0,1fr) auto;gap:16px;align-items:center;
  padding:16px 12px;border-bottom:1px solid var(--hairline);transition:background .18s}
.part:last-child{border-bottom:none}
.part:hover{background:rgba(250,250,249,.02)}
.part .n{font-family:var(--font-mono);font-size:12px;line-height:16px;color:var(--faint)}
.part .ti{font-size:15px;line-height:22px;color:var(--muted)}
.part .st{font-family:var(--font-mono);font-size:11px;line-height:16px;color:var(--muted-2);white-space:nowrap}
.part.done .n{color:var(--accent)}
.part.done .ti{color:var(--text)}
.part.now{background:rgba(255,246,149,.05)}
.part.now .n{color:var(--accent)}
.part.now .ti{color:var(--text);font-weight:600}
.part.now .st{color:var(--accent)}
.part.todo .ti{color:var(--muted-2)}

.pnnav{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.pn{display:flex;flex-direction:column;gap:6px;border:1px solid var(--border);border-radius:0;
  padding:18px 20px;background:var(--card);transition:border-color .2s,background .2s;min-width:0}
.pn:hover{border-color:var(--border-2);background:#191512}
.pn .dir{display:flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:11px;
  line-height:16px;color:var(--muted-2);text-transform:uppercase;letter-spacing:.04em}
.pn .ti{font-size:15px;line-height:22px;font-weight:600;color:var(--text)}
.pn.next{text-align:right}
.pn.next .dir{justify-content:flex-end}
.pn svg{width:12px;height:12px}

/* ==========================================================================
   post-wide.html — full-bleed editorial
   ========================================================================== */
.wide-hero{position:relative;border-bottom:1px solid var(--border);overflow:hidden}
.wide-hero .art{display:block;width:100%;height:340px}
.wide-hero .art svg{display:block;width:100%;height:100%}
.wide-cap{padding:14px var(--pad);border-top:1px solid var(--border);
  font-family:var(--font-mono);font-size:11px;line-height:16px;color:var(--faint)}

.disp-xl{font-family:var(--font-head);font-weight:700;text-transform:uppercase;
  font-size:64px;line-height:58px;letter-spacing:0;max-width:16ch}
.wide-head{padding:56px var(--pad) 44px;border-bottom:1px solid var(--border)}
.wide-head .dek{color:var(--muted);font-size:20px;line-height:30px;margin-top:24px;max-width:62ch}

.intro2{columns:2;column-gap:48px;padding:40px var(--pad) 0}
.intro2 p{color:var(--muted);font-size:16px;line-height:26px;break-inside:avoid}
.intro2 p + p{margin-top:20px}
.intro2 p:first-child::first-letter{float:left;font-family:var(--font-head);font-weight:700;
  font-size:56px;line-height:44px;padding:4px 10px 0 0;color:var(--text)}

.wide-stack > * + *{margin-top:28px}
.pullq{border-top:1px solid var(--border);border-bottom:1px solid var(--border);
  padding:44px var(--pad);margin:48px calc(var(--pad) * -1);text-align:center}
.pullq blockquote{font-family:var(--font-head);font-weight:700;text-transform:uppercase;
  font-size:34px;line-height:36px;letter-spacing:0;max-width:20ch;margin:0 auto;color:var(--text);
  quotes:"\201C" "\201D" "\2018" "\2019"}
.pullq blockquote::before{content:open-quote;color:var(--accent)}
.pullq blockquote::after{content:close-quote;color:var(--accent)}
.pullq .by{font-family:var(--font-mono);font-size:11px;line-height:16px;color:var(--muted-2);
  margin-top:20px;letter-spacing:.04em;text-transform:uppercase}

.fig{margin:36px 0;border:1px solid var(--border);border-radius:0;overflow:hidden;background:var(--card)}
.fig .viz{display:block;width:100%;height:220px;background:linear-gradient(150deg,var(--surface),var(--card))}
.fig .viz svg{display:block;width:100%;height:100%}
.fig figcaption{padding:14px 18px;border-top:1px solid var(--border);
  color:var(--muted-2);font-size:13px;line-height:20px}
.fig figcaption b{color:var(--muted);font-weight:600}
.fig.bleed{border-left:none;border-right:none;border-radius:0;margin:44px calc(var(--pad) * -1)}

.fnref{font-family:var(--font-mono);font-size:11px;vertical-align:super;line-height:0;
  color:var(--accent);text-decoration:none;padding:0 1px}
.fnref:hover{text-decoration:underline}
.fnotes{border-top:1px solid var(--border);padding-top:28px;margin-top:44px}
.fnotes h2{font-size:16px;line-height:24px;font-weight:600;margin-bottom:16px}
.fnotes ol{list-style:none;display:flex;flex-direction:column;gap:12px;padding:0;counter-reset:fn}
/* Small print. A source list is reference material read once, not body copy —
   at the body size it competed with the argument above it for the same
   attention. 12px on an 18px line, with the counter a step below that. */
.fnotes li{display:grid;grid-template-columns:20px minmax(0,1fr);gap:8px;
  color:var(--muted-2);font-size:12px;line-height:18px;scroll-margin-top:96px}
.fnotes li::before{counter-increment:fn;content:counter(fn) ".";font-family:var(--font-mono);
  font-size:11px;color:var(--faint)}

/* Two columns, but only once the list is long enough to earn them: :has(li:nth-child(7))
   is "more than six notes". Under that, two columns of three read as a broken table
   rather than a list, and a single column is easier to scan.

   Two details this depends on. The one-column list is a flex column, and `columns`
   does nothing to a flex container — so display has to go back to block, and the
   12px that was a flex gap becomes a margin. And the count is a *minimum column
   width*, not a flat 2: `columns:2 240px` gives two columns at the article measure
   and drops to one below ~520px, so no media query is needed and a phone never gets
   two 130px columns. Where :has is not supported the list stays single-column,
   which is the safe way to fail. */
.fnotes ol:has(li:nth-child(7)){display:block;columns:2 240px;column-gap:40px}
.fnotes ol:has(li:nth-child(7)) li{margin-bottom:12px;break-inside:avoid}
.fnotes ol:has(li:nth-child(7)) li:last-child{margin-bottom:0}

/* Split the list in half by COUNT, not by height.
   Left to itself, multicol balances the two columns' heights — and the notes are
   not the same height, since some wrap to two lines and some carry a back-chip.
   Thirteen notes came out 5 on the left and 8 on the right: correctly balanced,
   and it reads as a mistake, because a numbered list is counted rather than
   weighed.
   So the break is forced at the halfway item: for n notes the left column keeps
   the first ceil(n/2), which means break-before on item ceil(n/2)+1. Each rule
   below is one pair of lengths — "has a 9th but no 11th" is n of 9 or 10, whose
   halfway point is the same — and the ladder covers 7 to 20 notes. Past 20 it
   falls back to balancing, which is the right failure: a list that long is a
   bibliography and the count stops being the thing you read it by. */
.fnotes ol:has(li:nth-child(7)):not(:has(li:nth-child(9)))  li:nth-child(5){break-before:column}
.fnotes ol:has(li:nth-child(9)):not(:has(li:nth-child(11))) li:nth-child(6){break-before:column}
.fnotes ol:has(li:nth-child(11)):not(:has(li:nth-child(13))) li:nth-child(7){break-before:column}
.fnotes ol:has(li:nth-child(13)):not(:has(li:nth-child(15))) li:nth-child(8){break-before:column}
.fnotes ol:has(li:nth-child(15)):not(:has(li:nth-child(17))) li:nth-child(9){break-before:column}
.fnotes ol:has(li:nth-child(17)):not(:has(li:nth-child(19))) li:nth-child(10){break-before:column}
.fnotes ol:has(li:nth-child(19)):not(:has(li:nth-child(21))) li:nth-child(11){break-before:column}
.fnotes li:target{color:var(--text)}
/* Back-reference. The icon alone: "Back to text" printed on four chips in a row
   was more label than a repeated control needs, and the arrow says it. The name
   lives on the anchor's aria-label, so it is still announced. Square, and sized
   off the icon rather than the text it no longer has. */
.fnbk{display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;margin-left:8px;padding:0;
  border:1px solid var(--border);color:var(--muted-2);
  /* The chip's box has to fit inside the note's 20px line, or the four notes that
     carry one stand 4px taller than the nine that do not and the list staggers. */
  vertical-align:-3px;line-height:0;
  transition:color .15s,border-color .15s,background .15s}
.fnbk svg{width:10px;height:10px;flex:none}
.fnbk:hover{color:var(--text);border-color:var(--border-2);background:var(--chip)}

/* ==========================================================================
   post-minimal.html — reading first
   ========================================================================== */
.min-wrap{padding:0 var(--pad)}
.min-col{max-width:640px;margin:0 auto}
.min-col.wide{max-width:920px}
.min-head{padding:80px 0 44px}
.min-head h1{font-family:var(--font-body);font-weight:600;text-transform:none;
  font-size:36px;line-height:42px;letter-spacing:0}
.min-head .dek{color:var(--muted);font-size:19px;line-height:30px;margin-top:18px}
.min-body{padding:8px 0 64px}
.min-body.prose{max-width:640px}
.min-body.prose p,.min-body.prose li{font-size:18px;line-height:32px;color:#bdb7b1}
.min-body.prose > * + *{margin-top:28px}
.min-body.prose h2{font-size:22px;line-height:30px;margin-top:52px}
.min-body.prose h3{font-size:17px;line-height:24px;margin-top:36px}
.min-rule{height:1px;background:var(--border);margin:0}
.min-foot{padding:44px 0 96px;display:flex;flex-direction:column;gap:40px}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width:1100px){
  .post-grid{grid-template-columns:minmax(0,1fr)}
  .post-grid > .post-aside{border-right:none;border-bottom:1px solid var(--border)}
  .toc-wrap{position:static;padding:24px var(--pad)}
  .toc-nav{max-height:none;overflow:visible;margin-top:14px}
  .toc-t{display:none}
  .art-head h1{font-size:32px;line-height:36px}
  .disp-xl{font-size:44px;line-height:42px}
  .wide-hero .art{height:260px}
  .subs{grid-template-columns:minmax(0,1fr);gap:24px}
  .rel-grid{grid-template-columns:repeat(2,1fr)}
  .rel-grid > *:nth-child(3){grid-column:1 / -1}
  .intro2{columns:1}
  .min-head{padding:56px 0 36px}
}
@media (min-width:1101px){
  .toc-disc > summary{display:none}
}
@media (max-width:620px){
  .art-head,.art-body,.art-foot,.series-head,.wide-head,.wide-cap{padding-left:24px;padding-right:24px}
  .art-head h1{font-size:27px;line-height:32px}
  .art-head .dek{font-size:17px;line-height:26px}
  .disp-xl{font-size:32px;line-height:32px}
  .wide-hero .art{height:190px}
  .pullq blockquote{font-size:24px;line-height:26px}
  .pullq{padding:32px 24px}
  .fig.bleed{margin-left:-24px;margin-right:-24px}
  .rel-grid{grid-template-columns:1fr}
  .rel-grid > *:nth-child(3){grid-column:auto}
  .subs{padding:22px}
  .subs .srow{flex-direction:column;align-items:stretch}
  .pnnav{grid-template-columns:1fr}
  .pn.next{text-align:left}
  .pn.next .dir{justify-content:flex-start}
  .part{grid-template-columns:32px minmax(0,1fr);gap:12px}
  .part .st{grid-column:2;justify-self:start}
  .authorbox{grid-template-columns:1fr}
  .min-wrap{padding:0 24px}
  .min-head{padding:44px 0 28px}
  .min-head h1{font-size:28px;line-height:34px}
  .min-body.prose p,.min-body.prose li{font-size:17px;line-height:30px}
  .intro2{padding-left:24px;padding-right:24px}
  .toc-wrap{padding:20px 24px}
}

/* Syndicated pieces carry the originating masthead, the author and the
   permission line at the foot — the byline at the top names the writer, this
   names the licence. */
.min-foot .syndication{font-size:14px;line-height:22px;color:var(--muted-2);margin:0}
.min-foot .syndication a{color:var(--muted);text-decoration:underline;text-underline-offset:3px}
.min-foot .syndication a:hover{color:var(--text)}
