/*
 * Public marketing site — blog article typography (PROKURIO-OWNED).
 *
 * ONE of three ownership-scoped stylesheets split out of the former single
 * public.css (PRO-4814). All three are linked, in this order, by
 * marketing/base_public.html:
 *
 *     public-chrome.css   site chrome + design tokens   PROKURIO
 *     public-prose.css    blog article typography       PROKURIO
 *     public-pages.css    marketing page components     AGENCY
 *
 * The split exists so the external marketing agency can own the page
 * components without being able to alter the blog or the site chrome. Keep the
 * boundary honest: a rule belongs to the file that owns the thing it styles,
 * not to the file it is most convenient to add it to.
 *
 * THIS FILE IS PROKURIO-OWNED (owner direction, 2026-07-25: the agency advises
 * on the marketing pages; blog styling is ours). It is mirrored read-only into
 * the marketing-site repo; their CI rejects any PR that modifies it.
 *
 * Contents: the .pw-prose typographic stylesheet that wraps BlogPost.body, plus
 * the blog index cards and the blog detail article chrome. It was tuned against
 * the real 399-post corpus (PRO-4074, PRO-4077) — changing it re-styles every
 * imported article, so verify against real posts, not just a fixture. The
 * original block comment below is preserved verbatim; read it before editing.
 */

/* ═══════════════════════════════════════════════════════════════════
 * Prose — long-form article body (PRO-4074)
 *
 * The typographic stylesheet for `.pw-prose`, which wraps `BlogPost.body` on
 * the post detail page (marketing/blog_detail.html — the ONLY user of this
 * block). Everything below styles ELEMENTS, never class names.
 *
 * WHY ELEMENTS ONLY. Two write paths feed `body` and they agree on nothing but
 * semantics:
 *   * The 399 imported WordPress posts (Phase 4a) come out of Elementor. The
 *     import cleanup unwraps the builder scaffolding and the sanitiser strips
 *     `data-*`. Elements carried a further ~2.5k surviving `class` attributes
 *     — WP-editor and Notion/Docs paste artifacts (`OYPEnA`,
 *     `font-claude-response-body`, `whitespace-normal`, `td-content-wrapper`)
 *     that vary post to post and mean nothing without the stylesheet they came
 *     from; PRO-4074 Part 2 strips them at import, keeping only
 *     `wp-image-<id>` (834 of them, the media-library link Phase 4b needs).
 *     Nothing here may key off either the removed artifacts or that one
 *     survivor.
 *   * Posts authored from here on come from CKEditor, which emits bare
 *     semantic HTML with no classes at all.
 * An element selector is the only thing both paths share, so nothing here may
 * key off a legacy class.
 *
 * Measured against the real corpus (399 posts, 2022-05 → 2026-06, counted on
 * the cleaned + sanitised bodies): 4,271 p · 1,300 h2 · 384 h3 · 59 h4 ·
 * 110 h5 · 1,069 img (in 372 posts) · 1,359 li · 571 ul · 20 ol · 34 table
 * (in 18 posts; 19 with a thead, 14 with no th at all, max 7 columns) ·
 * 1,413 strong · 589 a · 1 blockquote · 0 pre/code/figure/hr/iframe. The
 * zero-count elements are still styled: they are exactly what a CKEditor
 * author will reach for next.
 *
 * `h1` is the page title in the template header, OUTSIDE this wrapper — the
 * body's top heading level is `h2`, so the scale starts there.
 *
 * RESOLVED CONFLICT (PRO-4074 Part 2, importer-side — deliberately never fixed
 * here): 704 `<span style="font-weight:400">` wrappers used to survive the
 * import and would beat every `font-weight` rule below on specificity, being
 * inline styles. They are NOT worked around with `!important`; the import
 * normalisation drops the no-op declaration at write time instead, so the
 * weight rules below are unopposed. Two `font-weight:600` spans inside an `h2`
 * remain by design — 600 is authored intent, not a restated default.
 * ═══════════════════════════════════════════════════════════════════ */
