/* ============================================================
   Single chunk — loaded only on single blog posts.

   Section order: header (breadcrumb · pills · h1 · author · hero) ·
   2-column body (sidebar TOC + scta-band on left, article on right) ·
   post footer (tags + author bio) · related posts · shared CTA band.

   Article body styles target the raw post content from the_content() —
   selectors are scoped under .blog-article so authoring patterns
   (h2/h3, ul/ol, code, blockquote, .blog-callout, .step-block,
   .blog-checklist, .compare-table, .article-cta, .article-rule)
   render correctly when pasted into Classic Editor.
   ============================================================ */

/* ─── HEADER ─── */
.blog-header { padding: 56px 40px 32px; }
/* .blog-breadcrumb base styles live in global style.css — used on
   single posts, archives, search results, and the 404 page. */

.blog-pre-meta {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-bottom: 16px;
}
.blog-pre-meta-pill {
  display: inline-flex; align-items: center;
  gap: 5px;
  padding: 5px 12px;
  background: var(--color-bg);
  border: 1px solid var(--color-border-subtle);
  border-radius: 6px;
  font-size: .68rem; font-weight: 400;
  line-height: 1;
  color: var(--color-text-muted);
}

.blog-header h1 {
  font-size: clamp(1.8rem, 4vw, 2.4rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -.03em;
  margin-bottom: 28px;
  /* No max-width: long titles get the full corridor width so they
     don't wrap when there's space on the right. */
}

.blog-meta { margin-bottom: 32px; }
.blog-meta-author { display: flex; align-items: center; gap: 14px; }
.blog-meta-author .author-avatar {
  width: 48px; height: 48px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--color-bg-warm);
  /* object-fit keeps the avatar a perfect circle when get_avatar()
     outputs an <img> — without it, mobile flex constraints can squash
     the image to oval. */
  object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; color: var(--color-text);
  overflow: hidden;
}
.blog-meta-author .author-avatar img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.author-name { font-size: .9rem; font-weight: 700; color: var(--color-text); }
.author-role { font-size: .78rem; line-height: 1.4; color: var(--color-text-muted); margin-top: 2px; }

/* Featured image — narrower than the full content column to feel
   editorial, matching single-blog-post.html (max-width 820, 1000/450). */
.blog-hero-wrap {
  margin: 16px auto 0;
  max-width: 820px;
  border: 1px solid var(--color-border-subtle);
  border-radius: 14px;
  overflow: hidden;
  background: var(--color-bg-warm);
}
.blog-hero-img {
  width: 100%; max-height: 450px;
  aspect-ratio: 1000 / 450;
  object-fit: cover; display: block;
}

