/* Blog listing + post template.
   Theme-aware: blog pages carry .bl-page on <body>; html[data-theme="light"|"dark"]
   is set pre-paint in head.html (default light) and toggled by js/blog.js.
   All components read the --pg-* tokens below — never the raw main.css tokens —
   so both themes come from one place. All classes are bl- prefixed (main.css owns
   .kicker/.blog-head/.post-meta/.post-body for homepage sections). */

.bl-page{
  /* one accent per post — the deck rule ("one accent colour per slide") applied to
     the blog. A post claims its colour inline on <body style="--post-accent:…">;
     --post-accent-aa is the darker cut of the same colour, used wherever it has to
     read as text on light paper. Everything downstream only ever sees --pg-accent. */
  --post-accent:var(--orange);
  --post-accent-aa:var(--orange-d);
  /* dark = the site's own palette */
  --pg-bg:var(--bg);
  --pg-fg:var(--fg);
  --pg-fg-2:var(--fg-2);
  --pg-line:var(--line);
  --pg-accent:var(--post-accent);
  --pg-accent-lg:var(--post-accent); /* large-text cut — brighter than -aa in light */
  --pg-card:var(--bg-2);
  /* scrim laid over an optional hero background image so the centred title/meta
     always read — dark tone on dark, matched to --pg-bg so text colour is unchanged */
  --hero-scrim:linear-gradient(rgba(34,34,41,.68),rgba(34,34,41,.82));
  background:var(--pg-bg);color:var(--pg-fg);
}
[data-theme="light"] .bl-page{
  /* light = warm paper, AA-safe accent for text */
  --pg-bg:var(--paper);
  --pg-fg:#17171c;
  --pg-fg-2:#5e5b53;
  --pg-line:rgba(23,23,28,.13);
  --pg-accent:var(--post-accent-aa);
  --pg-accent-lg:var(--post-accent-lg,var(--post-accent-aa));
  --pg-card:var(--paper-2);
  /* light paper scrim: lift the image toward the paper tone so dark text reads */
  --hero-scrim:linear-gradient(rgba(251,250,247,.80),rgba(251,250,247,.88));
}
/* text selection joins the post's accent (main.css pins it to orange globally) */
.bl-page ::selection{background:var(--pg-accent);color:var(--pg-bg)}

/* the shared header adapts on blog pages in light mode (it reads var(--fg) = white) */
[data-theme="light"] .bl-page .logo .lb,
[data-theme="light"] .bl-page .logo .lw{fill:var(--pg-fg)}
[data-theme="light"] .bl-page .logo:hover .lb{fill:var(--orange)}
[data-theme="light"] .bl-page .navlinks{color:var(--pg-fg);text-shadow:none} /* the shadow is for the homepage video */
[data-theme="light"] .bl-page .burger span{background:var(--pg-fg)}
[data-theme="light"] .bl-page header.scrolled{background:rgba(251,250,247,.72);
  box-shadow:inset 0 -1px 0 rgba(23,23,28,.07);
  -webkit-backdrop-filter:blur(24px) saturate(1.4);backdrop-filter:blur(24px) saturate(1.4)}
[data-theme="light"] .bl-page .logo-svg{filter:none}

/* the labs overlay is its own dark world — re-pin the tokens it reads */
.bl-page #labsPortal{--fg:#f6f3ec;--fg-2:#d7d3c8;--bg:#222229;--line:rgba(255,255,255,.10)}

/* matches .wrap (1400px) so blog content shares the nav's left edge */
.bl-main{padding:150px var(--pad) 90px;max-width:var(--wrap-max);margin:0 auto}

/* ---- shared bits ---- */
.bl-kicker{display:flex;align-items:center;gap:12px;font-family:var(--sans);font-weight:700;
  font-size:0.8125rem;letter-spacing:.14em;text-transform:uppercase;color:var(--pg-accent)}
.bl-kicker::before{content:"";width:34px;height:1px;background:var(--pg-accent)}

/* round utility buttons: share + theme toggle */
.bl-btn{display:inline-flex;align-items:center;gap:8px;background:none;cursor:pointer;
  border:1px solid var(--pg-line);border-radius:999px;padding:8px 16px;
  font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;color:var(--pg-fg);
  transition:border-color .2s,color .2s}