.pw-prose {
  /* One rhythm scale for the whole article, so a change lands everywhere. */
  --pw-prose-flow: 1.2em; /* gap between consecutive blocks */
  --pw-prose-lead: 2.1em; /* extra space above a new section heading */

  /* Controlled break-out (PRO-4074 round 2): how far a table/image may reach
     PAST the text measure on each side. Self-limiting, so no media query and
     no possibility of horizontal page overflow:
       * (100vw − medium tier) / 2  is the free space outside the capped
         container, and + --pw-gutter reclaims the container's own padding;
       * −24px keeps a classic desktop scrollbar (which 100vw includes but the
         viewport does not actually offer) from turning the last pixels into a
         sideways scroll;
       * clamp()'s lower bound zeroes the whole thing below the cap — at 375px
         the expression is deeply negative, so a phone gets no break-out at all
         and the Part 1 mobile measurements stand unchanged.
     110px is the upper bound: enough for the corpus' 7-column table and its
     140 full-width images, not so much that media stops belonging to the text. */
  --pw-prose-breakout: clamp(
    0px,
    calc((100vw - var(--aif-width-medium)) / 2 + var(--pw-gutter) - 24px),
    110px
  );

  font-size: 1.125rem;
  line-height: 1.75;
  /* Article body is near-black, not muted: `--aif-text-muted` is right for a
     marketing lede but too light to read 2,000 words of. Muted is reserved
     below for captions, table captions and small print. */
  color: var(--aif-text);
  /* The measure comes from the container tier — blog_detail.html renders this
     inside .pw-container--medium (--aif-width-medium), which lands at 1,020px
     on a 1,920px monitor. That is deliberate and measured, not a guess: the
     live WordPress article this replaces sets its own paragraphs to 1,000px at
     18px, and the narrow tier used in Part 1 rendered a 640px ribbon in the
     middle of a 1,920px screen — the owner's actual complaint. Media then
     breaks out beyond this measure (see --pw-prose-breakout above), so a wide
     table gets room the paragraphs do not need. */
  max-width: 100%;
  /* Imported bodies contain bare tracking URLs; a long unbroken token must
     wrap rather than widen the page on a phone. */
  overflow-wrap: break-word;
}

/* The opening paragraph reads as a stand-first. Scoped to `:first-child` (197
   of the 399 imported posts open with a root `p`) rather than `:first-of-type`,
   which would promote an arbitrary mid-article paragraph on the posts that open
   with a heading. The post EXCERPT is deliberately not rendered here as a
   stand-first instead: 273 of the 399 excerpts are WordPress auto-excerpts that
   simply repeat the first ~55 words of the body. */
.pw-prose > p:first-child {
  font-size: 1.18em;
  line-height: 1.6;
  color: var(--aif-text);
}

/* Baseline flow. Deliberately NOT `.pw-prose > *`: 26 `div` wrappers still
   survive the import (17 of them schema.org microdata around a table), and a
   descendant selector keeps their contents in rhythm too. `div` itself gets no
   margin — it is a transparent wrapper. */
.pw-prose p,
.pw-prose ul,
.pw-prose ol,
.pw-prose dl,
.pw-prose pre,
.pw-prose table,
.pw-prose blockquote,
.pw-prose figure,
.pw-prose address {
  margin-block: 0 var(--pw-prose-flow);
}

/* ── Headings — the scale starts at h2 ─────────────────────────── */
.pw-prose h2,
.pw-prose h3,
.pw-prose h4,
.pw-prose h5,
.pw-prose h6 {
  color: var(--aif-text);
  font-weight: 700;
  line-height: 1.25;
  text-wrap: balance;
  margin-block: var(--pw-prose-lead) 0.5em;
}

/* A section break, not just a bigger line of text: a hairline across the
   measure with a short brand-tint segment on its left end. The tint is a
   STRIPE behind nothing — never text — which is the sanctioned use of the light
   brand hues (design system §2). With 1,300 `h2`s across the corpus this is the
   one device that makes a long fee-update post scannable. */
.pw-prose h2 {
  position: relative;
  font-size: clamp(1.7rem, 2.4vw, 2.15rem);
  letter-spacing: -0.015em;
  padding-top: 0.62em;
  border-top: 1px solid var(--aif-border);
}

.pw-prose h2::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 52px;
  height: 3px;
  border-radius: 2px;
  background: var(--aif-teal);
}

/* An article that opens on a heading must not start with a stray rule under
   the cover image. */
.pw-prose > h2:first-child {
  padding-top: 0;
  border-top: 0;
}

