/* =============================================================
   Bud blog — EDITORIAL BODY SYSTEM
   From the "Bud Blog Template Options" handoff (Claude Design,
   direction 1c "image-led overlap"), reconciled to design-guide
   §09 v1.2 before implementation.

   It REPLACES the whitepaper-document typography that used to live
   in blog.css §2 — those rules were deleted rather than overridden,
   so nothing here needs !important and there is one owner per rule.
   blog.css now carries the INDEX only (category palette, grid,
   filters, byline) plus the light-band category tones.

   LOAD ORDER
     tokens.css → site.css → news-cards.css → blog.css →
     blog-body.css → v12.css (always last, see §09)

   WHAT WAS CHANGED FROM THE HANDOFF, AND WHY
   The handoff is written against v1.1: literal radii (8/12/14/20/999),
   700-weight headings, mono labels. v1.2 shipped site-wide on 31 Jul,
   so every one of those had to move or the blog would have landed as
   the only unconverted surface on the site. Three rules cover it:

     1. RADIUS IS A TOKEN, NEVER A LITERAL (§07 checklist). Every
        radius below is var(--radius-*), so the §09 R2 purge reaches
        this file for free and it needs no R2c sweep entry. The
        handoff's literals map straight across:
          8px → --radius-md    12px → --radius-lg
          14px → --radius-xl   20px → --radius-2xl   999px → --radius-pill
        The two exceptions stay LITERAL 50%, deliberately: the author
        portraits. A circular portrait is a photograph, not a card.
     2. HEADING WEIGHT (R1). The handoff's h2/700 h3/600 become
        500/500. h2 sets at 31px, which is display scale (30px+), so
        it takes the full -.03em rather than -.02em. The pull quote
        came down to 500 too — at 25px/600 it outweighed the 31px h2
        above it, which is the exact inversion R1 exists to prevent.
        NUMERALS KEEP 700: .bp-stats .v is the one thing that should
        still shout after the headings stop.
     3. LABELS ARE MONTSERRAT AT 11.5/600/.15em (R1b M1c + R1).
        The handoff's 11/700/.16em is the v1.1 mono spec. Mono
        survives in exactly one place on this page — the code block —
        and it uses --font-code (IBM Plex Mono), not --font-mono,
        which now resolves to Montserrat.

   SCOPING
     .blog-post  on the light <section> — shell overrides only.
                 .article-layout / .article-aside / .share-btn are
                 SHARED with /company/news, so every override of them
                 is scoped to this class and cannot reach the newsroom.
     .bp-doc     everything else.
   ============================================================= */

/* ---------- 01 · SHELL ------------------------------------- */
/* 720px measure + 188px rail. Wider than the old 690px document
   because body copy went 16.5px → 19px; at 19px, 720px is ~76
   characters, which is the same reading comfort by a different route. */
.blog-post .article-layout{
  grid-template-columns: minmax(0, 720px) 188px;
  justify-content: center;
  gap: 0;
  padding-top: 56px;
}
.blog-post .article-aside{ top: 32px; padding-left: 48px; }
.blog-post .share-btn{ font-size: 14px; font-weight: var(--fw-medium); }
.blog-post .share-btn:hover{ background: var(--surface-elev); }

.bp-doc{
  /* Document tokens. Deliberately NOT re-declaring --bg/--surface:
     the light band already resolves those to #FFFFFF / #FAF7FE, so
     the article inherits the band instead of painting over it. */
  --ink:#0A0712; --ink-2:#3D3450; --ink-3:#6B6080;
  --rule:rgba(76,29,149,.15); --rule-2:rgba(76,29,149,.10);
  --doc-accent:#6D28D9; --doc-accent-strong:#4C1D95;

  width: 100%; max-width: 720px; min-width: 0;
  color: var(--ink);
}

@media (max-width: 1100px){
  .blog-post .article-layout{ grid-template-columns: minmax(0, 1fr); }
  .blog-post .article-aside{ position: static; padding: 32px 0 0; }
  .blog-post .share-btns{ flex-direction: row; flex-wrap: wrap; }
}

/* ---------- 02 · HERO FIGURE + THE SEAM --------------------- */
/* The key visual straddles the dark/light seam. The header's bottom
   padding reacts to the figure's PRESENCE, so there is no flag to
   keep in sync — delete the <figure> and the band closes flush. */
.blog-post-hero{ padding-bottom: 56px; }
/* ── POST HERO BACKGROUND ─────────────────────────────────────────────
   The same treatment the homepage banner uses: one dense static lattice
   and one slow light, in place of the <bud-grid> pixel field that used
   to sit here. That motif animated ~1,600 squares on their own 3.6s
   cycles behind the headline; a post banner is something you read past,
   not something that should be moving.

   Painted on .hero-bg, which is already absolute/inset-0/z-index-0 under
   .page-hero, so the markup is just an empty <div class="hero-bg"></div>
   and there is no per-post seed to allocate any more.

   --bh-line is how present the grid is, --bh-cell how dense. Values match
   assets/css/home-hero-carousel.css's grid variant so the two banners
   read as the same surface.
   ──────────────────────────────────────────────────────────────────── */