@media (max-width: 768px) {
  .blog-header { padding: 40px 20px 24px; }
  /* .blog-breadcrumb mobile rules also live in global style.css. */

  /* Keep all three meta pills on one line; allow a horizontal scroll
     as a safety net on very narrow phones (≤340px). */
  .blog-pre-meta {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .blog-pre-meta::-webkit-scrollbar { display: none; }
  .blog-pre-meta-pill {
    flex-shrink: 0;
    font-size: .64rem;
    padding: 5px 10px;
  }
}

/* ─── BODY (sidebar + article) ─── */
.blog-body {
  display: grid;
  grid-template-columns: 322px 1fr;
  gap: 0 32px;
  padding: 0 0 100px;
  align-items: start;
}
.blog-sidebar {
  padding: 48px 0 48px 40px;
  position: sticky; top: var(--header-height);
  /* Fixed viewport height so the flex layout below can split:
     toc-label (fixed) + toc-list (flex:1, scrolls inside itself)
     + sidebar-cta (pinned to bottom). The CTA is therefore always
     visible no matter how long the TOC grows. */
  height: calc(100vh - var(--header-height));
  display: flex; flex-direction: column;
}

.toc-label {
  flex-shrink: 0;
  font-size: .72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em;
  color: var(--color-text-muted);
  margin: 0 0 14px;
}
.toc-list {
  /* Flex item — fills the space between the label and the CTA, and
     scrolls inside itself when the list is long so the CTA stays
     pinned at the bottom of the sticky sidebar. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
  display: flex; flex-direction: column;
  gap: 12px;
  padding: 0 12px 0 0;
  margin: 0 0 24px;
}
.toc-list::-webkit-scrollbar { display: none; }
.toc-list__item { list-style: none; }
.toc-list__item--sub { padding-left: 14px; }
.toc-list a {
  display: block;
  padding: 2px 10px;
  border-left: 2px solid transparent;
  font-size: .74rem; line-height: 1.5;
  color: var(--color-text-muted);
  text-decoration: none;
  transition: color .15s, border-color .15s;
}
.toc-list a:hover,
.toc-list a.active {
  color: var(--color-text);
  border-left-color: var(--color-accent);
}

/* .sidebar-cta wrapper + the .service-cta-band__* cluster live in
   style.css (global) since service pages reuse the same component.
   Inside .blog-sidebar's flex column, the CTA must not shrink so
   it stays anchored at the bottom of the sticky panel. */
.blog-sidebar .sidebar-cta { flex-shrink: 0; }

@media (max-width: 900px) {
  .blog-body { grid-template-columns: 1fr; padding: 0 20px 60px; gap: 0; }
  /* Sidebar reverts to a normal block — no sticky, no fixed height,
     no flex column. TOC flows naturally; the desktop scroll-inside
     behaviour isn't needed at this width. */
  .blog-sidebar {
    padding: 16px 0 0;
    position: static;
    height: auto;
    display: block;
  }
  /* Mobile: hide the sticky service CTA — it's a desktop sidebar
     affordance. The post body still has the in-article CTA + the
     shared bottom CTA, so removing this avoids dead space at the top
     of a narrow scroll. */
  .sidebar-cta { display: none; }
  /* TOC sits directly above the article on mobile — tighten the
     trailing gap and the list spacing so the article starts close. */
  .toc-list {
    flex: none;
    overflow: visible;
    padding-right: 0;
    gap: 8px;
    margin-bottom: 12px;
  }
}

/* ─── ARTICLE BODY ─── */
.blog-article {
  min-width: 0;
  padding: 64px 60px 0 24px;
}
.blog-article h2 {
  font-size: 1.45rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -.025em;
  margin: 56px 0 18px;
  scroll-margin-top: calc(var(--header-height) + 16px);
}
.blog-article h2:first-child { margin-top: 0; }
.blog-article h3 {
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -.02em;
  margin: 36px 0 14px;
  scroll-margin-top: calc(var(--header-height) + 16px);
}
.blog-article h4 {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.35;
  margin: 28px 0 10px;
}
/* Body text matches the homepage card body sizing (~.88rem) — source
   single uses 0.889rem with line-height 1.9. */
.blog-article p {
  font-size: .89rem;
  line-height: 1.9;
  margin-bottom: 1.45rem;
  color: var(--color-text);
}
.blog-article a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; }
.blog-article a:hover { color: var(--color-accent-hover); }
/* Bullets and numbers — restore inside the article. The site-wide
   reset zeros list-style for nav menus; article prose needs it back. */
.blog-article ul,
.blog-article ol { padding-left: 24px; margin-bottom: 22px; }
.blog-article ul { list-style: disc; }
.blog-article ul li,
.blog-article ol li {
  position: relative;
  padding-left: 4px;
  margin-bottom: 8px;
  font-size: .89rem; line-height: 1.7;
}
.blog-article ul li::marker { color: var(--color-accent); }

/* Ordered list: custom counter so the number gets the accent color. */
.blog-article ol { counter-reset: blog-ol; padding-left: 0; list-style: none; }
.blog-article ol li {
  counter-increment: blog-ol;
  padding-left: 32px;
}
.blog-article ol li::before {
  content: counter(blog-ol) ".";
  position: absolute; left: 0;
  color: var(--color-accent);
  font-weight: 700;
}

.blog-article pre {
  background: #FAFAFA;
  color: var(--color-text);
  padding: 28px;
  margin: 36px 0;
  border: 1px solid var(--color-border-subtle);
  border-radius: 10px;
  overflow-x: auto;
  font-size: .78rem;
  line-height: 1.65;
}
.blog-article pre code {
  font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
  background: transparent;
  color: inherit;
  padding: 0;
  border: none;
  border-radius: 0;
}
.blog-article code {
  font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
  font-size: .82rem;
  background: var(--color-bg-warm);
  color: var(--color-accent);
  padding: 2px 7px;
  border: 1px solid var(--color-border-subtle);
  border-radius: 5px;
}
/* IDE-style token colors for inline syntax-highlighted snippets. */
.code-kw  { color: var(--color-purple-strong); }
.code-cmd { color: var(--color-blue); }
.code-str { color: var(--color-green-strong); }
.code-cmt { color: var(--color-text-on-dark-subtle); font-style: italic; }
.code-env { color: var(--color-accent-strong); }
.code-num { color: var(--color-accent); }

.blog-callout {
  background: var(--color-accent-tint);
  padding: 18px 22px;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  margin: 24px 0;
}
.blog-callout.tip-green {
  background: var(--color-green-tint);
}
.blog-callout p { margin: 0; font-size: .94rem; }
/* In-callout button: .blog-article a (specificity 0,0,1,1) forces accent
   text + underline on every body link, which would make a .btn render
   accent-on-accent and underlined. Re-assert the button's own color and
   drop the underline, and add a trailing gap so a following plain text
   link (e.g. a secondary CTA) isn't congested against the button. */
.blog-article .blog-callout a.btn {
  text-decoration: none;
  vertical-align: middle;
  margin-right: 14px;
}
.blog-article .blog-callout a.btn--primary,
.blog-article .blog-callout a.btn--primary:hover { color: var(--color-bg); }
.blog-article .blog-callout p:has(a.btn) { margin-top: 16px; }

.step-block {
  display: flex; gap: 18px;
  padding: 18px 0;
  border-top: 1px solid var(--color-border-subtle);
}
.step-block:first-of-type { border-top: none; }
.step-num {
  flex-shrink: 0;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-accent-tint);
  color: var(--color-accent-strong);
  border-radius: 50%;
  font-weight: 700; font-size: .9rem;
}
.step-content { flex: 1; }
.step-content h4 { font-size: 1rem; font-weight: 700; margin-bottom: 6px; }
.step-content p { margin: 0; font-size: .95rem; color: var(--color-text-muted); }

