/* ============================================================
   Article (blog post / case study) — shared layout
   Used by all individual blog detail pages.
   Relies on tokens defined in styles.css :root
   ============================================================ */

/* ---- Layout shell ---- */
.article-wrap { background: #fff; }

/* Measure, not container width: the classic readable line is 45-75 characters
   (Bringhurst's 66 being the single-column ideal). At 17px Work Sans the old
   760px ran ~86 characters per line, past the point where the eye loses its
   place on the return sweep. 620px lands at ~70. */
.article-prose-width { max-width: 620px; margin: 0 auto; }

/* ---- Breadcrumb ---- */
.article-breadcrumb {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--sans);
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted-soft);
  margin-bottom: 28px;
}
.article-breadcrumb a { color: var(--muted-soft); transition: color 120ms; }
.article-breadcrumb a:hover { color: var(--indigo); }
.article-breadcrumb svg { width: 12px; height: 12px; flex-shrink: 0; opacity: 0.6; }

/* ---- Hero ----
   The masthead sits on the lightest paper token rather than pure white, so the
   header reads as its own band against the white article body below it (the
   CommCare blog does the same with its lavender wash). --paper is #FAFBFF. */
.article-hero {
  background: var(--paper);
  padding: 56px 0 36px;
}
/* Solid pill above the headline, matching the CommCare blog's .article-category.
   CommCare colours this per content type (Case Study, Insights…); Dimagi's tag
   is the product instead (Dimagi, Connect, SureAdhere, Open Chat Studio), so it
   uses the one brand indigo rather than a per-product palette we don't have
   tokens for. */
.article-category {
  display: inline-flex; align-items: center; align-self: flex-start;
  font-family: var(--sans);
  font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: #fff; background: var(--indigo);
  padding: 5px 12px; border-radius: 999px;
  margin: 0 0 18px;
}
h1.article-title {
  font-size: clamp(32px, 4.4vw, 50px);
  font-weight: 300;
  letter-spacing: -0.03em;
  line-height: 1.12;
  color: var(--ink);
  margin: 0 0 22px;
}
.article-deck {
  font-size: clamp(18px, 2.2vw, 21px);
  font-weight: 300;
  line-height: 1.55;
  color: var(--muted);
  margin: 0 0 36px;
}

/* ---- Meta bar: byline anchored left under the headline, share icons anchored
   right under the photo's edge. The two ends balance the two columns above.
   Full-bleed band closing the masthead, so the byline sits BELOW both the text
   and the cover rather than inside the text column. Mirrors the CommCare blog
   (src/styles/blog-article.css). */
.article-meta-band {
  margin-top: 40px;
  background: transparent;
}
/* Spread across the full width: byline on the left, share icons pushed right.
   A hairline above (content-width) separates it from the headline/photo. The
   rule is a tint of --indigo (#3843D0) rather than a new colour. */
.article-meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px 26px;
  flex-wrap: wrap;
  padding: 26px 0 34px;
  border-top: 1px solid rgba(56, 67, 208, 0.15);
}
/* Once they stack, space-between would strand them at opposite edges. */
@media (max-width: 760px) { .article-meta { justify-content: flex-start; } }

/* ---- Byline ---- */
.article-byline {
  display: flex; align-items: center; gap: 14px;
}
.article-byline-avatar {
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--grad-deep);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  font-weight: 600; font-size: 16px; color: #fff;
  letter-spacing: -0.01em;
}
.article-byline-meta { display: flex; flex-direction: column; gap: 3px; }
.article-byline-author {
  font-size: 15px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em;
}
.article-byline-detail {
  font-family: var(--sans);
  font-size: 11.5px; font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--muted);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.article-byline-detail .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--muted-soft); }

/* ---- Byline author link (-> /blog/author/<slug>/) ---- */
.article-byline-author a,
.article-byline-author-link {
  color: inherit; text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 140ms ease, border-color 140ms ease;
}
.article-byline-author a:hover,
.article-byline-author-link:hover {
  color: var(--indigo); border-bottom-color: currentColor;
}