.blog-post-hero{
  --bh-cell:18px;                      /* grid pitch */
  --bh-line:rgba(183,133,244,.10);     /* how present the grid is */
  --bh-lw:1px;                         /* line width */
  --bh-glow:.15;                       /* ambient lift under the lattice */
  --bh-light:.30;                      /* the drifting light */
  --bh-speed:37s;                      /* drift cycle; 0s stops it */
}
.blog-post-hero .hero-bg::before,
.blog-post-hero .hero-bg::after{
  content:""; position:absolute; pointer-events:none;
}
/* the grid — static, it is the surface the band sits on */
.blog-post-hero .hero-bg::before{
  inset:0;
  /* lattice first (paints on top), then the broad ambient glow beneath it.
     The homepage gets that glow from a separate .hc-glow div; the post banner
     has no such element, and without it the band stayed flat #0A0712 and the
     lines had nothing to read against. Same values as .hc-glow. */
  background-image:
    linear-gradient(to right,  var(--bh-line) var(--bh-lw), transparent var(--bh-lw)),
    linear-gradient(to bottom, var(--bh-line) var(--bh-lw), transparent var(--bh-lw)),
    radial-gradient(85% 90% at 50% 26%, rgba(140,51,239,var(--bh-glow)), transparent 68%);
  background-size:var(--bh-cell) var(--bh-cell), var(--bh-cell) var(--bh-cell), cover;
}
/* the light — two soft sources in one layer so it never reads as a single
   travelling blob; no blur filter, the gradients are already feathered */
.blog-post-hero .hero-bg::after{
  inset:-10% -8%;
  background:
    radial-gradient(58% 62% at 50% 88%, rgba(140,51,239,var(--bh-light)), transparent 72%),
    radial-gradient(36% 40% at 82% 6%,  rgba(109,40,217,calc(var(--bh-light) * .66)), transparent 74%);
  will-change:transform,opacity;
  animation:bhLight var(--bh-speed) cubic-bezier(.4,0,.2,1) infinite;
}
@keyframes bhLight{
  0%,100%{ transform:translate3d(0,6%,0)    scale(1);    opacity:.55 }
  50%    { transform:translate3d(-3%,-8%,0) scale(1.12); opacity:.9  }
}
@media (prefers-reduced-motion:reduce){
  .blog-post-hero .hero-bg::after{ animation:none; opacity:.7; }
}

.blog-post-hero:has(+ .blog-post .bp-hero){ padding-bottom: 150px; }
@supports not selector(:has(*)){
  .blog-post-hero.has-hero{ padding-bottom: 150px; }
}

/* The band's own top padding works against BOTH layouts, so it goes in
   both. With a key visual it cancels most of the figure's -110px pull —
   the figure lands ON the seam instead of across it, which is not the
   same picture. Without one it stacks on top of .article-layout's 56px
   and opens a ~120px void between the seam and the first line of text.
   Zero it either way and .article-layout owns the gap on its own: 56px
   under the seam on a plain post, 56px under the figure on an illustrated
   one. One rule, one owner, nothing below moves. */
.blog-post{ padding-top: 0; }

.blog-post:has(.bp-hero){
  /* .blog-post-hero is position:relative + isolation:isolate, so the whole
     header — motif included — paints as a positioned stacking context, above
     a static band that comes AFTER it in the DOM. The figure's overlapping
     strip loses, and because bud-grid paints on a canvas a frame or two late,
     it loses VISIBLY: the figure shows, then the motif covers it.
     Lift the band, not the figure. A z-index on .bp-hero gets trapped while
     the section is mid scroll-reveal (opacity:0 makes it a stacking context
     of its own), which turns the overlap into a flicker instead of a fix.
     1 clears the header and stays far below the sticky nav's 200. */
  position: relative;
  z-index: 1;
}

.bp-hero{ max-width: 900px; margin: -110px auto 0; }
.bp-hero > .frame{
  height: 430px; border-radius: var(--radius-xl); overflow: hidden;
  /* Restrained from the handoff's 0 30px 60px -20px. The figure needs
     separation from the dark band it overlaps, but a 60px blur under a
     squared corner reads as the v1.1 floating card that R5 retired. */
  box-shadow: 0 18px 40px -18px rgba(0,0,0,.55);
}
.bp-hero > .frame img{ width: 100%; height: 100%; object-fit: cover; display: block; }
.bp-hero figcaption{
  font-size: 13px; line-height: 1.5; color: var(--fg3); padding-top: 11px;
  max-width: 720px; margin: 0 auto;
}

/* ---------- 03 · THE CENTRED HEADER ------------------------- */
/* Direction 1c: tag + H1 + deck + one byline row, centred, 780px.
   Replaces the left-aligned 4-item .art-meta row. */