.pw-prose > h2:first-child::before {
  content: none;
}

.pw-prose h3 {
  font-size: clamp(1.3rem, 1.9vw, 1.55rem);
  letter-spacing: -0.008em;
}

.pw-prose h4 {
  font-size: 1.2rem;
}

.pw-prose h5,
.pw-prose h6 {
  font-size: 1.05rem;
}

/* Adjacency: a heading already owns the gap below it, so the block that
   follows must not add its own on top. Stacked headings (h2 → h3 opening a
   subsection) tighten instead of taking the full section lead. */
.pw-prose h2 + *,
.pw-prose h3 + *,
.pw-prose h4 + *,
.pw-prose h5 + *,
.pw-prose h6 + * {
  margin-top: 0;
}

.pw-prose h2 + h3,
.pw-prose h2 + h4,
.pw-prose h3 + h4,
.pw-prose h4 + h5,
.pw-prose h5 + h6 {
  margin-top: 0.8em;
}

/* The article opens and closes flush with the wrapper. `:first-child` /
   `:last-child` outrank the element rules above on specificity, so this holds
   wherever it sits in the file. */
.pw-prose > :first-child {
  margin-top: 0;
}

.pw-prose > :last-child {
  margin-bottom: 0;
}

/* ── Inline text ───────────────────────────────────────────────── */
.pw-prose a {
  color: var(--aif-accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--aif-accent-glow);
  text-underline-offset: 0.18em;
  transition:
    color 0.15s ease,
    text-decoration-color 0.15s ease;
}

.pw-prose a:hover {
  color: var(--aif-accent-hover);
  text-decoration-color: currentcolor;
}

.pw-prose a:focus-visible {
  outline: 2px solid var(--aif-accent);
  outline-offset: 3px;
  border-radius: 3px;
}

.pw-prose strong,
.pw-prose b {
  font-weight: 700;
  color: var(--aif-text);
}

.pw-prose em,
.pw-prose i {
  font-style: italic;
}

.pw-prose mark {
  background: var(--aif-accent-chip);
  color: var(--aif-text);
  padding: 0 0.2em;
  border-radius: 3px;
}

.pw-prose abbr[title] {
  text-decoration: underline dotted;
  cursor: help;
}

.pw-prose sub,
.pw-prose sup {
  font-size: 0.75em;
  line-height: 0;
}

.pw-prose small {
  font-size: 0.875em;
  color: var(--aif-text-muted);
}

/* ── Lists ─────────────────────────────────────────────────────── */
.pw-prose ul,
.pw-prose ol {
  padding-left: 1.5em;
}

.pw-prose li {
  margin-block: 0 0.4em;
}

/* Steel blue, not dim grey — a saturated brand hue is legible as a glyph and
   gives a 121-item list some structure. (The LIGHT tints stay off text/glyphs.) */
.pw-prose li::marker {
  color: var(--aif-brand-steel);
}

/* A nested list belongs to its parent item, not to the flow. */
.pw-prose li > ul,
.pw-prose li > ol {
  margin-block: 0.4em 0;
}

.pw-prose li > p {
  margin-bottom: 0.4em;
}

.pw-prose li > p:last-child {
  margin-bottom: 0;
}

.pw-prose ul ul {
  list-style-type: circle;
}

.pw-prose ul ul ul {
  list-style-type: square;
}

.pw-prose ol ol {
  list-style-type: lower-alpha;
}

.pw-prose ol ol ol {
  list-style-type: lower-roman;
}

.pw-prose dt {
  font-weight: 700;
  color: var(--aif-text);
}

.pw-prose dd {
  margin-inline-start: 1.5em;
  margin-bottom: 0.5em;
}

/* ── Images and embedded media ─────────────────────────────────── */
/* The sanitiser drops `srcset`/`sizes` (bleach cannot enforce its protocol
   allowlist inside `srcset`), so the browser always fetches the full-size
   original — often 2x the column. Without this cap every one of the 1,069
   in-body images overflows. `height: auto` is required alongside it because
   832 of them still carry the intrinsic `width`/`height` attributes. */
.pw-prose img {
  max-width: 100%;
  height: auto;
}