.blog-checklist { padding-left: 0; list-style: none; margin: 22px 0; }
.blog-checklist li {
  position: relative;
  padding-left: 28px;
  margin-bottom: 10px;
  font-size: .96rem; line-height: 1.6;
}
.blog-checklist li::before {
  content: '✓';
  position: absolute; left: 0; top: 1px;
  color: var(--color-green);
  font-weight: 800;
}

/* ─── ARTICLE TABLES ───
   Any <table> pasted into the article (Classic Editor or HTML view)
   inherits this styling automatically — editors don't need a wrapper
   class. .compare-table-wrap is still supported for opt-in horizontal
   scroll on narrow tables; on small viewports every table becomes
   horizontally scrollable via the display:block + overflow-x:auto
   rule in the responsive section below.

   Visual: rounded outer border, sand header band, hairline row
   dividers, comfortable cell padding, zebra-striped body. */
.blog-article table,
.compare-table,
.compare-table-wrap > table {
  width: 100%;
  margin: 28px 0;
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-bg);
  font-size: .88rem;
  line-height: 1.55;
}
.blog-article table th,
.blog-article table td,
.compare-table th,
.compare-table td {
  padding: 12px 16px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-border-subtle);
}
.blog-article table th,
.compare-table th {
  background: var(--color-bg-sand);
  font-weight: 600;
  color: var(--color-text);
  border-bottom: 2px solid var(--color-border-subtle);
}
.blog-article table tr:last-child td,
.compare-table tr:last-child td { border-bottom: none; }
.blog-article table tbody tr:nth-child(even) {
  background: var(--color-bg-subtle);
}
.blog-article table code {
  font-size: .85em;
}

/* Wrapper so editors can opt in to a non-collapsing table on narrow
   viewports: <div class="compare-table-wrap"><table>…</table></div>.
   Even without the wrapper, the responsive guard below makes every
   article table horizontally scrollable on mobile. */
.compare-table-wrap {
  margin: 28px 0;
  overflow-x: auto;
  border-radius: var(--radius-md);
}
.compare-table-wrap > table { margin: 0; }

.article-cta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
  padding: 24px;
  background: var(--color-accent-tint);
  border-radius: var(--radius-md);
  margin: 32px 0;
}
.article-cta h3 { font-size: 1.05rem; font-weight: 700; margin-bottom: 4px; }
.article-cta p { font-size: .9rem; color: var(--color-text-muted); margin: 0; }
.article-cta-btn {
  flex-shrink: 0;
  background: var(--color-accent);
  color: var(--color-bg);
  padding: 12px 22px;
  border-radius: var(--radius-sm);
  font-weight: 600; font-size: .9rem;
  text-decoration: none;
}
.article-cta-btn:hover {
  background: var(--color-accent-hover);
  color: var(--color-bg);
}

.article-rule {
  border: none;
  border-top: 1px solid var(--color-border-subtle);
  margin: 40px 0;
}