.bl-btn:hover{border-color:var(--pg-accent);color:var(--pg-accent)}
.bl-btn svg{width:14px;height:14px}

/* ---- listing ---- */
/* full-bleed masthead sheet, same treatment as the post hero: card-tone paper
   from the very top of the page (behind the nav — -150px matches .bl-main's top
   padding) down past the featured post, which now lives inside .bl-mast and shares
   this colour. Soft shadow only, no hairline. */
.bl-mast{position:relative;margin-bottom:60px}
.bl-mast::before{content:"";position:absolute;z-index:-1;
  left:calc(50% - 50vw);width:100vw;top:-150px;bottom:-44px;
  background:var(--pg-card);
  border-bottom:1px solid var(--pg-line); /* dark: the shadow is invisible, the seam isn't */
  box-shadow:0 18px 30px -28px rgba(23,23,28,.10)}
[data-theme="light"] .bl-page .bl-mast::before{border-bottom:0} /* light keeps shadow-only */
.bl-head{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;
  flex-wrap:wrap;margin-bottom:34px}
.bl-head h1{font-family:var(--sans);font-weight:800;font-size:clamp(2.375rem,6vw,4.5rem);
  letter-spacing:-0.03em;line-height:1.02;margin:14px 0 0}

/* every entry resolves its own post's accent: bright cut on dark, AA cut on paper.
   Entries without an inline --acc fall back to the page accent. */
.bl-row,.bl-feature{--en-acc:var(--acc,var(--pg-accent));--en-acc-lg:var(--acc,var(--pg-accent))}
[data-theme="light"] .bl-page .bl-row,
[data-theme="light"] .bl-page .bl-feature{--en-acc:var(--acc-aa,var(--pg-accent));--en-acc-lg:var(--acc-lg,var(--acc-aa,var(--pg-accent)))}
.bl-row[hidden],.bl-feature[hidden]{display:none}

/* category filter chips — the masthead sheet owns the gap below */
.bl-filters{display:flex;flex-wrap:wrap;gap:10px;margin:0}
.bl-chip{background:none;cursor:pointer;border:1px solid var(--pg-line);border-radius:999px;
  padding:7px 15px;font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;color:var(--pg-fg-2);
  transition:border-color .2s,color .2s,background .2s}
.bl-chip:hover{border-color:var(--pg-fg);color:var(--pg-fg)}
.bl-chip.on{background:color-mix(in srgb, var(--pg-accent) 15%, transparent);
  border-color:var(--pg-accent);color:var(--pg-accent);font-weight:600}

/* featured (latest) post: sits inside the masthead band and shares its colour, so it
   drops its own card fill/clip — the black art panel carries the rounding, and the
   text aligns flush-left with the "News, views…" title above it. */
.bl-feature{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,46%);
  text-decoration:none;margin:44px 0 0;align-items:center}
.bl-feature-body{padding:clamp(18px,3vw,36px) clamp(28px,4vw,48px) clamp(18px,3vw,36px) 0;
  display:flex;flex-direction:column;align-items:flex-start;justify-content:center}
.bl-feature .bl-rowmeta{flex-direction:row;align-items:center;gap:14px}
.bl-feature h2{font-family:var(--sans);font-weight:800;font-size:clamp(1.625rem,3.4vw,2.625rem);
  letter-spacing:-0.03em;line-height:1.06;margin:18px 0 0;transition:color .2s}
.bl-feature:hover h2{color:var(--en-acc-lg)}
.bl-feature .bl-excerpt{margin:16px 0 0;font-size:1rem;color:var(--pg-fg-2);line-height:1.55;max-width:52ch}
.bl-feature .bl-byline{margin-top:26px}
/* the cover is a black deck slide — contain the full slide and let the panel's
   black continue it, rather than cropping the slide's own headline.
   overflow:hidden clips the hover zoom to the panel. */
.bl-feature-media{position:relative;min-height:300px;background:var(--black);overflow:hidden;border-radius:18px}
.bl-feature-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  transition:transform .5s ease}
.bl-feature:hover .bl-feature-media img{transform:scale(1.025)}

/* rows */
.bl-list{border-bottom:1px solid var(--pg-line)}
.bl-row{display:grid;grid-template-columns:150px 1fr 220px;gap:28px;align-items:baseline;
  padding:34px 0;border-top:1px solid var(--pg-line);text-decoration:none}