/* ---- Outbound profile arrow, sits after the (unlinked) author name ----
   The name used to be the link itself, which made the whole byline look
   clickable and gave no hint it left the site. Mirrors the CommCare blog. */
/* The arrow is inline and sized to its glyph, not a flex child in a padded box:
   a flex container would insert its gap around the ", " text nodes of a
   multi-author byline, and a wider box would push the following comma away
   from the name it belongs to. */
.article-byline-profile {
  display: inline-flex; align-items: center;
  vertical-align: middle; margin-left: 4px; position: relative; top: -1px;
  border: 0; color: var(--muted);
  transition: color 140ms ease;
}
.article-byline-profile svg { width: 13px; height: 13px; }
.article-byline-profile:hover,
.article-byline-profile:focus-visible { color: var(--indigo); }

/* ---- Hero grid (split masthead: text one side, cover the other) ----
   Mobile-first: stacks (text, then cover) in the same order as the old layout.
   Side-by-side on desktop so the headline + byline land beside the cover. */
.article-hero-grid {
  display: grid;
  grid-template-columns: 100%;
  gap: 36px;
  align-items: start;
}
.article-hero-main,
.article-hero-media {
  min-width: 0;
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
}
.article-hero-media { display: flex; flex-direction: column; }
@media (min-width: 900px) {
  .article-hero { padding: 64px 0 44px; }
  .article-hero-grid.has-media {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: clamp(40px, 5vw, 60px);
    align-items: stretch;
  }
  .article-hero-grid.has-media .article-hero-main,
  .article-hero-grid.has-media .article-hero-media { max-width: none; margin: 0; }
  /* Centre the headline/byline optically against the taller cover column. */
  .article-hero-grid.has-media .article-hero-main {
    display: flex; flex-direction: column; justify-content: center;
  }
  .article-hero-grid.has-media h1.article-title {
    font-size: clamp(30px, 3.3vw, 42px); margin-bottom: 20px;
  }
  .article-hero-grid.has-media .article-deck {
    font-size: clamp(17px, 1.9vw, 20px); margin-bottom: 30px;
  }
  /* Cover fills the column edge to edge, top of the headline to the meta rule.
     Its 3:2 slot is released here so it can stretch to the row height. Video
     embeds keep their own 16:9 box, so they're excluded from the stretch. */
  .article-hero-grid.has-media .article-cover:not(.article-cover--video) {
    flex: 1; min-height: 380px; max-width: none; margin: 0;
  }
  .article-hero-grid.has-media .article-cover:not(.article-cover--video) img {
    height: 100%; aspect-ratio: auto;
  }
}