/* ─── POST FOOTER ─── */
.blog-post-footer { margin-top: 48px; }
.blog-tags-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 32px; }
.blog-tag-pill {
  display: inline-flex; align-items: center;
  padding: 4px 12px;
  background: var(--color-bg);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-pill);
  font-size: .76rem; font-weight: 500;
  color: var(--color-text-muted);
  text-decoration: none !important;
  transition: border-color .15s, color .15s;
}
.blog-tag-pill:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
  text-decoration: none !important;
}

.author-bio-card {
  display: flex; gap: 20px; align-items: flex-start;
  padding: 24px;
  background: var(--color-bg-subtle);
  border-radius: var(--radius-md);
}
.author-bio-avatar {
  flex-shrink: 0;
  width: 64px; height: 64px;
  border-radius: 50%; overflow: hidden;
  background: var(--color-bg-warm);
}
.author-bio-avatar img { width: 100%; height: 100%; object-fit: cover; }
.author-bio-body { flex: 1; }
.author-bio-name { font-size: 1.05rem; font-weight: 700; color: var(--color-text); margin-bottom: 3px; }
.author-bio-title { font-size: .85rem; color: var(--color-accent); font-weight: 600; margin-bottom: 12px; }
/* Higher specificity — .blog-article p (1 class + 1 tag) was overriding
   the single-class .author-bio-text rule. */
.author-bio-card p.author-bio-text { font-size: 16px; color: var(--color-text-muted); line-height: 1.7; margin: 0; }

/* ─── RELATED POSTS ─── */
.related-posts { padding: 72px 0 96px; background: var(--color-bg-subtle); }
.related-posts.cv-defer { content-visibility: visible; }
.related-posts h2 {
  font-size: clamp(1.3rem, 2.4vw, 1.75rem);
  font-weight: 700;
  margin-bottom: 28px;
}
.related-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
/* Related uses the global .blog-card cluster (in style.css) — only
   the grid wrapper is scoped here. */

@media (max-width: 900px) { .related-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .related-grid { grid-template-columns: 1fr; } }

/* ─── RESPONSIVE GUARDS ───
   Long content patterns (tables, code blocks, inline code, iframes,
   raw HTML pasted by editors) tend to push the article off-screen
   on narrow viewports. These rules keep everything inside the column
   without forcing a sideways scroll on the whole page. */
.blog-article { overflow-wrap: break-word; word-wrap: break-word; }
.blog-article img,
.blog-article iframe,
.blog-article video,
.blog-article embed {
  max-width: 100%; height: auto; display: block;
}
.blog-article pre {
  /* width:100% lets pre shrink to the column; overflow-x already on. */
  max-width: 100%;
}
/* Table responsive handling moved to the mobile @media block below —
   on desktop, tables render normally to keep cell alignment intact. */
.blog-article code { word-break: break-word; }
/* Step blocks can blow out width if the inner h4/p contain long
   unbreakable strings — let them wrap. */
.step-content { min-width: 0; word-break: break-word; }
.article-cta { min-width: 0; }
.article-cta > div { min-width: 0; }

@media (max-width: 900px) {
  .blog-article { padding: 32px 0 0; }
  .blog-article pre { padding: 18px; }
  .article-cta { flex-direction: column; align-items: flex-start; padding: 20px; }
  .author-bio-card { flex-direction: column; }
  .author-bio-avatar { width: 56px; height: 56px; }
  /* Tables: turn the table itself into a scrollable block so wide
     content scrolls horizontally inside the article column instead
     of pushing the page off-screen. The header and body cells
     visually still align because the scroll preserves the natural
     table layout — Chrome/Firefox/Safari all handle this. */
  .blog-article table,
  .compare-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }
  .blog-article table th,
  .blog-article table td,
  .compare-table th,
  .compare-table td {
    padding: 10px 14px;
    font-size: .85rem;
  }
}

/* Mobile typography matches the homepage scale (card headings,
   section h2s, and body sizes used across home.css). */
@media (max-width: 600px) {
  .blog-header h1 { font-size: 1.6rem; line-height: 1.25; margin-bottom: 20px; }
  .blog-article h2 {
    font-size: 1.25rem;
    margin: 36px 0 14px;
  }
  .blog-article h3 {
    font-size: 1.02rem;
    margin: 26px 0 10px;
  }
  .blog-article h4 { font-size: .96rem; margin: 22px 0 8px; }
  .blog-article p,
  .blog-article ul li,
  .blog-article ol li {
    font-size: .88rem;
    line-height: 1.7;
  }
  .blog-article p { margin-bottom: 1.2rem; }
}