/* the masthead band's shadow already marks its lower edge — don't double it with a hard
   rule under the first row. Hairlines stay between rows, where they divide entries. */
.bl-list .bl-row:first-child{border-top:0}
.bl-row time{font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;color:var(--pg-fg-2)}
.bl-row h2{font-family:var(--sans);font-weight:700;font-size:clamp(1.375rem,3vw,2.125rem);
  letter-spacing:-0.02em;line-height:1.1;margin:0;transition:color .2s}
.bl-row:hover h2{color:var(--en-acc-lg)}
.bl-row .bl-excerpt{margin:10px 0 0;font-size:1rem;color:var(--pg-fg-2);line-height:1.5;max-width:56ch}

/* optional row thumbnail — the row grid is untouched; the body cell just splits into
   text + a rounded thumb, echoing the feature card's media panel at row scale.
   Rows without .has-thumb keep their plain single-column body. */
.bl-row.has-thumb .bl-rowmain{display:grid;grid-template-columns:1fr 200px;gap:28px;align-items:start}
.bl-thumb{border-radius:12px;overflow:hidden;background:var(--pg-card);aspect-ratio:16/10}
.bl-thumb img{width:100%;height:100%;object-fit:cover;transition:transform .5s ease}
.bl-row:hover .bl-thumb img{transform:scale(1.04)}
@media(prefers-reduced-motion:reduce){.bl-thumb img{transition:none}}
@media(max-width:820px){.bl-row.has-thumb .bl-rowmain{grid-template-columns:1fr 150px}}

/* meta column: category eyebrow stays neutral like the date — the post's accent is held
   back for the hover reveal (title) and the post's own hero, not scattered here. */
.bl-rowmeta{display:flex;flex-direction:column;align-items:flex-start;gap:9px}
.bl-rowmeta time{font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;color:var(--pg-fg-2)}
.bl-rowcat{display:inline-flex;align-items:center;gap:8px;font-family:'IBM Plex Mono',monospace;
  font-size:0.75rem;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--pg-fg-2)}
.bl-rowcat::before{content:"";width:22px;height:2px;border-radius:1px;background:var(--en-acc-lg);flex:none}
.bl-rowcat b{font-weight:700;color:var(--pg-fg)}
/* reading-time estimate: mono like the date, one notch dimmer so the date leads.
   In the feature's inline meta it trails the date behind a middot; stacked in a row
   it just sits under the date. */
.bl-readtime{font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;color:var(--pg-fg-2);opacity:.75}
.bl-feature .bl-readtime{display:inline-flex;align-items:center;gap:14px}
.bl-feature .bl-readtime::before{content:"";width:3px;height:3px;border-radius:50%;background:currentColor;opacity:.6}

.bl-byline{display:flex;align-items:center;gap:10px;justify-self:end}
.bl-byline img{width:34px;height:34px;border-radius:50%;object-fit:cover}
.bl-byline span{font-size:0.875rem;color:var(--pg-fg-2)}

.bl-empty{margin:26px 4px 0;font-family:'IBM Plex Mono',monospace;font-size:0.875rem;color:var(--pg-fg-2)}

.bl-chip:focus-visible,.bl-row:focus-visible,.bl-feature:focus-visible{
  outline:2px solid var(--en-acc,var(--pg-accent));outline-offset:3px}

@media(prefers-reduced-motion:reduce){
  .bl-feature-media img{transition:none}
  .bl-feature:hover .bl-feature-media img{transform:none}
}
@media(max-width:900px){
  .bl-feature{grid-template-columns:1fr}
  .bl-feature-media{order:-1;min-height:0;aspect-ratio:16/8}
}
@media(max-width:820px){
  .bl-row{grid-template-columns:1fr;gap:10px}
  .bl-rowmeta{flex-direction:row;align-items:center;gap:14px}
  .bl-byline{justify-self:start}
}

/* ---- post hero: centred, meta line above the title ---- */
/* the ::before is a full-bleed masthead sheet: card-tone paper from the very top of
   the page (behind the nav — -150px matches .bl-main's top padding) to just under the
   author. No hairline: the soft shadow alone marks the edge, so the utility bar keeps
   the only rules on the page. 100vw + body overflow-x:hidden handles the bleed. */