/* ---- Cover image ---- */
.article-cover-wrap { background: #fff; }
/* Cover aligns to the body text column (760px) so its edges line up with the prose */
.article-cover {
  position: relative;
  max-width: 760px; margin: 0 auto;
  border-radius: var(--radius-lg);
  overflow: hidden;
  line-height: 0;
  box-shadow: 0 24px 50px -28px rgba(10,6,32,0.28);
}
/* Landscape cover (most post photos are rectangular): a 3:2 slot, top-aligned
   with the headline. object-fit crops non-3:2 sources to fill. Released to the
   row height inside .article-hero-grid.has-media above. */
.article-cover img { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; display: block; }
/* Caption/citation overlaid on the bottom of the cover photo (over a soft dark
   scrim), rather than set below it — the figure's overflow:hidden + radius clip
   it to the rounded corners, so the photo reads as one block edge to edge. */
.article-cover-caption {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  margin: 0; padding: 40px 18px 14px;
  font-size: 13px; line-height: 1.45; font-style: italic;
  color: rgba(255,255,255,0.95); text-align: left;
  background: linear-gradient(to top, rgba(10,6,32,0.82) 0%, rgba(10,6,32,0.42) 48%, transparent 100%);
  pointer-events: none;
}
/* Webinar cover: host the embed in the cover slot. The inner .article-video-embed
   already supplies the rounded, shadowed 16:9 frame, so the figure stays unstyled. */
.article-cover--video { border-radius: 0; overflow: visible; box-shadow: none; line-height: 0; }

/* ---- Inline body figure ---- */
.article-inline-figure {
  margin: 32px 0;
}
.article-inline-figure img {
  display: block;
  width: 100%; height: auto;
  border-radius: var(--radius-lg);
  box-shadow: 0 18px 40px -22px rgba(10,6,32,0.22);
}
.article-inline-figure figcaption {
  font-size: 13px; color: var(--muted-soft);
  line-height: 1.5;
  margin-top: 12px; padding: 0 4px;
  font-style: italic;
}

/* ---- Body prose ---- */
.article-body {
  padding: 52px 0 24px;
}
.article-body .article-prose-width > *:first-child { margin-top: 0; }

.prose p {
  font-size: 17px;
  font-weight: 350;
  line-height: 1.8;
  color: #2B2740;
  margin: 0 0 24px;
}
.prose p:last-child { margin-bottom: 0; }
.prose strong { color: var(--ink); font-weight: 600; }
.prose a:not(.btn) { color: var(--indigo); font-weight: 500; text-decoration: none; transition: color 150ms; }
.prose a:not(.btn):hover { color: var(--indigo-deep); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.prose a:not(.btn):focus-visible { text-decoration: underline; text-underline-offset: 2px; }

.prose h2 {
  font-size: clamp(23px, 2.8vw, 29px);
  font-weight: 450;
  letter-spacing: -0.02em;
  line-height: 1.25;
  color: var(--ink);
  margin: 52px 0 20px;
}
.prose h3 {
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.35;
  color: var(--ink);
  margin: 40px 0 14px;
}
.prose h2 + p, .prose h3 + p { margin-top: 0; }

.prose ul {
  margin: 0 0 26px; padding: 0; list-style: none;
}
.prose ul li {
  position: relative;
  font-size: 17px; font-weight: 350; line-height: 1.75; color: #2B2740;
  padding: 0 0 0 28px; margin: 0 0 14px;
}
.prose ul li::before {
  content: ""; position: absolute; left: 4px; top: 12px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--purple);
}
.prose ul li strong { color: var(--ink); }

/* numbered driver headings (e.g. "1. A Partnership ...") */
.prose .step-head {
  display: flex; align-items: baseline; gap: 14px;
  margin: 44px 0 14px;
}
.prose .step-num {
  font-family: var(--sans);
  font-size: 13px; font-weight: 600;
  color: var(--indigo);
  background: var(--indigo-soft);
  width: 30px; height: 30px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.prose .step-head h3 { margin: 0; align-self: center; }

/* ---- Pull quote ---- */
.prose blockquote {
  margin: 28px 0; padding: 4px 0 4px 28px;
  border-left: 3px solid var(--purple);
}
.prose blockquote p {
  font-size: 20px; font-weight: 400;
  line-height: 1.55; letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 12px;
}
.prose blockquote cite {
  display: block;
  font-style: normal;
  font-family: var(--sans);
  font-size: 12px; font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* Featured pull-quote — one per article, used as a visual break */
.prose blockquote.feature {
  border-left: none;
  text-align: center;
  max-width: 640px;
  margin: 56px auto;
  padding: 0;
}
.prose blockquote.feature::before {
  content: "\201C";
  display: block;
  font-size: 64px; line-height: 0.7;
  color: var(--purple);
  margin-bottom: 4px;
}
.prose blockquote.feature p {
  font-size: clamp(24px, 3.2vw, 31px);
  font-weight: 300;
  line-height: 1.32;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 18px;
}

/* ---- Results / stat callout ---- */
.article-callout {
  background: var(--sky-tint);
  border: 1px solid var(--indigo-soft);
  border-left: 4px solid var(--indigo);
  border-radius: var(--radius-lg);
  padding: 40px 44px;
  margin: 40px 0;
}
.article-callout-label {
  font-family: var(--sans); font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--indigo); margin-bottom: 12px;
}
.article-callout-num {
  font-size: clamp(40px, 6vw, 60px); font-weight: 300;
  line-height: 1; letter-spacing: -0.03em;
  color: var(--deep-purple);
  margin-bottom: 14px;
}
.article-callout-text {
  font-size: 17px; line-height: 1.65; color: #2B2740;
  margin: 0; max-width: 580px; font-weight: 400;
}

/* ---- Impact grid ---- */
.impact-team-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
  margin: 32px 0;
}
.impact-team-card {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 24px 26px;
}
.impact-team-card h4 {
  font-size: 13px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--indigo); margin: 0 0 8px;
}
.impact-team-card p { font-size: 15.5px; line-height: 1.6; color: var(--muted); margin: 0; }