/* A standalone image gets block layout, centring and its own rhythm: 1,066 of
   the 1,069 imported images sit directly at the prose root, and CKEditor wraps
   a block image in `<figure>`. An image inline in a sentence keeps inline
   flow, so no selector here matches `p img` with text beside it.
   NOTE: `loading="lazy"` cannot be added from CSS and these `<img>` tags come
   from the database, not from a template — deferring image loads is an
   importer/authoring concern, not this stylesheet's. */
.pw-prose > img,
.pw-prose > a > img,
.pw-prose > div > img,
.pw-prose figure > img {
  display: block;
  margin-inline: auto;
  border-radius: var(--aif-radius-sm);
}

.pw-prose > img,
.pw-prose > a > img,
.pw-prose > div > img {
  margin-block: 1.9em;
}

.pw-prose figure {
  margin-inline: 0;
}

.pw-prose figcaption {
  margin-top: 0.7em;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--aif-text-muted);
  text-align: center;
}

.pw-prose iframe,
.pw-prose video {
  display: block;
  max-width: 100%;
  margin-block: 1.75em;
  border: 0;
  border-radius: var(--aif-radius-sm);
}

.pw-prose iframe {
  width: 100%;
  aspect-ratio: 16 / 9;
}

/* ── Pull-quote ────────────────────────────────────────────────── */
/* A quote should read as a change of voice, not as an indented paragraph. The
   light teal is used the only way it is allowed to be — as a STRIPE and a very
   low-opacity FILL behind dark text (design system §2). The opening glyph uses
   `--aif-teal-deep`, which exists precisely as the readable-on-tint partner to
   the light tint, and the quote text itself stays `--aif-text`. */
.pw-prose blockquote {
  margin-inline: 0;
  padding: 20px 26px;
  border-left: 4px solid var(--aif-teal);
  border-radius: 0 var(--aif-radius) var(--aif-radius) 0;
  background: color-mix(in srgb, var(--aif-teal) 9%, var(--aif-surface));
  color: var(--aif-text);
  font-size: 1.18em;
  line-height: 1.6;
}

.pw-prose blockquote::before {
  content: "\201C";
  display: block;
  font-size: 2.6em;
  line-height: 0.72;
  font-weight: 700;
  color: var(--aif-teal-deep);
}

.pw-prose blockquote > :last-child {
  margin-bottom: 0;
}

/* ── Code ──────────────────────────────────────────────────────── */
.pw-prose code,
.pw-prose kbd,
.pw-prose samp,
.pw-prose var {
  font-family: var(--pw-mono);
  font-size: 0.9em;
  font-style: normal;
  background: var(--aif-surface-2);
  border: 1px solid var(--aif-border);
  border-radius: 4px;
  padding: 0.1em 0.35em;
}

.pw-prose pre {
  font-family: var(--pw-mono);
  font-size: 0.9rem;
  line-height: 1.55;
  background: var(--aif-surface-2);
  border: 1px solid var(--aif-border);
  border-radius: var(--aif-radius-sm);
  padding: 16px 18px;
  overflow-x: auto;
}

.pw-prose pre code {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  font-size: inherit;
}

/* ── Rule ──────────────────────────────────────────────────────── */
.pw-prose hr {
  height: 0;
  border: 0;
  border-top: 1px solid var(--aif-border);
  margin-block: 2.4em;
}

/* ── Tables ────────────────────────────────────────────────────── */
/* Mobile survival, without a wrapper element. These tables come out of the
   database, so no template can wrap them in a scroll container — `display:
   block` + `overflow-x: auto` turns the table element itself into that
   container. The rows keep their table display roles, so the browser
   regenerates an anonymous table box inside and real table layout is
   preserved; a table wider than the column scrolls instead of pushing the
   whole page sideways. `border-collapse` inherits into the anonymous box. */
.pw-prose table {
  display: block;
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  /* Swiping a table sideways must not drag the page with it, and a thin
     always-styled scrollbar is the only affordance available without a wrapper
     element (a gradient "more content" shade would be painted over by the
     header/zebra cell backgrounds). */
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--aif-border-light) transparent;
  border-collapse: collapse;
  font-size: 0.95rem;
  line-height: 1.45;
}

.pw-prose th,
.pw-prose td {
  border: 1px solid var(--aif-border);
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
}

/* 14 of the 34 imported tables have no `th` at all and put their header row in
   a `thead` of `td`, so the header treatment keys off both. */