.bl-post-hero{position:relative;max-width:820px;margin:0 auto 64px;text-align:center}
.bl-post-hero::before{content:"";position:absolute;z-index:-1;
  left:calc(50% - 50vw);width:100vw;top:-150px;bottom:-40px;
  background:var(--pg-card);
  border-bottom:1px solid var(--pg-line); /* dark: the shadow is invisible, the seam isn't */
  box-shadow:0 18px 30px -28px rgba(23,23,28,.10)}
[data-theme="light"] .bl-page .bl-post-hero::before{border-bottom:0} /* light keeps shadow-only */

/* optional hero background image. A post opts in with:
     <div class="bl-post-hero has-bg" style="--hero-bg:url(/assets/blog/…)">
   The theme-aware --hero-scrim sits over the image so the title/meta/author stay
   legible in both light and dark. Falls back cleanly to the card sheet if --hero-bg
   is unset. Extra breathing room since the art now runs to the band edges. */
.bl-post-hero.has-bg{padding:clamp(30px,5vw,58px) 22px 4px}
.bl-post-hero.has-bg::before{
  background:var(--hero-scrim),var(--hero-bg,none) center/cover no-repeat,var(--pg-card)}

/* ---- hero styles, switchable via body[data-hero="overlay|split|band"] ----
   Every style reads one image, set once inline on .bl-post-hero:
     --hero-bg    an art-only crop  (overlay + split)
     --hero-cover the full slide    (band — its own headline can't collide there)
   In a CMS these map to a single "Hero style" field + one image picker. ---- */
.bl-hero-band{display:none} /* only the band style shows the figure */

/* A) OVERLAY — full-bleed art behind the centred title, theme-aware scrim over it.
   (Also reachable via the plain .has-bg class for a hard-coded post.) */
body[data-hero="overlay"] .bl-post-hero{padding:clamp(30px,5vw,58px) 22px 4px;text-align:center}
body[data-hero="overlay"] .bl-post-hero::before{
  background:var(--hero-scrim),var(--hero-bg,none) center/cover no-repeat,var(--pg-card)}

/* B) SPLIT 50/50 — text in the left half on paper/ink, the image a hard-edged panel
   filling the right half of the viewport. No gradient, no scrim: a clean vertical seam. */
body[data-hero="split"] .bl-post-hero{max-width:none;text-align:left;
  min-height:min(42vw,470px);display:flex;flex-direction:column;justify-content:center;
  padding:clamp(30px,5vw,64px) 0}
body[data-hero="split"] .bl-post-hero>*{max-width:44%}
body[data-hero="split"] .bl-post-hero .bl-meta-line{justify-content:flex-start}
body[data-hero="split"] .bl-post-hero::before{box-shadow:none;border-bottom:0;left:50%;width:50vw;
  top:-150px;bottom:0; /* runs up behind the nav — a gap above the panel reads as a mistake */
  background:var(--hero-bg,none) center/cover no-repeat}
/* the sheet ::before normally paints — split repurposed it as the image panel,
   so the masthead-style paper comes back on ::after, behind everything */
body[data-hero="split"] .bl-post-hero::after{content:"";position:absolute;z-index:-2;
  left:calc(50% - 50vw);width:100vw;top:-150px;bottom:0;
  background:var(--pg-card);
  border-bottom:1px solid var(--pg-line);
  box-shadow:0 18px 30px -28px rgba(23,23,28,.10)}
[data-theme="light"] .bl-page[data-hero="split"] .bl-post-hero::after{border-bottom:0}

/* C) BAND — clean centred header with the picture as a cinematic band that sits
   between the meta line and the title. The band breaks out to the wrap width while the
   type stays at its reading measure. No scrim; type never overlaps the art. */
body[data-hero="band"] .bl-post-hero::before{display:none} /* no card sheet: plain header */
body[data-hero="band"] .bl-hero-band{display:block;
  width:var(--wide);margin-left:50%;transform:translateX(-50%);
  height:clamp(300px,32vw,430px);margin-top:clamp(22px,3vw,32px);
  margin-bottom:clamp(26px,3.5vw,44px);
  border-radius:18px;overflow:hidden;
  background:var(--black) var(--hero-cover,var(--hero-bg,none)) center/cover no-repeat;
  box-shadow:0 26px 52px -32px rgba(23,23,28,.4)}