/* ---- End CTA ---- */
/* Closing CTA flows as part of the article content (no box, no divider line) */
.article-end-cta {
  margin: 44px 0 0;
}
.article-end-cta h3 {
  font-size: clamp(23px, 3vw, 30px); font-weight: 500; letter-spacing: -0.02em;
  color: var(--ink); margin: 0 0 16px; line-height: 1.2;
}
.article-end-cta p {
  font-size: 18px; color: #2B2740; line-height: 1.78;
  margin: 0 0 26px; max-width: none;
}
.article-video-embed {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  background: #000; border-radius: 14px; overflow: hidden;
  box-shadow: 0 18px 40px -22px rgba(10, 6, 32, 0.45);
}
.article-video-embed iframe {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block;
}
/* CONVENTION: every blog/article video embed (YouTube, Wistia, Vimeo, etc.) must be
   wrapped in <figure class="article-inline-figure"> with the iframe inside (ideally in a
   <div class="article-video-embed">). That makes it break out of the 760px text column to a
   centered, responsive player. Width is the single knob below (min(700px, 92vw)); change it
   in one place. Do NOT add raw <iframe>/wp-block-embed video markup elsewhere or it will
   render at its hardcoded width and look inconsistent.
   Symmetric negative margins keep it centered relative to the (centered) text column. */
.article-inline-figure:has(iframe) {
  width: auto;
  margin-left: calc((100% - var(--article-video-w, min(700px, 92vw))) / 2);
  margin-right: calc((100% - var(--article-video-w, min(700px, 92vw))) / 2);
}
.article-inline-figure:has(iframe) figcaption { text-align: center; }
@media (max-width: 680px) {
  .article-inline-figure:has(iframe) { margin-left: 0; margin-right: 0; }
}

/* ---- Article focus chip (single tag near the top, replaces old "Filed under" footer) ---- */
.article-focus-tag {
  display: inline-flex; align-items: center;
  font-family: var(--sans); font-size: 11px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--indigo); background: #fff;
  border: 1px solid var(--line);
  padding: 7px 14px; border-radius: 999px;
  margin: 0 0 14px;
  box-shadow: 0 2px 8px rgba(10,6,32,0.08);
}
/* Legacy footer-tag styles kept so any unmigrated page still renders; new pages
   should use .article-focus-tag at the top instead. */
.article-foot { margin-top: 40px; margin-bottom: 28px; }
.article-foot-label {
  font-family: var(--sans); font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--muted-soft); margin-bottom: 16px;
}
.article-tags { display: flex; gap: 10px; flex-wrap: wrap; }
.article-tag {
  font-family: var(--sans); font-size: 11px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--indigo); background: #fff;
  border: 1px solid var(--line);
  padding: 8px 15px; border-radius: 999px;
}