.pw-prose th,
.pw-prose thead td {
  background: var(--aif-surface-2);
  color: var(--aif-text);
  font-weight: 700;
  white-space: nowrap;
}

.pw-prose tbody tr:nth-child(even) td {
  background: var(--aif-bg);
}

.pw-prose caption {
  caption-side: bottom;
  padding-top: 0.7em;
  font-size: 0.9rem;
  color: var(--aif-text-muted);
  text-align: left;
}

/* ── Controlled break-out ──────────────────────────────────────── */
/* Standalone media may reach past the text measure by --pw-prose-breakout on
 * each side, so a screenshot or the corpus' 7-column table gets room while the
 * paragraphs keep a comfortable measure. Last in the block ON PURPOSE: these
 * selectors carry the same specificity as the `.pw-prose img/table/iframe`
 * rules above, so only source order lets the break-out win.
 *
 * WHY left/transform AND NOT negative margins. A negative `margin-inline` is
 * exact only for something that always fills its box (a table — already
 * `width: 100%`). An `img` is intrinsically sized: the corpus' median in-body
 * image is 800px wide and only 140 of 832 reach 1,020px, so most are NARROWER
 * than the column. Negative margins would shove every one of those off to the
 * left; `left: 50%` + `translateX(-50%)` centres any used width — broken out or
 * not — against the same origin. `max-width` (not `width`) on the images is
 * what keeps an 800px original from being upscaled to 1,240px.
 *
 * Excluded deliberately: `.pw-prose > a > img` (2 images, wrapped in an INLINE
 * `a`, where offsetting the child would detach it from its link box), the one
 * table nested in a `ul > li`, `pre` (it already scrolls, and code belongs on
 * the text measure), and anything inside a blockquote. On a phone
 * --pw-prose-breakout clamps to 0, so every rule here is a no-op and the Part 1
 * 375px measurements stand. */
.pw-prose > img,
.pw-prose > div > img,
.pw-prose > figure,
.pw-prose > iframe,
.pw-prose > video,
.pw-prose > table,
.pw-prose > div > table {
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  margin-inline: 0;
  max-width: calc(100% + 2 * var(--pw-prose-breakout));
}

/* Things that always fill their box take the extra width outright; the images
   above stay intrinsically sized under the same cap. */
.pw-prose > figure,
.pw-prose > iframe,
.pw-prose > video {
  width: calc(100% + 2 * var(--pw-prose-breakout));
}

/* A table takes only the width it actually needs. Measured: forcing the full
   break-out width on every table left the narrow ones (a 2×7 currency grid
   wants ~590px) rendered as a short run of cells starting 110px LEFT of the
   text — technically wider, visibly misaligned. `fit-content` between a
   `min-width` of the text measure and a `max-width` of the broken-out measure
   means a narrow table lines up with the paragraphs exactly as before, and only
   a genuinely wide one spends the extra room. Past that it still scrolls
   in-place (`overflow-x: auto` above), so nothing pushes the page sideways. */
.pw-prose > table,
.pw-prose > div > table {
  width: fit-content;
  min-width: 100%;
}

/* ── Narrow viewports ──────────────────────────────────────────── */
@media (max-width: 600px) {
  .pw-prose {
    --pw-prose-flow: 1.1em;
    --pw-prose-lead: 1.75em;

    /* 17px on a phone: one step down from the desktop 18px, one step up from
       the 16px Part 1 measured, and still comfortably above the 343px column's
       readable floor. */
    font-size: 1.0625rem;
  }

  .pw-prose > p:first-child {
    font-size: 1.1em;
  }

  .pw-prose blockquote {
    padding: 16px 18px;
  }

  .pw-prose ul,
  .pw-prose ol {
    padding-left: 1.25em;
  }

  .pw-prose th,
  .pw-prose td {
    padding: 8px 10px;
  }

  /* Let header labels wrap on a phone. Measured on the imported tables, this
     is the difference between a table that needs sideways scrolling and one
     that fits the column outright (e.g. 462px → 353px against a 343px
     column); the nowrap above is a desktop nicety, not worth the scroll. */
  .pw-prose th,
  .pw-prose thead td {
    white-space: normal;
  }

  .pw-prose table {
    font-size: 0.9rem;
  }
}