/* D) TEXT ONLY — no image, plain paper. Two alignments: centred and left. */
body[data-hero="text-center"] .bl-post-hero::before,
body[data-hero="text-left"] .bl-post-hero::before{display:none}
body[data-hero="text-left"] .bl-post-hero{margin-left:0;text-align:left}
body[data-hero="text-left"] .bl-post-hero .bl-meta-line{justify-content:flex-start}

@media(max-width:820px){
  /* split stacks: fall back to the overlay treatment so text stays legible */
  body[data-hero="split"] .bl-post-hero{text-align:center;min-height:0;
    padding:clamp(30px,5vw,58px) 22px 4px}
  body[data-hero="split"] .bl-post-hero>*{max-width:100%}
  body[data-hero="split"] .bl-post-hero .bl-meta-line{justify-content:center}
  body[data-hero="split"] .bl-post-hero::before{left:calc(50% - 50vw);width:100vw;
    background:var(--hero-scrim),var(--hero-bg,none) center/cover no-repeat,var(--pg-card)}
  body[data-hero="band"] .bl-hero-band{height:clamp(220px,52vw,340px)}
}

/* ---- corner hero-style switcher (preview/testing tool only) ---- */
.hero-switch{position:fixed;z-index:60;right:22px;bottom:22px;
  display:flex;flex-direction:column;align-items:flex-end;gap:8px}
.hero-switch-toggle{border:1px solid var(--pg-line);cursor:pointer;
  background:var(--pg-card);color:var(--pg-fg-2);
  font-family:'IBM Plex Mono',monospace;font-size:0.6875rem;letter-spacing:.12em;
  text-transform:uppercase;padding:8px 14px;border-radius:999px;
  box-shadow:0 14px 34px -14px rgba(0,0,0,.4);transition:color .15s,background .15s}
.hero-switch-toggle:hover,.hero-switch.is-open .hero-switch-toggle{color:var(--pg-fg)}
.hero-switch-menu{display:none;flex-direction:column;align-items:stretch;gap:2px;
  padding:6px;border-radius:12px;background:var(--pg-card);
  border:1px solid var(--pg-line);box-shadow:0 14px 34px -14px rgba(0,0,0,.4)}
.hero-switch.is-open .hero-switch-menu{display:flex}
.hero-switch-menu button{border:0;background:none;cursor:pointer;color:var(--pg-fg-2);
  font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;padding:7px 14px;
  border-radius:12px;text-align:left;transition:background .15s,color .15s}
.hero-switch-menu button:hover{color:var(--pg-fg)}
.hero-switch-menu button[aria-pressed="true"]{background:var(--pg-fg);color:var(--pg-bg)}
.bl-meta-line{display:flex;justify-content:center;gap:1.6em;font-family:'IBM Plex Mono',monospace;
  font-size:0.8125rem;color:var(--pg-fg-2)}
.bl-meta-line .bl-cat{color:var(--pg-accent)}
.bl-post-hero h1{font-family:var(--sans);font-weight:800;font-size:clamp(2rem,4.6vw,3.5rem);
  letter-spacing:-0.03em;line-height:1.05;margin:20px 0 0}

/* ---- utility bar: one hairline below only — the hero band edge above it
   already separates, so a top rule would double up ---- */
.bl-utility{margin:0 0 48px;display:flex;align-items:center;
  justify-content:space-between;gap:16px;padding:0 4px 14px;
  border-bottom:1px solid var(--pg-line)}
.bl-read{font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;color:var(--pg-fg-2)}
.bl-utils{display:flex;gap:10px}

/* breadcrumb back to the listing, sharing the read-time slot */
.bl-nav-left{display:flex;align-items:center;gap:16px}
.bl-crumb{display:inline-flex;align-items:center;gap:7px;text-decoration:none;
  font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;color:var(--pg-fg-2);transition:color .2s}
.bl-crumb:hover{color:var(--pg-accent)}
.bl-crumb svg{width:13px;height:13px}
.bl-read::before{content:"/";margin-right:16px;color:var(--pg-line)}
.bl-utility>.bl-read::before{content:none} /* posts without a crumb keep a bare read time */
/* narrow screens: the bar can't fit worded buttons — collapse them to icons */
@media(max-width:560px){
  .bl-crumb,.bl-read{white-space:nowrap}
  .bl-share-word,.bl-theme-word{display:none}
  .bl-btn{padding:9px}
}