/* ---- Related posts (dark Dimagi-purple band) ---- */
.related-wrap {
  background: var(--grad-deep);
  padding: 80px 0;
  position: relative; overflow: hidden;
}
.related-wrap::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(50% 80% at 100% 0%, rgba(56,67,208,0.35), transparent 65%);
  pointer-events: none;
}
.related-wrap > .container { position: relative; z-index: 1; }
.related-head { text-align: center; margin-bottom: 40px; }
.related-head .eyebrow { justify-content: center; color: #fff; }
.related-head .eyebrow::before { background: rgba(255,255,255,0.6); }
.related-head h2 { font-size: clamp(26px, 3vw, 34px); font-weight: 300; letter-spacing: -0.025em; color: #fff; }
.related-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.related-card {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  overflow: hidden; display: flex; flex-direction: column;
  box-shadow: 0 1px 2px rgba(10,6,32,0.04);
  transition: transform 200ms, box-shadow 200ms, border-color 200ms;
}
.related-card:hover { transform: translateY(-4px); box-shadow: 0 20px 40px -12px rgba(10,6,32,0.14); border-color: var(--rule); }
.related-card-thumb {
  aspect-ratio: 16 / 9; overflow: hidden; line-height: 0;
  background: var(--grad-deep);
}
.related-card-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 350ms ease; }
.related-card:hover .related-card-thumb img { transform: scale(1.04); }
.related-card-body { padding: 22px 24px 26px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.related-card-cat { font-family: var(--sans); font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--indigo); }
.related-card-title { font-size: 16px; font-weight: 500; letter-spacing: -0.015em; color: var(--ink); line-height: 1.4; flex: 1; }
.related-card-footer { display: flex; align-items: center; justify-content: space-between; margin-top: auto; padding-top: 16px; border-top: 1px solid var(--line); }
.related-card-date { font-family: var(--sans); font-size: 11px; font-weight: 500; color: var(--muted-soft); letter-spacing: 0.06em; }
.related-card-link { font-size: 12.5px; font-weight: 600; color: var(--indigo); display: inline-flex; align-items: center; gap: 4px; transition: gap 150ms; }
.related-card-link::after { content: "→"; }
.related-card:hover .related-card-link { gap: 8px; }

/* Back-to-blog action under the related grid */
.related-foot { text-align: center; margin-top: 48px; }
/* "Return to Blog home" CTA = Dimagi marigold (pops on the dark band) */
.related-foot .btn-primary { background: var(--marigold); color: var(--ink); }
.related-foot .btn-primary:hover { background: var(--marigold); color: var(--ink); transform: translateY(-1px); box-shadow: 0 6px 18px -6px rgba(254,175,49,0.55); }

/* ---- Reading progress bar ---- */
.reading-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  background: transparent; z-index: 60; pointer-events: none;
}
.reading-progress-bar {
  display: block; height: 100%; width: 0;
  background: var(--purple);
  transition: width 80ms linear;
}

/* ---- Share row (under byline) ---- */
.article-share {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
/* Icon-only circles — Copy · LinkedIn · X · Download, all the same footprint.
   The old "Share" label and per-button text labels are gone: in the meta band
   the row sits opposite the byline, where labels crowded the line. */
.article-share-btn {
  width: 36px; height: 36px; padding: 0;
  display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 50%;
  background: #fff; color: var(--muted);
  cursor: pointer; transition: border-color 150ms, color 150ms, background 150ms;
}
.article-share-btn svg { width: 15px; height: 15px; }
/* Copy link: swap the link glyph for a check on success (no text label). */
.article-copy .article-copy-check { display: none; }
.article-copy.is-copied .article-copy-link { display: none; }
.article-copy.is-copied .article-copy-check { display: block; }
.article-share-btn:hover { border-color: var(--indigo); color: var(--indigo); }
.article-share-btn.is-copied { border-color: var(--indigo); color: var(--indigo); background: var(--indigo-soft); }

/* ---- Lead paragraph ---- */
.prose p.lead {
  font-size: clamp(18px, 2vw, 21px);
  line-height: 1.62; font-weight: 350; color: var(--ink);
  margin-bottom: 30px;
}

/* ---- Back to top ---- */
.back-to-top {
  position: fixed; bottom: 28px; right: 28px; z-index: 55;
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--deep-purple); color: #fff; border: none;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; box-shadow: 0 8px 24px -6px rgba(10,6,32,0.45);
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity 200ms, transform 200ms, visibility 200ms, background 150ms;
}
.back-to-top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.back-to-top:hover { background: var(--indigo); }
.back-to-top svg { width: 20px; height: 20px; }
@media (prefers-reduced-motion: reduce) {
  .reading-progress-bar { transition: none; }
  .back-to-top { transition: opacity 200ms, visibility 200ms; }
}