.art-head{
  max-width: 780px; margin: 0 auto; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 20px;
}
.art-head h1{ margin: 0; font-size: clamp(32px, 4.6vw, 52px); max-width: none; }
.art-head .lede{ margin: 0; font-size: 20px; line-height: 1.55; max-width: 640px; text-wrap: pretty; }
.art-byline{
  display: flex; align-items: center; justify-content: center;
  /* The "·" separators are flex items of their own, so this gap lands on
     BOTH sides of each one — 12px reads as ~28px between name, date and
     read time, which is the air the row wanted once the chip joined it. */
  gap: 12px; flex-wrap: wrap;
  font-size: 13px; color: var(--bud-violet-2, #8577AE);
}
/* The avatar is part of the name, not a fourth item — keep it tucked in
   so the wider gap separates the three meta items and nothing else. */
.art-byline .ba + .an{ margin-left: -4px; }
.art-byline .ba{
  width: 30px; height: 30px; border-radius: 50%;   /* portrait — R2 exception */
  flex: none; object-fit: cover;
  background: var(--accent-muted); border: 1px solid var(--border-strong);
  display: grid; place-items: center;
  font-size: 10px; font-weight: var(--fw-bold); color: var(--bud-electric-3, #D9BAF9);
}
.art-byline .an{ color: var(--fg1); font-weight: var(--fw-semibold); }
/* The category chip rides the byline instead of owning a row of its own —
   the chip's height plus one 20px .art-head gap, ~44px off every post hero.
   It trails the row so the author reads first. No "·" before it: it is
   already a bordered object, and a separator against a box reads as
   punctuation inside the box. The margin does that job instead.
   /company/news is untouched — it runs the chip in its own .art-meta row,
   which has never had a byline to merge into. */
.art-byline .art-tag{ margin-left: 5px; }
.blog-post-hero .crumbs{ margin-bottom: 56px; }

/* ---------- 04 · TEXT -------------------------------------- */

/* Opening stand-first. One per post, first thing in the column. */
.bp-doc .bp-lead{
  margin: 0 0 26px;
  font-size: 22px; line-height: 1.6; font-weight: var(--fw-medium);
  color: var(--ink); text-wrap: pretty;
}

/* Running body. 19px/1.72 is the editorial default and the whole point
   of the revision — do not drop it below 18px. */
.bp-doc p{
  margin: 0 0 24px;
  font-size: 19px; line-height: 1.72; color: var(--ink-2);
  text-wrap: pretty;
}
.bp-doc strong{ font-weight: var(--fw-semibold); color: var(--ink); }
.bp-doc em{ font-style: italic; }

/* Section head. NO .sec-no numbering — retired for the blog, which is
   the one tier where a numbered section reads as a document rather
   than an article. 31px is display scale, hence -.03em (R1). */
.bp-doc h2{
  margin: 44px 0 16px;
  font-size: 31px; font-weight: var(--fw-medium);
  letter-spacing: -.03em; line-height: 1.18;
  color: var(--ink); text-wrap: balance;
}
.bp-doc h3{
  margin: 30px 0 12px;
  font-size: 22px; font-weight: var(--fw-medium);
  letter-spacing: -.01em; line-height: 1.3;
  color: var(--ink);
}
.bp-doc h2 + h3{ margin-top: 20px; }

.bp-doc a{
  color: var(--doc-accent); text-decoration: underline;
  text-decoration-color: rgba(109,40,217,.35); text-underline-offset: 3px;
}
.bp-doc a:hover{ color: var(--doc-accent-strong); text-decoration-color: currentColor; }

/* Shared label treatment for every uppercase micro-label in the
   document. v1.2 spec: Montserrat, 11.5px, 600, .15em. */
.bp-doc .co-label,
.bp-doc .tk-label,
.bp-doc .ft,
.bp-doc .bp-cols .col .lbl,
.bp-doc .bp-paper .pl,
.bp-doc .bp-cta-inline .cl,
.bp-doc .bp-foot .al{
  font-family: var(--font-sans);
  font-size: 11.5px; font-weight: var(--fw-semibold);
  letter-spacing: .15em; text-transform: uppercase;
}

/* ---------- 05 · LISTS ------------------------------------- */

/* THE MARKER IS ABSOLUTELY POSITIONED, NOT A FLEX ITEM — and that is a
   correction to the handoff, not a preference. The handoff sets
   `li{display:flex; gap:14px}` with the bullet as ::before, which is fine
   for an item of bare text but breaks the moment one contains inline
   markup: every inline element (<code>, <a>, <strong>) becomes its OWN
   flex item, so the line lays out as a non-wrapping row instead of
   wrapping prose. Caught on the web-fetch post, where a single
   <code>docs.example.com</code> pushed its list item 434px past the
   container and the whole page scrolled sideways. Padding + an absolute
   marker keeps the <li> a normal block, so inline content flows. */
.bp-doc .bp-list,
.bp-doc ul:not(.bp-takeaways ul):not(.bp-cols ul){
  margin: 0 0 26px; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 12px;
}
.bp-doc .bp-list > li,
.bp-doc ul:not(.bp-takeaways ul):not(.bp-cols ul) > li{
  position: relative; padding-left: 20px;
  font-size: 19px; line-height: 1.65; color: var(--ink-2);
}
.bp-doc .bp-list > li::before,
.bp-doc ul:not(.bp-takeaways ul):not(.bp-cols ul) > li::before{
  content: ""; position: absolute; left: 0; top: .62em;
  width: 6px; height: 6px; border-radius: var(--radius-pill);
  background: var(--bud-electric);
}

/* Numbered steps — replaces .bp-phases. Numbers come from a CSS
   counter, never typed. The marker is a numeral BADGE, not a control,
   so it squares under v1.2 (same call as .promo-card .icon-badge).
   Absolute for the same reason as the bullets above: every step item
   opens with a <strong> clause. */
.bp-doc .bp-steps{
  margin: 0 0 30px; padding: 0; list-style: none;
  counter-reset: bpstep;
  display: flex; flex-direction: column; gap: 18px;
}
.bp-doc .bp-steps > li{
  position: relative; padding-left: 44px; min-height: 28px;
  font-size: 19px; line-height: 1.68; color: var(--ink-2);
  counter-increment: bpstep;
}
.bp-doc .bp-steps > li::before{
  content: counter(bpstep); position: absolute; left: 0; top: 2px;
  width: 28px; height: 28px; border-radius: var(--radius-pill);
  background: rgba(109,40,217,.10); color: var(--doc-accent);
  font-size: 13px; font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: center;
}

/* ---------- 06 · PULL QUOTE -------------------------------- */
/* 500, not the handoff's 600: at 25px a 600 quote outweighs the 31px
   h2 above it, and R1 is precisely about not letting smaller type
   carry more mass than the heading it sits under. */
.bp-doc .bp-quote{
  margin: 20px 0 36px; padding: 0 0 0 26px;
  border-left: 2px solid var(--bud-electric);
}
.bp-doc .bp-quote p{
  margin: 0;
  font-size: 25px; line-height: 1.42;
  font-weight: var(--fw-medium); letter-spacing: -.015em;
  color: var(--ink); text-wrap: pretty;
}
.bp-doc .bp-quote cite{
  display: block; margin-top: 14px; font-style: normal;
  font-size: 13px; color: var(--ink-3);
}

/* ---------- 07 · CALLOUT ----------------------------------- */

.bp-doc .bp-callout{
  margin: 14px 0 34px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left: 2px solid var(--doc-accent);
  border-radius: 0 var(--radius-xl) var(--radius-xl) 0;
  padding: 22px 24px;
}
.bp-doc .bp-callout .co-label{
  display: flex; align-items: center; gap: 8px;
  color: var(--doc-accent); margin-bottom: 10px;
}
.bp-doc .bp-callout .co-label i,
.bp-doc .bp-callout .co-label svg{ width: 14px; height: 14px; }
.bp-doc .bp-callout p{ margin: 0 0 12px; font-size: 17px; line-height: 1.66; color: var(--ink); }
.bp-doc .bp-callout p:last-child{ margin-bottom: 0; }
.bp-doc .bp-callout ul{ margin: 0; gap: 9px; }
.bp-doc .bp-callout ul > li{ font-size: 16px; line-height: 1.6; padding-left: 18px; }
.bp-doc .bp-callout ul > li::before{ top: .58em; }
/* Carried over from the old system — the handoff does not mention the
   two modifiers, but shipped posts use them and they are a legitimate
   distinction (supporting evidence vs. a caveat). */
.bp-doc .bp-callout--key{ background: linear-gradient(100deg, rgba(140,51,239,.08), rgba(140,51,239,.02)); }
.bp-doc .bp-callout--warn{ border-left-color: var(--bud-amber); }
.bp-doc .bp-callout--warn .co-label{ color: #9A7400; }

/* ---------- 08 · STAT BAND --------------------------------- */
/* Replaces .bp-duo as well: auto-fit takes 2 or 3 without a modifier. */
.bp-doc .bp-stats{
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1px; background: var(--rule);
  border: 1px solid var(--rule); border-radius: var(--radius-xl);
  overflow: hidden; margin: 14px 0 34px;
}
.bp-doc .bp-stats .s{ background: var(--surface); padding: 26px 24px; }
.bp-doc .bp-stats .v{
  font-size: 46px; font-weight: var(--fw-bold);   /* numerals keep 700 — R1 */
  letter-spacing: -.03em; line-height: 1;
  color: var(--doc-accent); font-variant-numeric: tabular-nums;
}
.bp-doc .bp-stats .v em,
.bp-doc .bp-stats .v span{ font-style: normal; font-size: 26px; font-weight: var(--fw-semibold); }
.bp-doc .bp-stats .l{ font-size: 14px; line-height: 1.5; color: var(--ink-2); margin-top: 10px; }

/* ---------- 09 · TABLES ------------------------------------ */

.bp-doc .bp-table{
  margin: 0 0 14px;
  border: 1px solid var(--rule); border-radius: var(--radius-xl);
  overflow: hidden; overflow-x: auto;
}
.bp-doc table.bp-data{ width: 100%; border-collapse: collapse; font-size: 15px; }
.bp-doc table.bp-data thead tr{ background: var(--surface-elev); }
.bp-doc table.bp-data th{
  padding: 13px 18px;
  font-family: var(--font-sans);
  font-size: 11.5px; font-weight: var(--fw-semibold);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--doc-accent-strong);
  border-bottom: 1px solid var(--rule);
  text-align: right; white-space: nowrap;
}
.bp-doc table.bp-data th:first-child{ text-align: left; }
.bp-doc table.bp-data td{
  padding: 13px 18px; color: var(--ink);
  border-bottom: 1px solid var(--rule-2);
  text-align: right; font-variant-numeric: tabular-nums; vertical-align: top;
}
.bp-doc table.bp-data td:first-child{ text-align: left; color: var(--ink-2); }
.bp-doc table.bp-data tbody tr:last-child td{ border-bottom: 0; }
.bp-doc table.bp-data tfoot td{ padding-top: 13px; font-size: 13px; color: var(--ink-3); font-style: italic; text-align: left; }

/* Comparison matrix — left-aligned prose, "next" column tinted. */
.bp-doc table.bp-data.is-prose th,
.bp-doc table.bp-data.is-prose td{
  text-align: left; font-variant-numeric: normal;
  line-height: 1.55; padding: 15px 18px;
}
.bp-doc table.bp-data.is-prose td:first-child{ font-weight: var(--fw-semibold); color: var(--ink); }
.bp-doc table.bp-data.is-prose .is-now,
.bp-doc table.bp-data.is-prose th.is-now{ color: var(--ink-3); }
.bp-doc table.bp-data.is-prose .is-next{ background: rgba(109,40,217,.04); color: var(--ink-2); }

/* Caption sits BELOW the table, as a numbered label. */
.bp-doc .bp-caption{
  margin: 0 0 34px; font-size: 13px; line-height: 1.5; color: var(--ink-3);
}

/* ---------- 10 · FIGURES ----------------------------------- */

.bp-doc figure{ margin: 6px 0 34px; }
.bp-doc figcaption{ font-size: 13px; line-height: 1.5; color: var(--ink-3); padding-top: 11px; }
.bp-doc figcaption strong{ color: var(--ink); }

.bp-doc .bp-figure-frame{
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius-xl); padding: 26px 26px 20px;
}
.bp-doc .bp-figure-frame .ft{ color: var(--ink-3); margin-bottom: 20px; }
.bp-doc .bp-figure-frame svg{ display: block; width: 100%; height: auto; }

/* Inline image — screenshots run straight. No device frame, no shadow. */
.bp-doc .bp-figure-img{
  border-radius: var(--radius-xl); overflow: hidden; border: 1px solid var(--rule);
}
.bp-doc .bp-figure-img img{ width: 100%; height: auto; display: block; }
/* Portrait source art. A 2:3 diagram run to the full 720px measure is over
   1000px tall and pushes the caption off-screen on a laptop — cap it and
   centre it instead of letting the column dictate the height. */
.bp-doc .bp-figure-img.is-portrait{ max-width: 440px; margin-inline: auto; }

/* In-article walkthrough video. Click-to-play: nothing is requested from
   YouTube until the reader asks, and initTheater() in site.js does the
   swap — it selects .th-screen[data-yt] anywhere on the page, so the
   button keeps that class and no new JS is needed. The brief tier's own
   .theater blade is a full-width page band and its CSS lives in
   brief.css, which a post does not load; these rules are the in-column
   equivalent and are scoped to .bp-doc so the two cannot collide. */
.bp-doc .bp-video-stage{
  position: relative; aspect-ratio: 16 / 9; overflow: hidden;
  border: 1px solid var(--rule); border-radius: var(--radius-xl);
  background: linear-gradient(165deg, #191330, var(--bud-midnight-purple) 62%);
}
.bp-doc .bp-video-stage iframe{ position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.bp-doc .bp-video-stage .th-screen{
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; padding: 0; border: 0; background: transparent; font: inherit; cursor: pointer;
}
.bp-doc .bp-video-stage .play-badge{
  width: 72px; height: 72px; border-radius: var(--radius-pill);
  background: rgba(10,7,18,.72); border: 1px solid rgba(255,255,255,.22);
  display: flex; align-items: center; justify-content: center; color: #fff;
  transition: transform var(--duration-md) var(--ease-out-expo), background var(--duration-md);
}
.bp-doc .bp-video-stage .play-badge i,
.bp-doc .bp-video-stage .play-badge svg{ width: 26px; height: 26px; margin-left: 3px; }
.bp-doc .bp-video-stage .th-screen:hover .play-badge,
.bp-doc .bp-video-stage .th-screen:focus-visible .play-badge{
  transform: scale(1.08); background: var(--bud-electric);
}
.bp-doc .bp-video-stage .th-cue{
  font-size: 13px; letter-spacing: .02em; color: rgba(255,255,255,.72);
}
@media (max-width: 560px){
  .bp-doc .bp-video-stage .play-badge{ width: 58px; height: 58px; }
  .bp-doc .bp-video-stage .play-badge i,
  .bp-doc .bp-video-stage .play-badge svg{ width: 21px; height: 21px; }
}

/* House two-series bar chart */
.bp-doc .bp-bars{ display: flex; flex-direction: column; gap: 16px; }
.bp-doc .bp-bars .row{ display: flex; align-items: center; gap: 14px; }
.bp-doc .bp-bars .row .k{ width: 118px; flex: none; font-size: 14px; color: var(--ink-2); }
.bp-doc .bp-bars .row .track{
  flex: 1; height: 14px; border-radius: var(--radius-pill);
  background: rgba(76,29,149,.08); overflow: hidden;
}
.bp-doc .bp-bars .row .fill{
  display: block; height: 100%; border-radius: var(--radius-pill);
  background: var(--bud-electric);
}
.bp-doc .bp-bars .row.is-muted .fill{ background: #8577AE; }
/* .is-ours carried over from the old chart — the author's own series gets
   the label in accent, which is how the shipped economics post distinguishes
   Bud's number from the market range it sits inside. */
.bp-doc .bp-bars .row.is-ours .k{ color: var(--doc-accent); font-weight: var(--fw-semibold); }
.bp-doc .bp-bars .row .n{
  width: 52px; flex: none; text-align: right;
  font-size: 14px; font-weight: var(--fw-semibold); color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* Routing / flow diagram — carried over, restyled to the new scale. */
.bp-doc .bp-flow{ display: grid; grid-template-columns: 1fr auto 1fr; gap: 16px; align-items: center; }
.bp-doc .bp-flow.is-5{ grid-template-columns: 1fr auto 1.15fr auto 1fr; gap: 12px; }
.bp-doc .bp-flow .fl-node{
  border: 1px solid var(--rule-2); border-radius: var(--radius-xl);
  background: var(--bg); padding: 14px 16px;
}
.bp-doc .bp-flow .fl-node .t{ font-size: 13.5px; font-weight: var(--fw-semibold); color: var(--ink); }
.bp-doc .bp-flow .fl-node .d{ font-size: 12px; color: var(--ink-3); margin-top: 5px; line-height: 1.45; }
.bp-doc .bp-flow .fl-node .tag{
  font-family: var(--font-sans); font-size: 10px; letter-spacing: .15em;
  text-transform: uppercase; color: var(--doc-accent);
  font-weight: var(--fw-semibold); display: block; margin-bottom: 5px;
}
.bp-doc .bp-flow .fl-node.is-core{
  border-color: var(--bud-electric); border-width: 2px;
  background: linear-gradient(140deg, rgba(140,51,239,.08), rgba(140,51,239,.02));
}
.bp-doc .bp-flow .fl-node.is-core .t{ color: var(--doc-accent); }
.bp-doc .bp-flow .fl-arrow{ color: var(--bud-electric); font-size: 17px; line-height: 1; }
.bp-doc .bp-flow .fl-stack{ display: flex; flex-direction: column; gap: 10px; }

/* Step chain — a wrapping row of tool/stage nodes. */
.bp-doc .bp-chain{ display: flex; align-items: stretch; flex-wrap: wrap; gap: 10px; }
.bp-doc .bp-chain .ch-node{
  flex: 1 1 118px; min-width: 112px;
  border: 1px solid var(--rule-2); border-top: 2px solid var(--bud-electric);
  border-radius: var(--radius-xl); background: var(--bg); padding: 12px 13px;
}
.bp-doc .bp-chain .ch-node .s{
  font-family: var(--font-sans); font-size: 10px; letter-spacing: .15em;
  text-transform: uppercase; color: var(--doc-accent); font-weight: var(--fw-semibold);
}
.bp-doc .bp-chain .ch-node .t{ font-size: 13.5px; font-weight: var(--fw-semibold); color: var(--ink); margin-top: 6px; line-height: 1.25; }
.bp-doc .bp-chain .ch-node .d{ font-size: 12px; color: var(--ink-3); margin-top: 5px; line-height: 1.45; }

/* ---------- 11 · COLUMN CARDS ------------------------------ */
/* The handoff retires .bp-cols with no replacement, but three shipped
   posts use it for labelled side-by-side card sets — an audience split,
   a good/bad pair — which no other block in the new set expresses.
   Deleting it would have meant rewriting reader content to fit the
   stylesheet, so it is carried forward at the new scale instead. */
.bp-doc .bp-cols{ display: grid; gap: 14px; margin: 20px 0 34px; }
.bp-doc .bp-cols.is-2{ grid-template-columns: 1fr 1fr; }
.bp-doc .bp-cols.is-3{ grid-template-columns: repeat(3, 1fr); }
.bp-doc .bp-cols .col{
  border: 1px solid var(--rule); border-top: 3px solid var(--bud-electric);
  border-radius: var(--radius-xl); padding: 20px 22px; background: var(--surface);
}
.bp-doc .bp-cols .col.is-bad{ border-top-color: var(--bud-alert); }
.bp-doc .bp-cols .col .lbl{ color: var(--doc-accent); margin-bottom: 10px; }
.bp-doc .bp-cols .col.is-bad .lbl{ color: var(--bud-alert); }
.bp-doc .bp-cols .col h3{ margin: 0 0 9px; font-size: 17px; }
.bp-doc .bp-cols .col p{ font-size: 15px; line-height: 1.6; margin: 0 0 10px; }
.bp-doc .bp-cols .col p:last-child{ margin-bottom: 0; }
.bp-doc .bp-cols .col ul{
  margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 9px;
}
.bp-doc .bp-cols .col ul > li{
  position: relative; padding-left: 16px;
  font-size: 14.5px; line-height: 1.6; color: var(--ink-2);
}
.bp-doc .bp-cols .col ul > li::before{
  content: ""; position: absolute; left: 0; top: .6em;
  width: 5px; height: 5px;
  border-radius: var(--radius-pill); background: var(--bud-electric);
}

/* ---------- 12 · CODE ------------------------------------- */
/* Code stays DARK inside the light band — it reads as a terminal and
   matches the developer materials elsewhere on the site.
   --font-code, NOT --font-mono: under M1c the mono token resolves to
   Montserrat, and code is the one surface that still wants a real
   monospace. The fallback keeps this file correct off the v12 scope. */
.bp-doc .bp-code{
  margin: 0 0 34px;
  background: var(--bud-midnight); border: 1px solid rgba(183,133,244,.15);
  border-radius: var(--radius-lg); overflow: hidden;
}
.bp-doc .bp-code .cb-bar{
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 16px; border-bottom: 1px solid rgba(183,133,244,.15);
}
.bp-doc .bp-code .cb-file{
  font-family: var(--font-code, var(--font-mono)); font-size: 12px; color: #8577AE;
}
.bp-doc .bp-code .cb-copy{
  font-family: var(--font-sans);
  font-size: 11px; font-weight: var(--fw-semibold);
  letter-spacing: .1em; text-transform: uppercase;
  color: #6B6080; background: none; border: 0; cursor: pointer; padding: 0;
}
.bp-doc .bp-code .cb-copy:hover{ color: var(--bud-electric-2); }
.bp-doc .bp-code pre{
  margin: 0; padding: 18px 16px; overflow-x: auto;
  font-family: var(--font-code, var(--font-mono));
  font-size: 13.5px; line-height: 1.75; color: var(--bud-haze);
}
.bp-doc .bp-code .tok-key{ color: var(--bud-electric-2); }
.bp-doc .bp-code .tok-comment{ color: #6B6080; }

/* Inline code inside prose */
.bp-doc p code, .bp-doc li code, .bp-doc td code{
  font-family: var(--font-code, var(--font-mono)); font-size: .88em;
  background: var(--surface-elev); border: 1px solid var(--rule);
  border-radius: var(--radius-xs); padding: 1px 5px;
  color: var(--doc-accent-strong);
}

/* ---------- 13 · TAKEAWAYS -------------------------------- */

.bp-doc .bp-takeaways{
  margin: 20px 0 30px;
  border: 1px solid var(--rule); border-radius: var(--radius-xl);
  padding: 24px 26px;
}
.bp-doc .bp-takeaways .tk-label{ color: var(--doc-accent); margin-bottom: 14px; }
.bp-doc .bp-takeaways ul{
  margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 11px;
}
.bp-doc .bp-takeaways li{
  display: flex; gap: 12px; font-size: 17px; line-height: 1.6; color: var(--ink-2);
}
.bp-doc .bp-takeaways li::before{ content: none; }
.bp-doc .bp-takeaways li i,
.bp-doc .bp-takeaways li svg{
  width: 17px; height: 17px; flex: none; margin-top: 4px; color: var(--doc-accent);
}

/* ---------- 14 · INLINE CTA (dark, one per post max) ------- */

.bp-doc .bp-cta-inline{
  margin: 6px 0 36px;
  background: var(--bud-midnight); border-radius: var(--radius-xl);
  padding: 24px 26px;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
}
.bp-doc .bp-cta-inline .cl{ color: var(--bud-electric-2); margin-bottom: 7px; }
.bp-doc .bp-cta-inline p{
  margin: 0; font-size: 16px; line-height: 1.55;
  color: var(--bud-haze); max-width: 380px;
}
.bp-doc .bp-cta-inline .btn{
  flex: none; display: inline-flex; align-items: center; gap: 8px;
  background: var(--bud-electric); color: #fff;
  font-size: 14px; font-weight: var(--fw-semibold);
  padding: 12px 20px; border-radius: var(--radius-md);
  text-decoration: none; white-space: nowrap;
  transition: background var(--duration-sm) var(--ease-out-expo);
}
.bp-doc .bp-cta-inline .btn:hover{ background: var(--bud-electric-2); }
.bp-doc .bp-cta-inline .btn i{ width: 15px; height: 15px; }

/* ---------- 15 · RELATED WHITE PAPER ---------------------- */

.bp-doc .bp-paper{
  display: flex; align-items: center; gap: 18px; margin: 0 0 30px;
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius-xl); padding: 20px 22px;
  text-decoration: none;
  transition: background var(--duration-sm) var(--ease-out-expo);
}
.bp-doc .bp-paper:hover{ background: var(--surface-elev); }
/* The spine is a document EDGE — never rounded, in either system. */
.bp-doc .bp-paper .sp{
  flex: none; width: 44px; height: 56px; border-radius: 0;
  background: var(--bud-midnight); border: 1px solid rgba(183,133,244,.30);
  display: flex; align-items: center; justify-content: center;
}
.bp-doc .bp-paper .sp i, .bp-doc .bp-paper .sp svg{ width: 20px; height: 20px; color: var(--bud-electric-2); }
.bp-doc .bp-paper > span:last-child{ display: flex; flex-direction: column; gap: 4px; }
.bp-doc .bp-paper .pl{ color: var(--ink-3); }
.bp-doc .bp-paper .pt{ font-size: 17px; font-weight: var(--fw-semibold); color: var(--ink); }
.bp-doc .bp-paper .pd{ font-size: 14px; line-height: 1.5; color: var(--ink-3); }

/* ---------- 16 · NOTE · NEWSLETTER · AUTHOR --------------- */

/* Methodology footnote. Last body element before the newsletter. */
.bp-doc .bp-note{
  margin: 34px 0 0; padding-top: 22px;
  border-top: 1px solid var(--rule);
  font-size: 13.5px; line-height: 1.6; color: var(--ink-3); font-style: italic;
}

.bp-doc .bp-newsletter{
  margin-top: 44px;
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius-xl); padding: 26px;
}
.bp-doc .bp-newsletter .nl-h{
  font-size: 20px; font-weight: var(--fw-semibold); letter-spacing: -.01em;
  color: var(--ink); margin-bottom: 8px;
}
.bp-doc .bp-newsletter p{ margin: 0 0 18px; font-size: 15px; line-height: 1.6; }
.bp-doc .bp-newsletter form{ display: flex; gap: 10px; flex-wrap: wrap; }
.bp-doc .bp-newsletter input{
  flex: 1 1 220px; min-width: 0; background: var(--bg);
  border: 1px solid var(--rule); border-radius: var(--radius-md);
  padding: 12px 14px; font: inherit; font-size: 15px; color: var(--ink);
}
.bp-doc .bp-newsletter button{
  flex: none; background: var(--doc-accent); color: #fff;
  font: inherit; font-size: 15px; font-weight: var(--fw-semibold);
  padding: 12px 22px; border: 0; border-radius: var(--radius-md); cursor: pointer;
  transition: background var(--duration-sm) var(--ease-out-expo);
}
.bp-doc .bp-newsletter button:hover{ background: var(--doc-accent-strong); }
.bp-doc .bp-newsletter .nl-note{ margin: 12px 0 0; font-size: 12.5px; color: var(--ink-3); }

.bp-doc .bp-foot{
  margin-top: 44px; padding-top: 30px;
  border-top: 1px solid var(--rule);
  display: flex; gap: 20px; align-items: flex-start;
}
.bp-doc .bp-foot .ph{
  flex: none; width: 64px; height: 64px;
  border-radius: 50%;                    /* portrait — R2 exception */
  object-fit: cover;
  background: var(--surface-elev); border: 1px solid var(--rule);
  color: var(--doc-accent); font-size: 19px; font-weight: var(--fw-bold);
  display: flex; align-items: center; justify-content: center;
}
.bp-doc .bp-foot .al{ color: var(--ink-3); margin-bottom: 6px; }
.bp-doc .bp-foot .an{ font-size: 19px; font-weight: var(--fw-semibold); color: var(--ink); line-height: 1.2; }
.bp-doc .bp-foot .ar{ font-size: 14px; color: var(--ink-3); margin: 3px 0 10px; }
/* That 10px separates the role from the bio. Bud Newsroom posts have no
   bio — a masthead does not have one — so the role is last and the margin
   would hang as dead space under the card. */
.bp-doc .bp-foot .ar:last-child{ margin-bottom: 0; }
.bp-doc .bp-foot .ab{ margin: 0; font-size: 15px; line-height: 1.65; }

/* ---------- 17 · RESPONSIVE -------------------------------- */

@media (max-width: 860px){
  .bp-doc .bp-cols.is-3,
  .bp-doc .bp-cols.is-2{ grid-template-columns: 1fr; }
  .bp-doc .bp-flow,
  .bp-doc .bp-flow.is-5{ grid-template-columns: 1fr; }
  .bp-doc .bp-flow .fl-arrow{ justify-self: center; transform: rotate(90deg); }
  .bp-doc .bp-bars .row{ flex-wrap: wrap; }
  .bp-doc .bp-bars .row .k{ width: 100%; }
}

@media (max-width: 768px){
  .bp-doc .bp-lead{ font-size: 20px; }
  .bp-doc p,
  .bp-doc .bp-list > li,
  .bp-doc ul > li,
  .bp-doc .bp-steps > li{ font-size: 17px; line-height: 1.68; }
  .bp-doc h2{ font-size: 26px; margin-top: 36px; }
  .bp-doc h3{ font-size: 20px; }
  .bp-doc .bp-quote p{ font-size: 21px; }
  .bp-doc .bp-stats .v{ font-size: 38px; }
  .art-head .lede{ font-size: 18px; }
  .bp-hero{ margin-top: -60px; }
  .bp-hero > .frame{ height: 240px; }
  .blog-post-hero:has(+ .blog-post .bp-hero){ padding-bottom: 90px; }
  .blog-post-hero .crumbs{ margin-bottom: 32px; }
}

@media (max-width: 640px){
  .bp-doc .bp-cta-inline{ flex-direction: column; align-items: flex-start; }
  .bp-doc .bp-foot{ flex-direction: column; }
}

/* An SVG chart squeezed below ~440px stops being readable — let the
   FRAME scroll rather than shrink the type. The page never scrolls. */
@media (max-width: 620px){
  .bp-doc .bp-figure-frame:has(svg){ overflow-x: auto; }
  .bp-doc .bp-figure-frame svg{ min-width: 440px; }
}