/* ── Blog (PRO-4059) ───────────────────────────────────────────── */
/* Index: reuses .pw-grid-3 + .pw-card; these add the cover image, meta line
   and hover affordance. Colour resolves only through --aif-* tokens. */
.pw-blog-grid {
  margin-top: 8px;
}

.pw-post-card {
  padding: 0;
  overflow: hidden;
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease;
}

.pw-post-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--pw-shadow);
}

.pw-post-card__link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.pw-post-card__img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--aif-surface-2);
}

.pw-post-card__body {
  padding: 22px 24px 24px;
}

.pw-post-card__body h3 {
  margin: 0 0 0.4em;
  color: var(--aif-text);
}

.pw-post-card__more {
  display: inline-block;
  margin-top: 14px;
  font-weight: 600;
  color: var(--aif-accent);
}

.pw-post-meta {
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--aif-text-dim);
  margin: 0 0 0.6em;
}

.pw-post-meta__sep {
  margin-inline: 0.4em;
}

/* Index pagination (PRO-4065) — the imported archive is 399 posts, so the index
   is paged. Neutral outlined controls in the same idiom as .pw-btn--secondary,
   with the current page as the one accent-filled chip; all colour resolves
   through --aif-* tokens and the control is plain links (no JS). */
.pw-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 40px;
}

.pw-pagination__pages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.pw-page-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  padding: 0.55em 0.85em;
  border: 1px solid var(--aif-border-light);
  border-radius: var(--aif-radius-sm);
  background: var(--aif-surface);
  color: var(--aif-text);
  font-weight: 600;
  font-size: 0.92rem;
  line-height: 1.2;
  text-decoration: none;
  transition:
    background 0.15s ease,
    border-color 0.15s ease;
}

a.pw-page-link:hover {
  background: var(--aif-surface-hover);
  color: var(--aif-text);
  text-decoration: none;
}

.pw-page-link--current {
  background: var(--aif-accent);
  border-color: var(--aif-accent);
  color: var(--aif-on-accent);
}

.pw-page-link--disabled {
  background: var(--aif-surface-2);
  color: var(--aif-text-dim);
}

.pw-page-ellipsis {
  padding-inline: 4px;
  color: var(--aif-text-dim);
}

.pw-pagination__status {
  flex-basis: 100%;
  text-align: center;
  margin: 6px 0 0;
  font-size: 0.9rem;
  color: var(--aif-text-muted);
}

/* ── Detail article (PRO-4074 round 2) ─────────────────────────── */
/* The header is a composed masthead, not three stacked marketing elements: a
   full-bleed tinted band separates the article's identity (eyebrow, title,
   byline) from its body, and a short brand bar gives the page a deliberate
   opening mark. Everything else on the page stays a neutral surface. */
/* The masthead is flush against the nav, so the article owns only its bottom
   padding — it is not a .pw-section. */
.pw-article {
  padding-bottom: clamp(48px, 8vw, 96px);
}

/* Reviewer preview banner (PRO-4063) — only ever rendered on the admin site's
   preview route, never on a public page. Gold as a FILL with dark text, per the
   design system's legibility rule for the light accent tints. */
.pw-article__preview-banner {
  position: sticky;
  top: 0;
  z-index: 10;
  margin: 0;
  padding: 10px var(--pw-gutter);
  background: var(--aif-gold);
  color: var(--aif-ink); /* stays dark in both themes, unlike --aif-text */
  text-align: center;
  font-size: 0.95rem;
}

.pw-article__masthead {
  background: var(--aif-bg);
  border-bottom: 1px solid var(--aif-border);
  padding-block: clamp(36px, 5vw, 68px) clamp(30px, 4vw, 52px);
  margin-bottom: clamp(30px, 4vw, 52px);
}

.pw-article__header {
  margin-bottom: 0;
}

/* Three sanctioned brand hues as a FILL (never as text): strong blue, teal,
   gold. One instance per page — the article's opening mark. */
.pw-article__header::before {
  content: "";
  display: block;
  width: 92px;
  height: 4px;
  border-radius: 2px;
  margin-bottom: 22px;
  background: linear-gradient(
    90deg,
    var(--aif-accent) 0 34%,
    var(--aif-teal) 34% 67%,
    var(--aif-gold) 67% 100%
  );
}