/* ---- Responsive ---- */
@media (max-width: 900px) {
  .related-grid { grid-template-columns: 1fr 1fr; }
  .article-callout { padding: 36px 32px; }
}
@media (max-width: 680px) {
  .article-hero { padding: 40px 0 36px; }
  .article-cover { margin-top: 0; border-radius: var(--radius); }
  .article-body { padding: 44px 0 16px; }
  .prose p, .prose ul li { font-size: 17px; }
  .impact-team-grid { grid-template-columns: 1fr; }
  .related-grid { grid-template-columns: 1fr; }
  .article-callout { padding: 30px 24px; }
  .back-to-top { bottom: 18px; right: 18px; }
  .prose p, .prose ul li { font-size: 16px; }
}

/* ---- Table of contents (sticky right-gutter sidebar, desktop only) ---- */
html { scroll-padding-top: 90px; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
.article-toc { display: none; }
.article-toc-label {
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted-soft); margin: 0 0 14px;
}
.article-toc nav { display: flex; flex-direction: column; border-left: 1px solid var(--line); }
.article-toc a {
  font-size: 13px; font-weight: 350; line-height: 1.4;
  color: var(--muted);
  padding: 7px 0 7px 16px; margin-left: -1px;
  border-left: 2px solid transparent;
  transition: color 150ms, border-color 150ms;
}
.article-toc a:hover { color: var(--ink); }
.article-toc a.is-active { color: var(--purple); border-left-color: var(--purple); font-weight: 500; }
@media (min-width: 1140px) {
  .article-body > .container {
    display: grid;
    grid-template-columns: 1fr min(760px, 100%) 1fr;
    column-gap: 32px;
    align-items: start;
  }
  .article-body > .container > .article-prose-width { grid-column: 2; }
  .article-toc {
    display: block; grid-column: 3;
    position: sticky; top: 96px; align-self: start;
  }
}

/* ---- Mobile / tablet TOC (native <details>; hidden once the desktop rail
       takes over at 1140px). Built from the same anchors as .article-toc. ---- */
.article-toc-mobile {
  margin: 0 0 34px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper-warm);
}
.article-toc-mobile summary {
  cursor: pointer;
  padding: 14px 18px;
  font-family: var(--sans);
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted-soft);
}
.article-toc-mobile summary::marker { color: var(--indigo); }
.article-toc-mobile summary::-webkit-details-marker { color: var(--indigo); }
.article-toc-mobile summary:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; border-radius: var(--radius); }
.article-toc-mobile[open] summary { padding-bottom: 4px; }
.article-toc-list { list-style: none; margin: 0; padding: 0 18px 14px; }
.article-toc-list li { margin: 0; padding: 0; }
.article-toc-list a {
  display: block;
  padding: 7px 0;
  font-family: var(--sans);
  font-size: 14px; font-weight: 400; line-height: 1.45;
  color: var(--muted);
  transition: color 140ms ease;
}
.article-toc-list a:hover { color: var(--indigo); }
/* Neutralize the prose list styling that would otherwise leak into the TOC. */
.prose .article-toc-list { margin: 0; }
.prose .article-toc-list li::before { content: none; }
.prose .article-toc-list a { text-decoration: none; }
@media (min-width: 1140px) { .article-toc-mobile { display: none; } }