/* ---- post grid: toc on the left, article at a ~78-char measure ----
   740px at 18px ≈ 75–80 characters a line, matching the OpenAI reference Jake
   pointed at; the sidebar stays flush with the wrap/nav edge. */
.bl-grid{--bl-aside:260px;--bl-gap:72px;
  display:grid;grid-template-columns:var(--bl-aside) minmax(0,740px);gap:var(--bl-gap);
  justify-content:flex-start}
.bl-side{position:sticky;top:130px;align-self:start}

/* author sits in the post header, under the title */
.bl-author{display:inline-flex;align-items:center;gap:14px;margin-top:28px;text-align:left}
.bl-author img{width:56px;height:56px;border-radius:50%;object-fit:cover}
.bl-author .bl-who{font-size:1rem;font-weight:700;line-height:1.35}
.bl-author .bl-who span{display:block;font-family:'IBM Plex Mono',monospace;font-weight:400;
  font-size:0.75rem;color:var(--pg-fg-2);margin-top:4px}

/* main.css styles bare <nav> as a flex row (the site nav) — restore block flow here */
.bl-toc{display:block;height:auto}
.bl-toc h4{font-family:'IBM Plex Mono',monospace;font-weight:500;font-size:0.75rem;
  letter-spacing:.14em;text-transform:uppercase;color:var(--pg-fg-2);margin:0 0 14px}
.bl-toc a{display:block;padding:6px 0 6px 14px;font-size:0.875rem;line-height:1.4;
  color:var(--pg-fg-2);border-left:2px solid var(--pg-line);transition:color .2s,border-color .2s}
.bl-toc a:hover{color:var(--pg-accent)}
.bl-toc a.on{color:var(--pg-fg);border-left-color:var(--pg-accent)}

/* ---- article body ---- */
.bl-body{font-size:1.125rem;line-height:1.68;color:var(--pg-fg)}
.bl-body>*:first-child{margin-top:0}
.bl-body p{margin:0 0 1.4em}
.bl-body h2{font-family:var(--sans);font-weight:700;font-size:1.6875rem;letter-spacing:-0.02em;
  margin:2.2em 0 .6em;scroll-margin-top:110px}
.bl-body a{color:var(--pg-accent);text-decoration:underline;text-underline-offset:3px}
.bl-body ul{margin:0 0 1.4em;padding-left:22px}
.bl-body li{margin-bottom:.5em}
.bl-body blockquote{margin:2em 0;padding-left:20px;border-left:3px solid var(--pg-accent);
  color:var(--pg-fg-2);font-size:1.25rem}
.bl-standfirst{font-size:1.3125rem;line-height:1.55;color:var(--pg-fg-2);font-style:italic}
.bl-body figure{margin:2.2em 0}
.bl-body figure img,.bl-body figure video{display:block;width:100%;border-radius:12px;
  border:1px solid var(--pg-line)}
.bl-body figcaption{margin-top:12px;font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;
  color:var(--pg-fg-2);line-height:1.55}
.bl-figpair img+img{margin-top:14px}

/* ---- article media breaks out of the reading measure (Medium-style) ----
   The post grid is left-justified, so the article column sits 332px (sidebar + gap)
   in from the wrap's left edge with the TOC beside it. A viewport-centred breakout
   (as the work pages use, where the article is centred) would collide with the
   sticky sidebar, so post media instead stays flush with the text on the left and
   extends rightward to the nav/wrap edge — the same --wide measure everything else
   lines up to. max(100%, …) means it only ever grows: as the viewport narrows and
   the article column shrinks, the breakout closes to zero and media is full-column
   again (and below 820px, where the sidebar is gone, plain 100% wins). */
body[data-page="post"] .bl-body figure{
  width:max(100%,calc(var(--wide) - var(--bl-aside) - var(--bl-gap)))}

/* paired shots go side-by-side at the wider measure, caption spanning both */
body[data-page="post"] .bl-body figure.bl-figpair{display:grid;
  grid-template-columns:1fr 1fr;gap:14px}
body[data-page="post"] .bl-figpair img+img{margin-top:0}
body[data-page="post"] .bl-figpair figcaption{grid-column:1/-1}
@media(max-width:640px){
  body[data-page="post"] .bl-body figure.bl-figpair{grid-template-columns:1fr}
  body[data-page="post"] .bl-figpair img+img{margin-top:14px}}