.pw-article__masthead .pw-eyebrow {
  margin-bottom: 0.6em;
}

.pw-article__title {
  font-size: clamp(2.15rem, 3.9vw, 3.35rem);
  line-height: 1.08;
  letter-spacing: -0.025em;
  /* A headline that runs the full 1,020px measure reads as a paragraph. */
  max-width: 22ch;
  margin-bottom: 0.5em;
  text-wrap: balance;
}

.pw-article__masthead .pw-post-meta {
  margin-bottom: 0;
  color: var(--aif-text-muted);
}

/* Cover image. `aspect-ratio` + `contain` reserves the box before the image
   loads (no layout shift) WITHOUT cropping: measured across the 315 distinct
   featured images the corpus uses, the ratio spread is 0.67 → 5.56 with a
   median of exactly 1.50, so 3/2 fits half of them perfectly and mats the rest
   against the second surface tint. `cover` would silently crop the charts and
   fee tables that many of these images actually are. */
.pw-article__cover {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: contain;
  background: var(--aif-surface-2);
  border-radius: var(--aif-radius-lg);
  border: 1px solid var(--aif-border);
  margin-bottom: clamp(28px, 4vw, 44px);
}

.pw-article__back {
  margin-top: clamp(36px, 5vw, 56px);
  padding-top: clamp(24px, 3vw, 32px);
  border-top: 1px solid var(--aif-border);
}


/* ==========================================================================
   HELP CENTRE (PRO-5865, Phase 6)
   ==========================================================================
   The BetterDocs help centre migrated onto our own routes at /help/. It lives
   in THIS sheet, not public-pages.css, for the same reason the blog does: it is
   Prokurio-owned long-form content and the agency must not be able to restyle
   an imported support article. `test_stylesheet_ownership` enforces that.

   Every colour, space and radius resolves through the --aif-* tokens declared
   in public-chrome.css — no raw hex, per the Nextgen design system.
   ========================================================================== */

.pw-help-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Search --------------------------------------------------------------- */

.pw-help-search {
  display: flex;
  gap: var(--aif-space-2, 0.5rem);
  max-width: 34rem;
  margin: var(--aif-space-4, 1rem) auto 0;
}

.pw-help-search__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.65rem 0.9rem;
  font: inherit;
  color: var(--aif-text);
  background: var(--aif-surface);
  border: 1px solid var(--aif-border);
  border-radius: var(--aif-radius-md, 8px);
}

.pw-help-search__input:focus-visible {
  outline: 2px solid var(--aif-accent);
  outline-offset: 1px;
}

.pw-help-search__button {
  flex: 0 0 auto;
}

/* Two-column shell ------------------------------------------------------ */

.pw-help-layout {
  display: grid;
  grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
  gap: var(--aif-space-8, 2rem);
  align-items: start;
}

@media (max-width: 62rem) {
  .pw-help-layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

.pw-help-layout__main {
  min-width: 0;
}

/* Category navigation --------------------------------------------------- */

.pw-help-nav {
  position: sticky;
  top: var(--aif-space-6, 1.5rem);
  padding: var(--aif-space-4, 1rem);
  background: var(--aif-surface);
  border: 1px solid var(--aif-border);
  border-radius: var(--aif-radius-lg, 12px);
}

.pw-help-nav__group + .pw-help-nav__group {
  margin-top: var(--aif-space-5, 1.25rem);
}

.pw-help-nav__kb {
  margin: 0 0 var(--aif-space-2, 0.5rem);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--aif-text-muted);
}

.pw-help-nav__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.pw-help-nav__link {
  display: flex;
  justify-content: space-between;
  gap: var(--aif-space-2, 0.5rem);
  padding: 0.35rem 0.5rem;
  border-radius: var(--aif-radius-sm, 6px);
  color: var(--aif-text);
  text-decoration: none;
}

.pw-help-nav__link:hover,
.pw-help-nav__link.is-current {
  background: var(--aif-surface-hover);
  color: var(--aif-accent);
}

.pw-help-nav__count {
  flex: 0 0 auto;
  color: var(--aif-text-muted);
  font-variant-numeric: tabular-nums;
}

/* Breadcrumb ------------------------------------------------------------ */

.pw-help-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: var(--aif-space-2, 0.5rem);
  margin-bottom: var(--aif-space-4, 1rem);
  font-size: 0.88rem;
  color: var(--aif-text-muted);
}