/* ---- Related reading band (CommCare-style, replaces the old .related-wrap) ---- */
.article-related-band {
  background: linear-gradient(180deg, #EEF0FB 0%, #F5F6FC 60%, #F1F3FB 100%);
  padding: 58px 0 66px;
}
.article-related-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px 28px; flex-wrap: wrap; margin: 0 0 22px;
}
.article-related-label {
  font-family: var(--sans); font-size: 11px; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--muted-soft); margin: 0;
}
.article-related-all {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--sans); font-size: 13px; font-weight: 600;
  letter-spacing: 0.02em; color: var(--indigo);
  text-decoration: none; transition: gap 150ms ease, color 150ms ease;
}
.article-related-all svg { width: 15px; height: 15px; flex-shrink: 0; }
.article-related-all:hover { gap: 10px; color: var(--indigo-deep); }
.article-related-all:focus-visible { outline: 2px solid var(--indigo); outline-offset: 3px; border-radius: 4px; }
.article-related-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
a.article-related-card {
  display: flex; flex-direction: column;
  background: #fff;
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden;
  color: var(--ink); font-weight: 400; text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: transform 200ms, box-shadow 200ms, border-color 200ms;
}
a.article-related-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: var(--rule);
  color: var(--ink); text-decoration: none;
}
a.article-related-card:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }
.article-related-thumb {
  display: block; aspect-ratio: 16 / 9;
  background: var(--grad-deep);
  overflow: hidden; line-height: 0;
}
.article-related-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.article-related-body { display: flex; flex-direction: column; gap: 7px; padding: 14px 16px 17px; }
.article-related-tag {
  font-family: var(--sans); font-size: 10px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--indigo);
}
.article-related-title { font-size: 14.5px; font-weight: 500; letter-spacing: -0.01em; line-height: 1.45; color: var(--ink); }
@media (min-width: 640px) {
  .article-related-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 639px) {
  a.article-related-card { flex-direction: row; align-items: stretch; }
  .article-related-thumb { width: 110px; flex-shrink: 0; aspect-ratio: auto; }
  .article-related-body { padding: 12px 14px; justify-content: center; }
}

/* ============================================================
   Print / "Download PDF" — scoped to body.blog-pdf so it only
   applies to article pages that show the Download button.
   Ported from the CommCare blog (src/styles/blog-article.css).
   ============================================================ */