/* ---- end-of-post CTA: tone-matched panel (card tone on paper, raised panel on
   dark) so the page reads as one calm surface into the footer — the orange button
   is the only loud thing, which is the point of it ---- */
.bl-cta{margin:70px 0 0;padding:52px clamp(28px,6vw,60px);
  border-radius:18px;background:var(--pg-card);border:1px solid var(--pg-line);
  color:var(--pg-fg);text-align:left}
.bl-cta .bl-cta-kicker{font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;color:var(--pg-accent)}
.bl-cta h2{font-family:var(--sans);font-weight:800;font-size:clamp(1.625rem,3.4vw,2.375rem);
  letter-spacing:-0.03em;line-height:1.08;margin:14px 0 12px}
.bl-cta p{font-size:1.125rem;line-height:1.6;color:var(--pg-fg-2);max-width:46ch;margin:0 0 28px}
.bl-cta .btn-talk{display:inline-flex}

/* ---- more from the blog: hairline rows after the CTA — date left, title right,
   each row hovers in its own post's accent (the index spine rule) ---- */
.bl-more{margin:70px 0 0}
.bl-more h3{font-family:var(--sans);font-weight:700;font-size:1.375rem;letter-spacing:-0.02em;
  margin:0 0 18px}
.bl-more a{--en-acc:var(--acc,var(--pg-accent));--en-acc-lg:var(--acc,var(--pg-accent));
  display:grid;grid-template-columns:150px 1fr;gap:28px;align-items:baseline;
  padding:20px 0;border-top:1px solid var(--pg-line);text-decoration:none}
[data-theme="light"] .bl-page .bl-more a{--en-acc:var(--acc-aa,var(--pg-accent));--en-acc-lg:var(--acc-lg,var(--acc-aa,var(--pg-accent)))}
.bl-more a:last-of-type{border-bottom:1px solid var(--pg-line)}
.bl-more time{font-family:'IBM Plex Mono',monospace;font-size:0.8125rem;color:var(--pg-fg-2)}
.bl-more-title{font-family:var(--sans);font-weight:700;font-size:1.1875rem;letter-spacing:-0.01em;
  line-height:1.3;color:var(--pg-fg);transition:color .2s}
.bl-more a:hover .bl-more-title{color:var(--en-acc-lg)}
.bl-more-title svg{width:15px;height:15px;margin-left:9px;vertical-align:-2px;
  opacity:0;transform:translateX(-6px);transition:opacity .2s,transform .2s}
.bl-more a:hover .bl-more-title svg{opacity:1;transform:none}
.bl-more a:focus-visible{outline:2px solid var(--en-acc);outline-offset:3px}
@media(prefers-reduced-motion:reduce){
  .bl-more-title svg{transition:none;transform:none}
}
@media(max-width:640px){
  .bl-more a{grid-template-columns:1fr;gap:6px}
}

@media(max-width:1100px){
  .bl-grid{grid-template-columns:minmax(0,1fr)}
  .bl-side{display:none}
}

/* ---- footer on blog pages ----
   The giant scrolling wordmark is populated by home.js, which blog pages don't
   load — so .foot-marquee is just an empty band framed by its own border plus the
   footer's top border (the "double keyline"). Drop it; one clean keyline remains.
   The marquee also carried the footer's top breathing room, so restore that on
   the footer itself now that foot-top is the first child. */
.bl-page .foot-marquee{display:none}
/* the black footer basement (matches main.css); light mode re-pins to paper below */
.bl-page footer{padding-top:clamp(60px,7vw,88px);border-top:1px solid var(--line);background:var(--black)}
/* Light mode: re-pin the global tokens the footer reads (same trick as #labsPortal
   above) so the whole slab flips to paper instead of slamming into black. */
[data-theme="light"] .bl-page footer{
  --fg:#17171c;
  --fg-2:#5e5b53;
  --line:rgba(23,23,28,.13);
  --bg-2:var(--paper-2);
  background:var(--bg-2);
}
/* the accreditation marks are white cuts, so light mode inverts them to ink
   (same treatment as the services client logos) */
[data-theme="light"] .bl-page .foot-accred-logos img{filter:grayscale(1) invert(1)}