.pw-help-breadcrumb a {
  color: var(--aif-accent);
}

/* On the agency's dark navy .pw-hero (PRO-6983) the light-page colours above —
   muted grey text, accent-blue links, dim meta — fall far below AA. Same
   grey-blue as the hero lede in public-chrome.css; links go white and keep an
   underline so they still read as links. */
.pw-hero .pw-help-breadcrumb,
.pw-hero .pw-post-meta {
  color: var(--aif-grey-blue);
}

.pw-hero .pw-help-breadcrumb a {
  color: var(--aif-on-accent);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Category cards and result lists --------------------------------------- */

.pw-help-kb + .pw-help-kb {
  margin-top: var(--aif-space-8, 2rem);
}

.pw-help-kb__title {
  margin-bottom: var(--aif-space-4, 1rem);
}

.pw-help-card {
  display: block;
  padding: var(--aif-space-5, 1.25rem);
  color: inherit;
  text-decoration: none;
}

.pw-help-card__title {
  margin: 0 0 var(--aif-space-2, 0.5rem);
  font-size: 1.05rem;
}

.pw-help-card__lede {
  margin: 0 0 var(--aif-space-2, 0.5rem);
  color: var(--aif-text-muted);
}

.pw-help-card__count {
  margin: 0;
  font-size: 0.85rem;
  color: var(--aif-text-muted);
}

.pw-help-results {
  margin: var(--aif-space-4, 1rem) 0 0;
  padding: 0;
  list-style: none;
}

.pw-help-results__heading {
  margin-bottom: var(--aif-space-2, 0.5rem);
}

.pw-help-results__item {
  padding: var(--aif-space-4, 1rem) 0;
  border-bottom: 1px solid var(--aif-border);
}

.pw-help-results__link {
  font-weight: 600;
  color: var(--aif-accent);
}

.pw-help-results__excerpt {
  margin: 0.35rem 0 0;
  color: var(--aif-text-muted);
}

.pw-help-empty {
  color: var(--aif-text-muted);
}

/* Table of contents ----------------------------------------------------- */

.pw-help-toc {
  margin: var(--aif-space-5, 1.25rem) 0;
  padding: var(--aif-space-4, 1rem) var(--aif-space-5, 1.25rem);
  background: var(--aif-bg);
  border-radius: var(--aif-radius-lg, 12px);
}

.pw-help-toc__title {
  margin: 0 0 var(--aif-space-2, 0.5rem);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--aif-text-muted);
}

.pw-help-toc__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.pw-help-toc__item--h3 {
  padding-left: var(--aif-space-4, 1rem);
}

/* Previous / next ------------------------------------------------------- */

.pw-help-pager {
  display: flex;
  flex-wrap: wrap;
  gap: var(--aif-space-4, 1rem);
  margin-top: var(--aif-space-8, 2rem);
  padding-top: var(--aif-space-5, 1.25rem);
  border-top: 1px solid var(--aif-border);
}

.pw-help-pager__link {
  flex: 1 1 14rem;
  padding: var(--aif-space-4, 1rem);
  border: 1px solid var(--aif-border);
  border-radius: var(--aif-radius-lg, 12px);
  color: inherit;
  text-decoration: none;
}

.pw-help-pager__link--next {
  text-align: right;
}

.pw-help-pager__label {
  display: block;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--aif-text-muted);
}

.pw-help-pager__title {
  display: block;
  font-weight: 600;
  color: var(--aif-accent);
}

/* Reviewer preview banner (PRO-5876) — shown only on /help/preview/<token>/,
   so a reviewer reading an unpublished draft can never mistake it for the live
   article. Warning-toned on purpose: the message is "this is not public yet",
   not a decorative note. Uses the shared --aif-* tokens, no raw hex. */
.pw-help-preview-banner {
  margin: 0 0 var(--aif-space-4, 1rem);
  padding: 0.75rem 1rem;
  border: 1px solid var(--aif-warning-border, var(--aif-border));
  border-left-width: 4px;
  border-radius: var(--aif-radius-sm, 6px);
  background: var(--aif-warning-soft, var(--aif-surface-muted));
  color: var(--aif-text);
  font-size: 0.92rem;
  line-height: 1.5;
}