@media print {
  body.blog-pdf { background: #fff; color: #1a1a1a; }

  /* Kill drop shadows — print engines render box-shadow as ugly grey boxes. */
  body.blog-pdf * { box-shadow: none !important; }

  /* Strip site chrome + interactive/promo elements */
  body.blog-pdf .skip-link,
  body.blog-pdf .nav-wrap,
  body.blog-pdf footer,
  body.blog-pdf .reading-progress,
  body.blog-pdf .back-to-top,
  body.blog-pdf .gtranslate_wrapper,
  body.blog-pdf .article-breadcrumb,
  body.blog-pdf .article-category,
  body.blog-pdf .article-share,
  body.blog-pdf .article-end-cta,
  body.blog-pdf .article-toc,
  body.blog-pdf .article-toc-mobile,
  body.blog-pdf .article-related-band { display: none !important; }

  /* One readable column (~70 chars/line) centered on the page. The hero grid
     and the desktop TOC grid both collapse back to a plain block flow. */
  body.blog-pdf .article-hero { background: #fff !important; }
  /* No tinted strip in the PDF — the byline prints as plain text on white. */
  body.blog-pdf .article-meta-band { background: none !important; margin-top: 0; }
  body.blog-pdf .article-meta { border-top: none; padding: 0 0 10pt; }
  body.blog-pdf .container,
  body.blog-pdf .article-body > .container { display: block; max-width: none; padding: 0; }
  body.blog-pdf .article-hero-grid { display: block; }
  body.blog-pdf .article-prose-width,
  body.blog-pdf .article-hero-main { max-width: 6.6in; margin-left: auto; margin-right: auto; }
  body.blog-pdf .article-hero,
  body.blog-pdf .article-body { padding: 0 !important; }
  body.blog-pdf .article-hero-media { margin: 18pt auto 22pt; }
  body.blog-pdf .article-hero-media,
  body.blog-pdf .article-cover { max-width: 6.6in; }
  body.blog-pdf .article-cover { margin: 0 auto; }
  /* The caption is an overlay on screen; in print it drops below the photo as
     plain text (the white-on-scrim treatment is unreadable on paper). */
  body.blog-pdf .article-cover { overflow: visible; }
  body.blog-pdf .article-cover-caption {
    position: static; background: none; padding: 0;
    margin-top: 6pt; font-size: 8.5pt; color: #777;
  }
  body.blog-pdf .article-byline { margin-bottom: 4pt; }

  /* Dimagi wordmark at the top of the PDF (page 1), indigo, over a hairline. */
  body.blog-pdf .print-brandbar {
    display: block;
    max-width: 6.6in; margin: 0 auto 16pt; padding-bottom: 7pt;
    border-bottom: 1px solid #d8d8e0;
  }
  body.blog-pdf .print-brandbar .pb-logo {
    font-size: 14pt; font-weight: 700; letter-spacing: -0.01em; color: var(--indigo);
  }

  /* Source footer — a clean attribution line at the foot of the article
     (article URL + the date the reader saved the PDF). In-flow at the end so it
     never overlaps body text. */
  body.blog-pdf .print-footer { display: block; break-inside: avoid; }
  body.blog-pdf .print-footer .pf-inner {
    display: flex; align-items: baseline; justify-content: space-between; gap: 16pt;
    max-width: 6.6in; margin: 18pt auto 0; padding-top: 6pt;
    border-top: 1px solid #d8d8e0;
    font-size: 8pt; line-height: 1.3; color: #888;
  }
  body.blog-pdf .print-footer .pf-url { color: #666; word-break: break-all; }
  body.blog-pdf .print-footer .pf-accessed { color: #999; white-space: nowrap; }

  /* Cover: cap height so it doesn't eat a full page. */
  body.blog-pdf .article-cover img {
    max-height: 3in; width: 100%; object-fit: cover; border-radius: 6pt;
    aspect-ratio: auto;
  }

  /* Ink-friendly type. */
  body.blog-pdf .article-title { font-size: 21pt; line-height: 1.15; color: #14103A; }
  body.blog-pdf .article-deck { font-size: 12pt; }
  body.blog-pdf .prose p,
  body.blog-pdf .prose li { font-size: 10.5pt; line-height: 1.5; color: #1a1a1a; }
  body.blog-pdf .prose h2 { font-size: 14.5pt; margin-top: 16pt; color: #14103A; }
  body.blog-pdf .prose h3 { font-size: 12.5pt; color: #14103A; }

  /* Keep atomic blocks intact; keep headings with the text that follows. */
  body.blog-pdf .article-callout,
  body.blog-pdf figure,
  body.blog-pdf img { break-inside: avoid; }
  body.blog-pdf .prose h2,
  body.blog-pdf .prose h3 { break-after: avoid; }
  body.blog-pdf .prose p,
  body.blog-pdf .prose li { orphans: 2; widows: 2; }

  /* Print background colors (callouts, accents). */
  body.blog-pdf * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  @page { margin: 0.55in; }
}

/* Print-only chrome: hidden on screen, revealed by the @media print block. */
.print-brandbar, .print-footer { display: none; }
