/* blog.css — editorial + knowledge-base components for the content engine.
   Premium dark treatment: NO borders anywhere (no hairlines, no accent left-bars).
   Depth comes from a continuous story-arc gradient, surface fills and soft
   elevation. Accent shows only in eyebrows, links, small dots and hover states.
   The page sets --accent-h/-s/-l inline (per collection). Full site width (1600). */

.post,
.hub,
.author-page {
    --post-accent: hsl(var(--accent-h, 205), 82%, 64%);
    --post-accent-soft: hsla(var(--accent-h, 205), 82%, 60%, 0.12);
    --post-measure: 820px;
    --post-container: var(--wide-width);   /* 1600, matches the homepage .container */
    /* ONE width for BOTH sticky sidebars (the contents card and the author +
       CTA rail) — they must never read as two differently-sized columns. This is
       only the CAP: in the three-column reading layout the two rails SPLIT the
       space the reading measure leaves over, equally, so they stay identical at
       every viewport (see .post-layout below). */
    --post-side-max: 300px;
    --box-fill: var(--color-surface-elevated);
    --box-elev: 0 1px 2px rgba(0, 0, 0, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.04);
    --box-elev-hover: 0 18px 44px -20px rgba(0, 0, 0, 0.75), inset 0 1px 0 rgba(255, 255, 255, 0.06);
    color: var(--color-text);
    background: var(--color-bg);   /* solid; the ambient glow is a masked ::before */
    padding-bottom: 0;
    position: relative;
    isolation: isolate;
}

/* ---------- ambient accent glow ----------
   ONE continuous, mask-faded halo behind the whole hero region (breadcrumb,
   title, byline AND the lead image). Because it fades to transparent long before
   its own bottom edge, there is no hard seam where a band ends, and because it
   sits at z-index 0 (content is lifted to z-index 1) it never paints on top of
   the article image. The bloom is centred ~360px down so the top stays dark
   under the site header's fixed glass panel. */
.post::before,
.hub::before,
.author-page::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: clamp(760px, 82vh, 1180px);
    z-index: 0;
    pointer-events: none;
    background:
        radial-gradient(1500px 680px at 26% 360px,
            hsla(var(--accent-h, 205), 62%, 20%, 0.55), transparent 64%),
        radial-gradient(940px 500px at 92% 200px,
            hsla(calc(var(--accent-h, 205) + 24), 56%, 18%, 0.28), transparent 70%);
    /* long, soft fall-off so the light bleeds into the top of the card grid
       instead of dying at a hard black cliff below the hero */
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 60%, transparent 100%);
            mask-image: linear-gradient(180deg, #000 0%, #000 60%, transparent 100%);
}
.post > *,
.hub > *,
.author-page > * {
    position: relative;
    z-index: 1;
}

.post-container {
    max-width: var(--post-container);
    margin: 0 auto;
    padding: 0 var(--space-xl);
}

/* ---------- hero band ---------- */
/* No background of its own now — the glow lives on .post/.hub::before so it can
   run continuously behind the band and the lead image without a clip seam. */
.post-hero-band {
    position: relative;
    padding: 8rem 0 var(--space-2xl);
}

.breadcrumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    margin-bottom: var(--space-xl);
}
.breadcrumbs a { color: var(--color-text-muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--post-accent); }
.breadcrumbs__sep { color: var(--color-border-light); }
.breadcrumbs [aria-current="page"] { color: var(--color-text-secondary); }

.post-hero { max-width: 1200px; }
.post-eyebrow {
    display: inline-block;
    font-size: var(--text-xs);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--post-accent);
    margin-bottom: var(--space-md);
}
.post-hero__title {
    font-size: clamp(2.2rem, 5.2vw, 3.6rem);
    line-height: 1.12;
    font-weight: 800;
    letter-spacing: -0.018em;
    margin: 0 0 var(--space-md);
    text-wrap: balance;
}
.post-hero__standfirst {
    font-size: clamp(1.15rem, 2.1vw, 1.45rem);
    line-height: 1.5;
    color: var(--color-text-secondary);
    max-width: 720px;
    margin: 0 0 var(--space-lg);
}
.post-byline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm) var(--space-lg);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    padding-top: var(--space-sm);
}
.post-byline a { color: var(--color-text-secondary); text-decoration: none; font-weight: 600; }
.post-byline a:hover { color: var(--post-accent); }
.post-byline > span { display: inline-flex; align-items: center; }
.post-byline__avatar {
    width: 34px; height: 34px;
    border-radius: var(--radius-full);
    object-fit: cover;
    margin-right: var(--space-sm);
}
.post-byline__icon { margin-right: 0.45em; opacity: 0.6; flex-shrink: 0; }
/* a small dot only BETWEEN the top-level groups (author · dates · read) */
.post-byline > span:not(:first-child)::before {
    content: "";
    display: inline-block;
    width: 3px; height: 3px;
    border-radius: 50%;
    background: var(--color-border-light);
    margin-right: var(--space-lg);
    flex-shrink: 0;
}

/* ---------- hero figure (full container width) ---------- */
/* Sits between the table of contents and the body copy, same spacing rhythm
   as the other stacked overview blocks above it. */
.post-hero__figure { margin: 0 0 var(--space-2xl); }
.post-hero__figure img {
    width: 100%; height: auto;
    object-fit: cover;
    border-radius: var(--radius-4xl);
    display: block;
    box-shadow: var(--shadow-xl);
}
.post-hero__figure figcaption,
.post-figure figcaption,
.post-video__figure figcaption {
    margin-top: var(--space-sm);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    text-align: center;
}
.post-video__figure figcaption a { color: var(--color-primary-light); }
.post-img-placeholder {
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-3xl);
    background:
        radial-gradient(80% 120% at 100% 0%, hsla(var(--accent-h, 205), 55%, 24%, 0.6), transparent 60%),
        linear-gradient(135deg, hsla(var(--accent-h, 205), 45%, 16%, 0.6), hsla(var(--accent-h, 205), 40%, 8%, 0.75));
}
.post-hero__figure .post-img-placeholder { max-height: 460px; aspect-ratio: 21 / 8; border-radius: var(--radius-4xl); box-shadow: var(--shadow-xl); }

/* an author photo that hasn't been uploaded yet gets this instead of a
   broken-image icon; width/height/radius come from the paired avatar class
   (.post-byline__avatar or .arc-author__avatar), this just supplies the fill */
.post-avatar-placeholder {
    background:
        radial-gradient(80% 120% at 100% 0%, hsla(var(--accent-h, 205), 55%, 30%, 0.55), transparent 60%),
        linear-gradient(135deg, hsla(var(--accent-h, 205), 45%, 20%, 0.6), hsla(var(--accent-h, 205), 40%, 10%, 0.75));
}

/* ---------- hero band (article) ----------
   The article header is the SAME wide dark hero band as the hub/section index
   pages (.post-hero-band, above): breadcrumb + pill + title + standfirst +
   byline flush to the far-left on the ambient accent glow. There is NO full-bleed
   cover image — the lead image renders in-column as the article's opening figure
   — so the breadcrumb/title chrome reads IDENTICALLY across index and article
   pages. The <main> carries `.story-arc`; cancel its top padding + rounding so the
   band's own 8rem top (which clears the fixed glass header) is the only top
   spacing, exactly like the index. `.story-arc` adds a -48px overlap margin to
   tuck each arc under the previous section's rounded bottom; the article header
   is the FIRST section (nothing above but the fixed nav), so cancel it too —
   otherwise the breadcrumb rides 48px higher than the index's (which is a plain
   .hub, no overlap margin). Also neutralise the .story-arc.theme-dark SURFACE
   (layout.css: a diagonal --_accent-glow gradient + a top hairline) so the header
   backdrop is IDENTICAL to the index .hub (which is not a story-arc): the shared
   ambient glow must come ONLY from .post::before, exactly like .hub::before —
   not from an extra story-arc gradient the index never gets. */
.post.story-arc {
    margin-top: 0; padding-top: 0; border-radius: 0;
    background: var(--color-bg);
    background-image: none;
    border-top: none;
}
/* article title wraps a touch narrower than the full band for a comfortable
   line length, still left-aligned (mirrors the hub hero). */
.post .post-hero { max-width: 1000px; }

/* ---------- two-column reading layout (blog + knowledge) ----------
   ONE layout for both collections: a sticky, boxed contents rail pinned to the
   LEFT (flush to the container padding, lined up with the wide header's
   breadcrumb) and the readable reading column on the RIGHT. */
.post-layout {
    display: grid;
    /* The rail is FLUID, not a hard 300px: on a tablet-width two-column viewport
       (iPad portrait ~1024, iPad landscape ~1180) a fixed 300px rail ate a third of
       the row and squeezed the reading measure to ~600px, so the contents card read
       as the bigger of the two columns. It reaches its full 300px only from ~1250px
       up, where there is width to spare. */
    grid-template-columns: 300px minmax(0, 1fr);   /* fallback: no clamp() support */
    grid-template-columns: var(--post-toc-w, clamp(15rem, 24vw, var(--post-side-max))) minmax(0, 1fr);
    gap: clamp(2.5rem, 5vw, 6rem);
    /* NB: no `align-items: start` — the aside cell must STRETCH to the row height
       (the tall prose column) so the sticky ToC inside it has room to travel the
       whole article. A short (content-height) cell would strand the ToC near the
       top. */
}
/* reading column capped to a comfortable measure, left-aligned within the right
   grid cell (just past the ToC + gap). On wide desktop it becomes a light card
   flanked by the two sticky sidebars — see the 3-column block below. */
.post-main { min-width: 0; max-width: var(--post-measure); margin-inline: 0; }
/* Zero the last block's trailing margin so the reading column's content ends
   EXACTLY at the grid-row bottom — that's where the sticky ToC / rail cards dock,
   so at the end of the article all three columns line up on the same bottom edge
   (the light chapter's own padding-bottom still supplies the gap to the outro). */
.post-main > :last-child { margin-bottom: 0; }

.post-aside { position: relative; min-width: 0; }
/* the sticky wrapper only positions; the card itself owns the height cap + scroll */
.post-aside__inner { position: sticky; top: 6.5rem; }

/* ---------- sticky right rail (author + start-your-own CTA) ----------
   On WIDE screens the layout gains a THIRD column that fills the empty gutter to
   the right of the reading measure with a sticky author credit + CTA. The reading
   column stays pinned to --post-measure (so the reading experience is unchanged);
   only the previously-empty gutter becomes the rail — no reflow of the prose. The
   rail is a visual enhancement: hidden until the reader scrolls (revealed by
   RAIL_REVEAL_JS), so it never competes with the hero, and hidden again once the
   outro repeats the same author + CTA. Below the breakpoint it's display:none and
   the grid falls back to the two-column (then single-column) layout. */
.post-rail { display: none; }
/* The whole 3-column arrangement hangs off `:has()`. Without it the `display:block`
   below would still fire while the grid template stayed 2-column, so the rail became
   a THIRD grid item that wrapped under the contents card — a stray author panel in
   the left rail. Older WebKit (Safari < 15.4, i.e. iPadOS 15.0–15.3) has no `:has()`,
   so gate the reveal on support: those browsers keep the plain two-column reading
   layout they already get below 1500px. */
@supports selector(:has(*)) {
@media (min-width: 1500px) {
    .post-rail { display: block; min-width: 0; }
    /* The TWO sidebars are ONE width. The contents card used to be a hard 300px
       while the author rail took whatever was left over (`1fr`), so between 1500
       and 1600px the rail rendered visibly narrower than the contents card (219px
       vs 300px at a 1512px laptop viewport) — two mismatched columns flanking the
       sheet. Both rails are `1fr` now, so they SPLIT the leftover space equally
       and are identical at every width. The reading column keeps its own
       `minmax(0, --post-measure)` track, so the prose measure is sized FIRST and
       is never squeezed to pay for the rails — the two rails meet in the middle
       instead (≈260px each at 1512px, ≈294px at 1600px and up). */
    .post-layout:has(.post-rail) {
        grid-template-columns:
            minmax(0, 1fr) minmax(0, var(--post-measure)) minmax(0, 1fr);
        column-gap: clamp(2.5rem, 3.4vw, 4rem);
    }
    /* Cap both cards at the SAME value, so the pair is identical by construction
       even where the tracks aren't (they peak at ~304px just past 1600px — where
       the container is capped but the gap is still growing — then settle to
       ~294px; the cap trims those few pixels off BOTH cards equally, and keeps
       them from ballooning if --post-container ever grows). Scoped to this block:
       the stacked layout's contents card is full-width. */
    .post-layout:has(.post-rail) .post-toc { max-width: var(--post-side-max); }
    /* Reading column becomes a light CARD — but ONLY here, where the two sticky
       sidebars flank it — so the article reads as a floating sheet between them.
       The chapter goes a touch grey so the white sheet (+ sidebars) actually reads
       as a card. Below this width there is no rail, so no sheet: plain prose. */
    .post-body-arc.theme-light:has(.post-rail) { background-color: #eceef2; }
    .post-layout:has(.post-rail) .post-main {
        background: var(--box-fill);
        box-shadow: var(--box-elev);
        border-radius: var(--radius-3xl);
        padding: var(--space-2xl);
    }
}
}   /* @supports selector(:has(*)) */
.post-rail__inner {
    position: sticky; top: 6.5rem;
    /* same cap as the contents card (see --post-side-max), and hug the container's
       RIGHT edge so the rail mirrors the contents card's flush-left alignment if
       the cap ever bites before the track does */
    max-width: var(--post-side-max);
    margin-inline-start: auto;
    opacity: 0; transform: translateY(16px);
    transition: opacity 0.55s ease, transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
    will-change: opacity, transform;
    pointer-events: none;
}
.post-rail.is-visible .post-rail__inner { opacity: 1; transform: none; pointer-events: auto; }
@media (prefers-reduced-motion: reduce) {
    .post-rail__inner { transition: opacity 0.25s linear; transform: none; }
    .post-rail:not(.is-visible) .post-rail__inner { transform: none; }
}
.post-rail__card {
    display: flex; flex-direction: column;
    /* flat surface — no radial tint at the top (matches the at-a-glance / key-takeaways cards) */
    background: var(--box-fill);
    box-shadow: var(--box-elev);
    border-radius: var(--radius-3xl);
    padding: var(--space-lg);
}
.post-rail__author {
    display: flex; align-items: center; gap: var(--space-sm);
    text-decoration: none; min-width: 0;
}
.post-rail__avatar {
    flex: 0 0 auto; width: 48px; height: 48px; border-radius: 50%;
    object-fit: cover; box-shadow: 0 0 0 2px hsla(var(--accent-h, 205), 60%, 60%, 0.35);
}
.post-rail__author-text { display: flex; flex-direction: column; min-width: 0; }
.post-rail__eyebrow {
    font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase;
    font-weight: 700; color: var(--color-text-muted);
}
.post-rail__name {
    color: var(--color-text); font-weight: 700; font-size: var(--text-base); line-height: 1.25;
}
.post-rail__author:hover .post-rail__name { color: var(--post-accent); }
.post-rail__role { color: var(--post-accent); font-size: var(--text-sm); font-weight: 600; }
.post-rail__divider {
    height: 1px; margin: var(--space-lg) 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.14), transparent);
}
.post-rail__cta-title {
    margin: 0 0 var(--space-xs); color: var(--color-text);
    font-size: var(--text-xl); font-weight: 800; line-height: 1.15;
}
.post-rail__cta-lead {
    margin: 0 0 var(--space-md); color: var(--color-text-secondary);
    font-size: var(--text-sm); line-height: 1.5;
}
.post-rail__btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
    width: 100%;
}
.post-rail__btn-arrow { transition: transform var(--transition-base); }
.post-rail__btn:hover .post-rail__btn-arrow { transform: translateX(3px); }

/* ---------- table of contents ----------
   A boxed card (reusing the same --box-fill / --box-elev surface as the other
   overview blocks — at-a-glance, key takeaways) that lives in the sticky left
   rail on desktop and stacks above the prose on mobile. The "ON THIS PAGE" label
   is pinned; only the list scrolls, so a long contents list stays compact. */
.post-toc {
    margin: 0;
    display: flex;
    flex-direction: column;
    /* The card is a COMPACT nav rail, never a full-height slab. Two caps, whichever
       is smaller:
       (a) the viewport under the sticky offset — in `dvh` so iOS Safari's dynamic
           toolbars are accounted for (`100vh` there is the *toolbars-hidden* height,
           so on an iPad the card overflowed the visible area); the `vh` line above
           is the fallback for Safari < 15.4.
       (b) a fixed 30rem — a long list (17 entries ≈ 940px) used to grow the card to
           the full screen height, dwarfing both the reading column and the author
           rail on a tablet-height viewport. Past this it scrolls inside instead,
           which is what the pinned label + edge fades + scroll-spy exist for. */
    max-height: 30rem;                                                  /* no min() */
    max-height: min(calc(100vh - 6.5rem - var(--space-lg)), 30rem);     /* no dvh */
    max-height: min(calc(100dvh - 6.5rem - var(--space-lg)), 30rem);
    /* no LEFT padding: the active pill sits flush to the card's left edge; the
       label + entry text are re-inset by --toc-inset so they still line up. The
       RIGHT padding is small so the scrollbar rides close to the card edge (a tidy
       narrow gutter) rather than floating a full --space-lg in from it. */
    --toc-inset: var(--space-lg);
    padding: var(--space-md) var(--space-sm) var(--space-md) 0;
    background: var(--box-fill);
    box-shadow: var(--box-elev);
    border-radius: var(--radius-3xl);
    overflow: hidden;   /* clip the list's fade mask to the rounded corners */
}
.post-toc__label { display: block; flex-shrink: 0; padding-left: var(--toc-inset); font-size: var(--text-xs); letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; color: var(--color-text-muted); margin-bottom: var(--space-sm); }
/* the scrolling region: soft fade top + bottom, and a subtle, inset scrollbar
   (thin, low-contrast, padded off the text — never flush to the card edge). */
.post-toc__list {
    list-style: none; margin: 0; display: grid;
    overflow-y: auto;
    /* a flick inside the contents list must not chain into the page scroll (it
       hijacked the article scroll on touch once the list started scrolling) */
    overscroll-behavior: contain;
    min-height: 0;
    padding-right: var(--space-sm);
    --toc-fade: 1.15rem;
    scrollbar-width: thin;
    scrollbar-color: var(--color-border-light) transparent;
}
.post-toc__list::-webkit-scrollbar { width: 5px; }
.post-toc__list::-webkit-scrollbar-track { background: transparent; margin: var(--toc-fade) 0; }
.post-toc__list::-webkit-scrollbar-thumb { background: var(--color-border-light); border-radius: var(--radius-full); }
.post-toc__list::-webkit-scrollbar-thumb:hover { background: var(--post-accent); }
/* Soft edge fade — applied ONLY when there is actually more list to scroll in
   that direction (classes toggled by the ToC script), so a short list that fits
   without scrolling is never faded: top edge fades when scrolled down, bottom
   edge when there's more below, both in the middle. */
.post-toc__list.is-fade-top.is-fade-bottom {
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 var(--toc-fade), #000 calc(100% - var(--toc-fade)), transparent 100%);
            mask-image: linear-gradient(180deg, transparent 0, #000 var(--toc-fade), #000 calc(100% - var(--toc-fade)), transparent 100%);
}
.post-toc__list.is-fade-top:not(.is-fade-bottom) {
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 var(--toc-fade));
            mask-image: linear-gradient(180deg, transparent 0, #000 var(--toc-fade));
}
.post-toc__list.is-fade-bottom:not(.is-fade-top) {
    -webkit-mask-image: linear-gradient(0deg, transparent 0, #000 var(--toc-fade));
            mask-image: linear-gradient(0deg, transparent 0, #000 var(--toc-fade));
}
/* thin hairline between entries — inset to the text column (--toc-inset) so it
   clears the active pill that sits in the left margin, never touching it. */
.post-toc__list li { position: relative; }
.post-toc__list li + li::after {
    content: ""; position: absolute; top: 0; left: var(--toc-inset); right: 0;
    height: 1px; background: var(--color-border);
}
.post-toc__list a {
    position: relative;
    color: var(--color-text-secondary); text-decoration: none;
    font-size: var(--text-sm); line-height: 1.4;
    display: block;
    padding: var(--space-sm) 0 var(--space-sm) var(--toc-inset);   /* text lines up with the label */
    transition: color var(--transition-fast);
}
.post-toc__list a:hover { color: var(--post-accent); }
/* scroll-spy: the current section gets accent text + a thicker rounded accent
   PILL flush to the card's left edge — mirrors the nav dropdown current-page
   indicator (header-mobile.css). */
.post-toc__list a.is-active { color: var(--post-accent); font-weight: 600; }
.post-toc__list a.is-active::before {
    content: ""; position: absolute; left: 0; top: var(--space-sm); bottom: var(--space-sm);
    width: 4px; border-radius: var(--radius-full);
    background: var(--post-accent);
}

/* ---------- article body prose ---------- */
.post-body { font-size: 1.18rem; line-height: 1.75; color: var(--color-text-secondary); }
.post-body > h2 {
    font-size: clamp(1.7rem, 3.2vw, 2.15rem);
    line-height: 1.2;
    font-weight: 800;
    color: var(--color-text);
    margin: var(--space-3xl) 0 var(--space-md);
    scroll-margin-top: 6rem;
    text-wrap: balance;
}
.post-body > h3 { font-size: clamp(1.3rem, 2.4vw, 1.55rem); font-weight: 700; color: var(--color-text); margin: var(--space-2xl) 0 var(--space-sm); scroll-margin-top: 6rem; }
.post-body > h4 { font-size: var(--text-xl); font-weight: 700; color: var(--color-text); margin: var(--space-xl) 0 var(--space-sm); }
.post-body p { margin: 0 0 var(--space-lg); }
.post-body a {
    color: var(--color-primary-light);
    text-decoration: underline;
    text-underline-offset: 2px;
    text-decoration-color: color-mix(in srgb, var(--color-primary-light) 40%, transparent);
}
.post-body a:hover { color: var(--color-primary); text-decoration-color: currentColor; }
.post-body strong { color: var(--color-text); font-weight: 700; }
.post-body ul.post-list,
.post-body ol.post-list { margin: 0 0 var(--space-lg); padding-left: 1.3em; }
.post-body ul.post-list li,
.post-body ol.post-list li { margin: var(--space-sm) 0; padding-left: 0.3em; }
.post-body ul.post-list li::marker { color: var(--post-accent); }
.post-body ol.post-list li::marker { color: var(--post-accent); font-weight: 700; }
.post-body ul.post-list ul.post-list { margin: var(--space-sm) 0; }
.post-figure { margin: var(--space-2xl) 0; }
.post-figure img { width: 100%; height: auto; border-radius: var(--radius-3xl); display: block; }
.post-body code { font-family: var(--font-mono); font-size: 0.88em; background: var(--color-surface); border-radius: var(--radius-md); padding: 0.1em 0.4em; }
.post-code { background: var(--box-fill); border: var(--panel-border); border-radius: var(--radius-2xl); padding: var(--space-lg); overflow-x: auto; margin: var(--space-xl) 0; font-size: var(--text-sm); }
.post-code code { background: none; padding: 0; }

/* pull quote: an editorial statement, no left bar */
.post-quote {
    position: relative;
    margin: var(--space-2xl) 0;
    padding: var(--space-xs) 0 var(--space-xs) 3.2rem;
    color: var(--color-text);
    font-size: 1.5rem;
    line-height: 1.4;
    font-weight: 500;
}
.post-quote::before {
    content: "\201C";
    position: absolute;
    left: 0; top: -0.15em;
    font-size: 3.4rem;
    line-height: 1;
    color: var(--post-accent);
    opacity: 0.6;
}
.post-quote p:last-child { margin-bottom: 0; }

/* callouts: a filled panel with a coloured dot, no bar */
.post-callout {
    display: grid;
    gap: var(--space-xs);
    border-radius: var(--radius-2xl);
    padding: var(--space-lg) var(--space-xl);
    margin: var(--space-xl) 0;
    background: var(--box-fill);
    border: var(--panel-border);
    --callout-dot: var(--post-accent);
}
.post-callout--tip { --callout-dot: var(--color-success); }
.post-callout--warning { --callout-dot: var(--color-primary); }
.post-callout__label { display: inline-flex; align-items: center; gap: var(--space-xs); font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; font-weight: 700; color: var(--color-text-muted); }
.post-callout__label::before { content: ""; width: 0.6em; height: 0.6em; border-radius: 50%; background: var(--callout-dot); }
.post-callout__body { font-size: var(--text-base); }
.post-callout__body p:last-child { margin-bottom: 0; }

/* tables */
.data-table-wrap { overflow-x: auto; margin: var(--space-xl) 0; border-radius: var(--radius-2xl); background: var(--box-fill); border: var(--panel-border); }
table.data-table { width: 100%; border-collapse: collapse; font-size: var(--text-base); font-variant-numeric: tabular-nums; }
table.data-table th,
table.data-table td { padding: var(--space-sm) var(--space-md); text-align: left; border-bottom: 1px solid rgba(255, 255, 255, 0.06); }
table.data-table thead th { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); background: rgba(255, 255, 255, 0.03); white-space: nowrap; }
table.data-table tbody tr:last-child td { border-bottom: none; }
table.data-table tbody tr:nth-child(even) { background: hsla(var(--accent-h, 205), 30%, 50%, 0.04); }
table.data-table tbody td { color: var(--color-text-secondary); }

/* ---------- at a glance ---------- */
.at-a-glance {
    background: linear-gradient(180deg, var(--post-accent-soft), transparent), var(--box-fill);
    border-radius: var(--radius-3xl);
    padding: var(--space-xl) var(--space-2xl);
    margin-bottom: var(--space-2xl);
    border: var(--panel-border);
}
.at-a-glance__label { display: inline-flex; align-items: center; gap: var(--space-xs); font-size: var(--text-xs); letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; color: var(--post-accent); margin-bottom: var(--space-sm); }
.at-a-glance__label::before { content: ""; width: 0.7em; height: 0.7em; border-radius: 50%; background: var(--post-accent); box-shadow: 0 0 0 4px var(--post-accent-soft); }
.at-a-glance__body p { margin: 0 0 var(--space-sm); color: var(--color-text); font-size: 1.18rem; line-height: 1.6; }
.at-a-glance__body p:last-child { margin-bottom: 0; }

/* ---------- key takeaways ---------- */
.key-takeaways { margin: var(--space-3xl) 0 var(--space-xl); background: var(--box-fill); border: var(--panel-border); border-radius: var(--radius-3xl); padding: var(--space-2xl); }
.key-takeaways__title { font-size: var(--text-xl); font-weight: 800; color: var(--color-text); margin: 0 0 var(--space-md); }
.key-takeaways__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-md); }
.key-takeaways__list li { position: relative; padding-left: 2em; color: var(--color-text-secondary); font-size: var(--text-lg); }
.key-takeaways__list li::before { content: ""; position: absolute; left: 0; top: 0.2em; width: 1.3em; height: 1.3em; border-radius: var(--radius-full); background: var(--post-accent-soft); }
.key-takeaways__list li::after { content: ""; position: absolute; left: 0.42em; top: 0.42em; width: 0.34em; height: 0.62em; border-right: 2px solid var(--post-accent); border-bottom: 2px solid var(--post-accent); transform: rotate(40deg); }

/* ---------- sources ---------- */
/* bottom margin halved: it stacks with .post-outro's own top padding right
   after it, and together they left too much air before the author panel. */
.post-sources { margin: var(--space-2xl) 0 calc(var(--space-2xl) / 2); }
.post-sources h2 { font-size: var(--text-lg); color: var(--color-text); margin: 0 0 var(--space-sm); }
.post-sources ul { margin: 0; padding-left: 1.2em; }
.post-sources li { margin: var(--space-xs) 0; font-size: var(--text-sm); }
.post-sources a { color: var(--color-primary-light); }

/* ---------- video embed ---------- */
.post-video { margin: var(--space-2xl) 0; }
.post-video .post-section__head { margin-bottom: var(--space-lg); }
.post-video__figure { margin: 0; }
/* the source clip is a vertical Short, so the frame keeps a 9:16 portrait
   ratio and stays capped to a phone-sized column instead of stretching full
   width like a 16:9 embed would. */
.post-video__frame {
    position: relative;
    width: 100%;
    max-width: 320px;
    aspect-ratio: 9 / 16;
    margin: 0 auto;
    border-radius: var(--radius-3xl);
    overflow: hidden;
    background: var(--color-surface);
    box-shadow: var(--shadow-xl);
}
.post-video__frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* ---------- outro: two story arcs ----------
   Arc 1 (author + FAQ) is one luminous elevated panel — the guide, then their
   answers. Arc 2 (keep reading + prev/next) is the open "where next" movement.
   The two read as distinct chapters that flow into the orange CTA, not a stack
   of boxes floating on black. */
/* halved to match the .post-sources cut above — same "closer to what's above
   it" fix, the other half of the gap. */
.post-outro { padding: calc(var(--space-2xl) / 2) 0 0; }
.post-arc { padding-block: var(--space-2xl); }
.post-section__head { margin-bottom: var(--space-xl); }
.post-section__head h2 { font-size: clamp(1.7rem, 3.4vw, 2.4rem); font-weight: 800; color: var(--color-text); margin: 0; }
.post-section__head .post-eyebrow { margin-bottom: var(--space-sm); }

/* ---------- Arc 1: the guide, then their answers — two distinct panels ---------- */
.arc-panel-stack { display: flex; flex-direction: column; gap: var(--space-xl); }
/* the FAQ card's own top padding, halved: "Frequently asked questions" was
   sitting too far from the card's top edge. */
.arc-panel--faq { padding-top: clamp(0.875rem, 1.5vw, calc(var(--space-3xl) / 2)); }
.arc-panel {
    position: relative;
    border-radius: var(--radius-3xl);
    padding: clamp(1.75rem, 3vw, var(--space-3xl));
    /* accent light pooled in the top-left, on an elevated surface with a soft
       top-edge highlight + drop shadow (no outline hairline — depth comes from
       elevation, not borders), so the panel can't be defeated by
       `.story-arc section { background:none }`. */
    background:
        radial-gradient(135% 78% at 12% 0%, hsla(var(--accent-h, 205), 42%, 18%, 0.38) 0%, transparent 56%),
        var(--box-fill);
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.06),
        var(--box-elev);
}

/* author masthead (heads the panel) */
.arc-author { display: flex; gap: var(--space-lg); align-items: flex-start; }
.arc-author__avatar {
    width: 84px; height: 84px; border-radius: var(--radius-full); object-fit: cover; flex-shrink: 0;
    /* accent ring floated off the surface with a bg-coloured gap */
    box-shadow: 0 0 0 2px var(--box-fill), 0 0 0 4px hsla(var(--accent-h, 205), 82%, 62%, 0.55);
}
.arc-author__eyebrow { display: block; font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-text-muted); font-weight: 700; }
.arc-author__name { margin: var(--space-xs) 0 0; font-size: var(--text-xl); }
.arc-author__name a { color: var(--color-text); text-decoration: none; }
.arc-author__name a:hover { color: var(--post-accent); }
.arc-author__role { color: var(--post-accent); font-size: var(--text-sm); margin: var(--space-xs) 0 var(--space-sm); font-weight: 600; }
.arc-author__bio { color: var(--color-text-secondary); font-size: var(--text-base); line-height: 1.6; margin: 0 0 var(--space-sm); max-width: 62ch; }
.arc-author__social { display: flex; flex-wrap: wrap; gap: var(--space-sm); margin-top: var(--space-xs); }
.arc-author__social .social-link { font-size: var(--text-sm); }

/* Author social links (shared: arc byline + author hero): a filled,
   brand-coloured pill button per platform (icon + label), same shape as the
   site's other CTA buttons — not a bare text link. Colour is the real brand
   colour for that platform (not the collection accent), so LinkedIn/X read
   the same regardless of which article's accent hue they sit on. */
.social-link {
    display: inline-flex; align-items: center; gap: 0.5em;
    padding: 0.55em 1.1em; border-radius: var(--radius-full);
    color: #fff; text-decoration: none; font-weight: 700; font-size: var(--text-sm); line-height: 1;
    transition: opacity var(--transition-base), transform var(--transition-base);
}
/* explicit colour on :hover, not just the base rule: the global `a:hover`
   (base.css, brand orange) has higher specificity than a bare .social-link
   and was winning on hover, so the pill's text flashed orange instead of
   staying white. */
.social-link:hover { color: #fff; opacity: 0.88; transform: translateY(-1px); }
.social-link--linkedin { background: #0A66C2; }
.social-link--x, .social-link--twitter { background: #000; }
.social-link__icon { width: 1.1em; height: 1.1em; flex: none; }

/* faint rule between the author and the FAQ, inside the panel */
.arc-panel__rule {
    height: 1px; margin: clamp(1.5rem, 3vw, var(--space-2xl)) 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.10) 10%, rgba(255, 255, 255, 0.10) 90%, transparent);
}

/* FAQ lives on the panel surface — flush, no card of its own */
.post-faq { margin: var(--space-3xl) 0 var(--space-2xl); }
.post-faq .post-section__head { margin-bottom: 0; }
.arc-panel .post-faq { margin: 0; }

/* plain question/answer list — every Q and A on screen at once, no toggle.
   Separation comes from whitespace only (no divider hairlines). */
/* every Q&A stays on screen (no toggle). Each item is a scannable ROW: the
   question in an aligned LEFT column (so the eye scans straight down the
   questions) + the answer in a readable RIGHT column, a hairline between rows.
   Fills the full panel width, and no ragged grid gaps (rows flow independently). */
.faq-list { display: flex; flex-direction: column; margin-top: var(--space-lg); }
/* every Q&A STACKS: the question, then its answer beneath it — one readable
   column, no side-by-side Q/A split. A full-width hairline separates each pair;
   the text itself caps at a comfortable reading measure. */
.faq-item { padding: var(--space-lg) 0; }
.faq-item + .faq-item { border-top: 1px solid rgba(255, 255, 255, 0.09); }
.faq-item__q { font-size: var(--text-lg); font-weight: 700; color: var(--color-text); margin: 0 0 var(--space-sm); line-height: 1.4; max-width: 74ch; }
.faq-item__a { color: var(--color-text-secondary); font-size: var(--text-base); line-height: 1.7; margin: 0; max-width: 74ch; }
/* Q:/A: accent decorators label each part */
.faq-item__q::before,
.faq-item__a::before { color: var(--post-accent); font-weight: 800; margin-right: 0.45em; }
.faq-item__q::before { content: "Q:"; }
.faq-item__a::before { content: "A:"; }
/* On desktop, indent the Q/A block so it lines up with the author's name/bio
   column in the masthead above (past the 84px avatar + its --space-lg gap). The
   FAQ heading stays flush-left. On mobile the author card stacks (avatar on top),
   so no indent. */
@media (min-width: 901px) {
    .arc-panel--faq .faq-list { padding-left: calc(84px + var(--space-lg)); }
}

/* ---------- Arc 2: keep reading + prev/next — its own full-bleed band ----------
   Arc 1 is an intimate contained panel; Arc 2 is an expansive band that spans
   edge-to-edge with a defining top hairline and a soft accent glow, so "where
   next" reads as its own chapter (not loose cards floating on black) and fades
   down into the orange CTA. Content still centres in .post-container. The
   compound selector beats `.story-arc section { background:none }`. */
.post-outro .post-arc--more {
    position: relative;
    margin-top: var(--space-xl);
    padding-block: clamp(3rem, 5vw, 6rem);
    /* a raised surface that keeps a baseline tint the whole way down (so the
       cards AND the prev/next both sit on it — nothing strands in a de-tinted
       zone) and only fades out in the last sliver as it meets the orange CTA. */
    background:
        radial-gradient(1300px 460px at 50% 0%, hsla(var(--accent-h, 205), 44%, 24%, 0.28) 0%, transparent 70%),
        linear-gradient(180deg, rgba(255, 255, 255, 0.055) 0%, rgba(255, 255, 255, 0.028) 45%, rgba(255, 255, 255, 0.022) 86%, transparent 100%);
    box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.08);
}
.post-related { margin-bottom: var(--space-2xl); }
/* Keep-reading cards fill the row EDGE-TO-EDGE so they line up with the prev/next
   nav below (which spans the full container). `grid-auto-flow:column` +
   `grid-auto-columns:1fr` lays every card out as an equal 1fr track on one row, so
   whatever number are visible always span the whole width evenly — no capped tiles
   stranded on the left, and no auto-fit math to keep in sync. As the viewport
   narrows we HIDE trailing cards (display:none drops them from the grid, so the
   remaining tracks re-fill the row) — the count steps DOWN 5 → 4 → 3 → 2 and the
   row stays a single tidy strip, before the tiles stack on phones. */
.post-cards { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--space-lg); }
@media (max-width: 1200px) { .post-cards > .post-card:nth-child(n + 5) { display: none; } }  /* 5 → 4 across */
@media (max-width: 980px)  { .post-cards > .post-card:nth-child(n + 4) { display: none; } }  /* 4 → 3 across */
@media (max-width: 700px)  { .post-cards > .post-card:nth-child(n + 3) { display: none; } }  /* 3 → 2 across */
@media (max-width: 560px) {
    .post-cards { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: 1fr; }  /* stacked */
}
/* Sparse hubs (1–2 related) keep the modest capped tile, LEFT-aligned, so a lone
   card doesn't billboard across the whole band. Placed AFTER the rules above so it
   wins for a `--few` element at every width. */
.post-cards--few {
    grid-auto-flow: row; grid-auto-columns: auto;
    grid-template-columns: repeat(auto-fill, minmax(220px, 264px));
    justify-content: start;
}
a.post-card {
    text-decoration: none;
    display: flex; flex-direction: column;
    background:
        radial-gradient(120% 90% at 50% 0%, hsla(var(--accent-h, 205), 34%, 16%, 0.32) 0%, transparent 58%),
        var(--box-fill);
    box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.06), var(--box-elev);
    border-radius: var(--radius-3xl);
    overflow: hidden;
    transition: box-shadow var(--transition-base), transform var(--transition-base);
}
a.post-card:hover {
    box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.1), var(--box-elev-hover);
    transform: translateY(-4px);
}
.post-card .static-card__media { aspect-ratio: 16 / 9; overflow: hidden; background: linear-gradient(135deg, hsla(var(--accent-h,205),40%,20%,0.5), hsla(var(--accent-h,205),40%,8%,0.5)); }
/* Pin media to its 16:9 box. layout.css gives `.img-top` media `flex:1 1 0%`, which
   stretches the image to absorb leftover card height — so short-text cards end up with a
   taller image than text-heavy ones. flex:0 0 auto keeps every card's image identical. */
.post-card.img-top > .static-card__media { flex: 0 0 auto; }
.post-card .static-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--transition-slow); }
.post-card:hover .static-card__media img { transform: scale(1.04); }
.post-card .static-card__content { padding: var(--space-lg) var(--space-xl) var(--space-xl); display: flex; flex-direction: column; gap: var(--space-sm); }
.post-card .card__label { color: var(--post-accent); font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; font-weight: 700; }
.post-card .card__title { color: var(--color-text); font-size: var(--text-lg); font-weight: 700; line-height: 1.25; }
.post-card .card__description { color: var(--color-text-muted); font-size: var(--text-sm); line-height: 1.55; }
.post-card:hover .card__title { color: var(--post-accent); }

.post-pagenav { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-lg); }
/* Explicit column placement (not DOM/auto-placement order): prev is ALWAYS the
   left column, next ALWAYS the right column. So when only one exists, it stays
   on its own side and the other column is simply empty, instead of the lone
   card stretching to span both. */
.post-pagenav__prev { grid-column: 1; }
.post-pagenav__next { grid-column: 2; }
/* Compact HORIZONTAL card: a small square thumbnail beside the direction + title,
   so prev/next reads as a slim nav strip, not a pair of huge stacked cards. The
   "next" card mirrors (thumbnail on the right) so it points forward. */
.post-pagenav__link { display: flex; flex-direction: row; align-items: stretch; text-decoration: none; border-radius: var(--radius-2xl); overflow: hidden; background: var(--box-fill); box-shadow: var(--box-elev); transition: box-shadow var(--transition-base), transform var(--transition-base); }
.post-pagenav__next .post-pagenav__link,
.post-pagenav__link.post-pagenav__next { flex-direction: row-reverse; }
.post-pagenav__link:hover { box-shadow: var(--box-elev-hover); transform: translateY(-2px); }
.post-pagenav__media { flex: 0 0 clamp(84px, 10vw, 116px); aspect-ratio: 1 / 1; overflow: hidden; background: linear-gradient(135deg, hsla(var(--accent-h, 205), 40%, 20%, 0.5), hsla(var(--accent-h, 205), 40%, 8%, 0.5)); }
.post-pagenav__media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform var(--transition-slow); }
.post-pagenav__link:hover .post-pagenav__media img { transform: scale(1.04); }
.post-pagenav__body { flex: 1 1 auto; min-width: 0; padding: var(--space-md) var(--space-lg); display: flex; flex-direction: column; justify-content: center; gap: 0.15rem; }
.post-pagenav__next .post-pagenav__body { text-align: right; }
.post-pagenav__dir { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--post-accent); font-weight: 700; }
.post-pagenav__title { color: var(--color-text); font-weight: 700; font-size: var(--text-base); line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- dark outro chapter (author / FAQ / keep-reading) ----------
   The light reading body closes as a rounded card and the outro opens as its OWN
   full-width DARK chapter on the page bg: author masthead + FAQ (Arc 1), then
   "Keep reading" + prev/next (Arc 2), before the orange CTA. `theme-dark` keeps
   every arc component on the dark recipe they were originally tuned for (elevated
   panels, the Arc-2 band) — nothing to re-skin — so this just sets the chapter's
   rhythm + a soft top-pooled accent glow so it reads as a distinct movement, not
   "more dark page". */
.post-outro.post-outro--dark {
    position: relative;
    margin-top: var(--space-2xl);
    padding: var(--space-3xl) 0 0;
    background: radial-gradient(1500px 560px at 50% 0%,
        hsla(var(--accent-h, 205), 42%, 20%, 0.30) 0%, transparent 72%);
}
/* Arc 1: the author masthead and the FAQ are STACKED, each a full-width panel
   (the stack is already a flex column — nothing to override). The FAQ uses its
   width via the per-item question-left / answer-right row grid above, not a
   two-column split of whole items. */

/* The global mobile rule `@media(max-width:768px){section{padding:0}}` strips the
   closing CTA's vertical padding, so on phones the "Ready to own the house?" heading
   jams against — and overlaps — the light outro above it. Restore breathing room.
   This sheet only loads on content-engine pages, so it can't touch the marketing CTAs. */
@media (max-width: 768px) {
    .story-arc + .cta.accent-background,
    .hub + .cta.accent-background,
    .author-page + .cta.accent-background {
        padding: clamp(2.25rem, 8vw, 3.5rem) 0;
    }
}

/* ============ light story arc — article body + hub listing ============
   The dark hero (cover / hub band) closes into a rounded LIGHT chapter that
   lifts off the dark page, echoing the light outro. `theme-light` already
   flipped the colour tokens; here we (a) paint the light chapter surface, (b)
   re-declare the derived elevation/accent tokens for a white bg — custom
   properties resolve where they are DECLARED, so a nested light subtree needs
   its own copy — and (c) re-skin the few components hand-tuned for the dark
   article so they read on white. */
.post-body-arc.theme-light,
.hub-arc.theme-light {
    position: relative;
    /* flat light surface — no diagonal corner tint (the old 135deg gradient left a
       grey smudge in the top-left / bottom-right corners). */
    background-color: var(--color-bg);
    --post-accent: hsl(var(--accent-h, 205), 68%, 42%);
    --box-fill: var(--color-surface-elevated);
    --box-elev: 0 1px 2px rgba(3, 3, 6, 0.05), 0 16px 40px -24px rgba(3, 3, 6, 0.18);
    --box-elev-hover: 0 1px 2px rgba(3, 3, 6, 0.07), 0 26px 60px -28px rgba(3, 3, 6, 0.26);
    /* flat panels inside the reading body use a hairline border instead of a drop
       shadow (the stacked shadows read as noise, especially nested in the sheet) */
    --panel-border: 1px solid rgba(15, 18, 40, 0.09);
}
/* The hub listing arc flows into the orange CTA, so it rounds its TOP only. The
   article body arc is instead a self-contained light card floating between the
   dark header above and the dark outro below — so it rounds ALL corners.
   Symmetric top/bottom padding keeps the prose off the rounded edges. */
.hub-arc.theme-light { border-radius: var(--radius-6xl) var(--radius-6xl) 0 0; }
.post-body-arc.theme-light { border-radius: var(--radius-6xl); }
.post-body-arc { padding-bottom: var(--space-3xl); }
.post-body-arc > .post-container { padding-top: var(--space-3xl); }
.hub-arc { padding-bottom: var(--space-4xl); }
/* the listing needs a top gap inside the rounded arc; the first cluster's own
   top margin would otherwise double it. */
.hub-arc > .post-container { padding-top: var(--space-3xl); }
.hub-arc .hub-cluster:first-child { margin-top: 0; }

/* --- article body prose: dark-tuned bits → light --- */
/* body links were a light indigo (#818CF8) that fails contrast on white — use
   the light-tuned collection accent instead. */
.post-body-arc .post-body a,
.post-body-arc .post-sources a {
    color: var(--post-accent);
    text-decoration-color: color-mix(in srgb, var(--post-accent) 40%, transparent);
}
.post-body-arc .post-body a:hover { color: var(--color-primary); text-decoration-color: currentColor; }
/* table hairlines were white-alpha; give panels a light hairline + light shadow */
.post-body-arc table.data-table th,
.post-body-arc table.data-table td { border-bottom: 1px solid var(--color-border); }
.post-body-arc table.data-table thead th { background: var(--color-surface); }
.post-body-arc table.data-table tbody tr:nth-child(even) { background: hsla(var(--accent-h, 205), 30%, 50%, 0.05); }
/* The sticky sidebar cards (ToC, rail) keep their card elevation; the panels
   INSIDE the reading body do not (see --panel-border) — stacked drop shadows on
   the sheet read as noise. */
.post-body-arc .post-toc {
    box-shadow: var(--box-elev);
}
.post-body-arc .data-table-wrap,
.post-body-arc .post-code,
.post-body-arc .post-callout,
.post-body-arc .at-a-glance,
.post-body-arc .key-takeaways {
    box-shadow: none;
    border: var(--panel-border);
}
.post-body-arc .post-body code { background: var(--color-surface); }
/* the lead image + inline figures sit flat on the reading surface (no drop shadow) */
.post-body-arc .post-figure img,
.post-body-arc .post-hero__figure img { box-shadow: none; }

/* accent-gradient phrase (hub cluster titles, etc.): the dark recipe adds
   +40/+65% lightness onto a 6% accent, which washes out on white — retune to a
   darker, readable gradient for the light arc. */
.post-body-arc .text-accent-highlight,
.hub-arc .text-accent-highlight {
    background-image: linear-gradient(90deg,
        hsl(var(--accent-h, 205), 72%, 38%) 0%,
        hsl(calc(var(--accent-h, 205) + 26), 74%, 50%) 100%);
}

/* hub listing cards on the light arc — the light "keep reading" card recipe */
.hub-arc a.post-card {
    background: var(--color-surface-elevated);
    box-shadow: var(--box-elev);
}
.hub-arc a.post-card:hover {
    box-shadow: var(--box-elev-hover);
    transform: translateY(-4px);
}
.hub-arc .post-card .static-card__media { background: var(--color-surface); }
.hub-arc .post-card .card__description { color: var(--color-text-muted); }

/* ---------- hub / section pages ---------- */
.hub { padding-bottom: 0; }
.hub .post-hero-band { padding-bottom: var(--space-2xl); }

/* eyebrow pill (mirrors the marketplace .live-pill) */
.hub-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    padding: 0.4rem 0.9rem 0.4rem 0.75rem;
    border-radius: var(--radius-full);
    background: hsla(var(--accent-h, 205), 40%, 22%, 0.28);
    box-shadow: inset 0 0 0 1px hsla(var(--accent-h, 205), 70%, 60%, 0.22);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-text-secondary);
    margin-bottom: var(--space-md);
}
.hub-pill__dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--post-accent);
    box-shadow: 0 0 0 4px hsla(var(--accent-h, 205), 82%, 60%, 0.18);
}

.hub-hero { max-width: 940px; }
.hub-hero__title {
    font-size: clamp(2.4rem, 5.4vw, 4rem);
    line-height: 1.12;   /* room for descenders — background-clip:text on the
                            accent span clips the "g"/"y" tails at tighter values */
    font-weight: 800;
    letter-spacing: -0.025em;
    margin: 0 0 var(--space-md);
    text-wrap: balance;
}
.hub-hero__lead {
    font-size: clamp(1.15rem, 1.8vw, 1.4rem);
    line-height: 1.55;
    color: var(--color-text-secondary);
    max-width: 680px;
    margin: 0;
}

/* topic chips — quick jump index in the hero */
.hub-chips { display: flex; flex-wrap: wrap; gap: var(--space-sm); margin-top: var(--space-xl); }
.hub-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.5rem 1rem;
    border-radius: var(--radius-full);
    background: var(--box-fill);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07), var(--box-elev);
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
    font-weight: 600;
    text-decoration: none;
    transition: color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
}
.hub-chip:hover {
    color: var(--color-text);
    box-shadow: inset 0 0 0 1px hsla(var(--accent-h, 205), 75%, 62%, 0.5), var(--box-elev);
    transform: translateY(-1px);
}

/* clusters — a premium split section header + a bento grid */
.hub-grid { padding-top: 0; }
.hub-cluster { margin-top: var(--space-4xl); }
/* NB: don't set align-items here — .sc-section-header already aligns to flex-end
   on desktop, and its ≤900px media query resets to flex-start. Re-declaring it
   outside a query would win the cascade and right-shift the heading on mobile. */
.hub-cluster__head { margin-bottom: var(--space-2xl); }
.hub-cluster__title {
    font-size: clamp(1.9rem, 3.4vw, 2.8rem);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.02em;
    margin: 0;
}
.hub-cluster__title a { color: var(--color-text); text-decoration: none; }
.hub-cluster__title a:hover .text-accent-highlight { filter: brightness(1.12); }
/* fill the right column to the container's right edge (no max-width cap, which
   would left-align the text short of the edge and read as stray right padding). */
.hub-cluster__head .sc-lead { color: var(--color-text-secondary); line-height: 1.6; }
.hub-cluster__head .sc-link {
    display: inline-block;
    margin-top: var(--space-xs);
    color: var(--post-accent);
    text-decoration: none;
    font-weight: 600;
    white-space: nowrap;
}
.hub-cluster__head .sc-link:hover { filter: brightness(1.15); }

/* ---------- author page ---------- */
.author-page { padding-bottom: 0; }
.author-page .container,
.author-page .post-container { max-width: var(--post-container); }

/* breadcrumb + masthead share this column so both line up (breadcrumb stays
   left-aligned text, just within the same centred width as everything below). */
.author-hero-col { max-width: var(--post-measure); margin-inline: auto; }

/* hero masthead: portrait -> name -> role -> socials, centred, single column,
   on the ambient glow. (Was a two-column portrait+text grid; centred stacking
   is now the default at every width, not just mobile.) */
.author-hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
    gap: var(--space-md);
    max-width: 640px;
    margin-inline: auto;
}
.author-hero__portrait { position: relative; flex-shrink: 0; }
/* soft accent bloom pooled behind the portrait */
.author-hero__portrait::before {
    content: "";
    position: absolute; inset: -32%;
    border-radius: 50%;
    background: radial-gradient(circle at 50% 45%,
        hsla(var(--accent-h, 205), 72%, 44%, 0.42), transparent 68%);
    z-index: 0;
    pointer-events: none;
}
.author-hero__avatar {
    position: relative;
    z-index: 1;
    width: clamp(120px, 15vw, 176px);
    height: clamp(120px, 15vw, 176px);
    border-radius: var(--radius-full);
    object-fit: cover;
    display: block;
    box-shadow:
        0 0 0 3px var(--color-bg),
        0 0 0 5px hsla(var(--accent-h, 205), 82%, 62%, 0.55),
        0 26px 52px -18px rgba(0, 0, 0, 0.72);
}
.author-hero__name {
    font-size: clamp(2.1rem, 5vw, 3.4rem);
    line-height: 1.08;
    font-weight: 800;
    letter-spacing: -0.02em;
    margin: 0 0 var(--space-sm);
    text-wrap: balance;
}
.author-hero__role {
    color: var(--post-accent);
    font-weight: 600;
    font-size: clamp(1rem, 1.6vw, 1.2rem);
    margin: 0 0 var(--space-md);
}
.author-hero__social { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-sm) var(--space-lg); }

/* body: full bio + sticky expertise aside (mirrors .post-layout) */
.author-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: clamp(2.5rem, 4vw, 5rem);
    padding-top: var(--space-3xl);
    align-items: start;
}
.author-layout--solo { grid-template-columns: minmax(0, var(--post-measure)); }
/* no sidebar now (single-column page throughout) — centred directly, the
   same block-centring as .post-main on the article page, rather than relying
   on the (now unused) .author-layout grid + a solo variant. */
.author-main { min-width: 0; max-width: var(--post-measure); margin-inline: auto; }
.author-articles { max-width: var(--post-measure); margin-inline: auto; }
.author-bio {
    color: var(--color-text-secondary);
    font-size: var(--text-lg);
    line-height: 1.8;
    max-width: 68ch;
}
.author-bio > p { margin: 0 0 var(--space-lg); }
.author-bio > p:last-child { margin-bottom: 0; }
/* the opening paragraph reads as a lead — larger and in full-strength ink */
.author-bio > p:first-child {
    font-size: clamp(1.2rem, 1.9vw, 1.4rem);
    line-height: 1.6;
    color: var(--color-text);
}

.author-aside { position: relative; }
.author-aside__inner {
    position: sticky;
    top: 6.5rem;
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
}

/* expertise panel — luminous elevated surface, like .arc-panel / .at-a-glance */
.author-panel {
    position: relative;
    border-radius: var(--radius-3xl);
    padding: var(--space-xl) var(--space-2xl) var(--space-2xl);
    background:
        radial-gradient(135% 92% at 0% 0%, hsla(var(--accent-h, 205), 42%, 18%, 0.42) 0%, transparent 58%),
        var(--box-fill);
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.06),
        inset 0 0 0 1px rgba(255, 255, 255, 0.045),
        var(--box-elev);
}
.author-panel__eyebrow {
    display: inline-flex; align-items: center; gap: var(--space-sm);
    font-size: var(--text-xs); letter-spacing: 0.1em; text-transform: uppercase;
    font-weight: 700; color: var(--post-accent); margin-bottom: var(--space-md);
}
.author-panel__eyebrow::before {
    content: ""; width: 0.7em; height: 0.7em; border-radius: 50%;
    background: var(--post-accent); box-shadow: 0 0 0 4px var(--post-accent-soft);
}
.author-topics { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-sm); }
.author-topics li {
    display: inline-flex; align-items: center;
    padding: 0.5rem 0.95rem;
    border-radius: var(--radius-full);
    background: hsla(var(--accent-h, 205), 42%, 50%, 0.09);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
    color: var(--color-text-secondary);
    font-size: var(--text-sm); font-weight: 600; line-height: 1.2;
}

/* published-count stat card */
.author-stat {
    display: flex; align-items: baseline; gap: var(--space-md);
    padding: var(--space-lg) var(--space-2xl);
    border-radius: var(--radius-3xl);
    background: var(--box-fill);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.045), var(--box-elev);
}
.author-stat__num { font-size: clamp(2rem, 3vw, 2.6rem); font-weight: 800; color: var(--color-text); line-height: 1; }
/* secondary (not muted): muted 12px bold fails AA on this dark surface (3.4:1). */
.author-stat__label { font-size: var(--text-xs); color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; }

/* articles chapter: a single read-down list of rows, not a card grid. Reuses
   the dark Arc-2 band (.post-outro .post-arc--more) for the surface; give it
   a little air above it. */
.author-page .post-outro { margin-top: var(--space-3xl); padding-top: 0; }
.author-articles__heading { font-size: clamp(1.7rem, 3.4vw, 2.4rem); font-weight: 800; color: var(--color-text); margin: 0; }
.author-articles__rule {
    height: 1px; margin: var(--space-xl) 0 var(--space-2xl);
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.14), transparent 70%);
}
.author-article-list { display: flex; flex-direction: column; gap: var(--space-lg); }
a.author-article-row {
    display: flex;
    gap: var(--space-xl);
    align-items: stretch;
    text-decoration: none;
    padding: var(--space-md);
    border-radius: var(--radius-3xl);
    background: var(--box-fill);
    box-shadow: var(--box-elev);
    transition: box-shadow var(--transition-base), transform var(--transition-base);
}
a.author-article-row:hover { box-shadow: var(--box-elev-hover); transform: translateY(-2px); }
.author-article-row__media {
    flex: 0 0 clamp(140px, 22vw, 220px);
    aspect-ratio: 3 / 2;
    border-radius: var(--radius-2xl);
    overflow: hidden;
}
.author-article-row__media img,
.author-article-row__media .post-img-placeholder {
    width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; object-fit: cover; display: block;
}
.author-article-row__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: var(--space-xs); padding: var(--space-sm) var(--space-md) var(--space-sm) 0; }
.author-article-row__title { color: var(--color-text); font-size: var(--text-lg); font-weight: 700; line-height: 1.3; margin: 0; }
a.author-article-row:hover .author-article-row__title { color: var(--post-accent); }
.author-article-row__desc {
    color: var(--color-text-secondary); font-size: var(--text-sm); line-height: 1.55; margin: 0;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.author-article-row__date { color: var(--color-text-muted); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; margin-top: var(--space-xs); }
@media (max-width: 640px) {
    a.author-article-row { flex-direction: column; }
    .author-article-row__media { flex-basis: auto; aspect-ratio: 16 / 9; }
}

/* ---------- authors index ---------- */
.authors-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: var(--space-xl);
    padding-top: var(--space-2xl);
    padding-bottom: var(--space-4xl);
}
.author-card {
    display: flex; gap: var(--space-lg); align-items: flex-start;
    text-decoration: none;
    padding: var(--space-xl);
    border-radius: var(--radius-3xl);
    background:
        radial-gradient(120% 92% at 0% 0%, hsla(var(--accent-h, 205), 34%, 16%, 0.32) 0%, transparent 60%),
        var(--box-fill);
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.06),
        inset 0 0 0 1px rgba(255, 255, 255, 0.04),
        var(--box-elev);
    transition: box-shadow var(--transition-base), transform var(--transition-base);
}
.author-card:hover {
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.1),
        inset 0 0 0 1px hsla(var(--accent-h, 205), 70%, 60%, 0.35),
        var(--box-elev-hover);
    transform: translateY(-4px);
}
.author-card__avatar {
    width: 78px; height: 78px; border-radius: 50%; object-fit: cover; flex-shrink: 0;
    box-shadow: 0 0 0 2px var(--box-fill), 0 0 0 4px hsla(var(--accent-h, 205), 82%, 62%, 0.5);
}
.author-card__body { min-width: 0; }
.author-card__name { font-size: var(--text-xl); font-weight: 700; color: var(--color-text); margin: 0; transition: color var(--transition-base); }
.author-card:hover .author-card__name { color: var(--post-accent); }
.author-card__role { color: var(--post-accent); font-size: var(--text-sm); font-weight: 600; margin: 0.2rem 0 var(--space-sm); }
.author-card__bio { color: var(--color-text-muted); font-size: var(--text-sm); line-height: 1.55; margin: 0; }

/* ---------- keyboard focus ---------- */
/* The cards + editorial links have rich hover states but no focus affordance, so
   keyboard users fell back to the bare UA ring on dark. Mirror the hover with the
   accent outline pattern used elsewhere (engagement-tools.css / footer.css).
   --post-accent is in scope on every wrapper and adapts on the light outro too. */
.author-card:focus-visible,
a.post-card:focus-visible {
    outline: 2px solid var(--post-accent);
    outline-offset: 3px;
    border-radius: var(--radius-3xl);
}
.breadcrumbs a:focus-visible,
.social-link:focus-visible,
.hub-chip:focus-visible,
.post-toc__list a:focus-visible,
.post-pagenav__link:focus-visible {
    outline: 2px solid var(--post-accent);
    outline-offset: 2px;
}

/* ---------- responsive ---------- */
@media (max-width: 1000px) {
    /* single column: the contents card (emitted first) stacks ABOVE the prose,
       un-stuck; it keeps its pinned-label + scrolling-list treatment but caps at
       a compact height so a long list never dominates the screen. */
    .post-layout { grid-template-columns: 1fr; gap: var(--space-2xl); }
    .post-aside__inner { position: static; }
    /* 60vh was ~700px on a tablet in portrait — the contents list filled the whole
       first screen of the article. Cap it to a short block the reader scrolls past
       (or scrolls within), so the prose starts above the fold. */
    .post-toc { max-height: 22rem; }
    .post-toc { max-height: min(50vh, 22rem); }
    .post-toc { max-height: min(50dvh, 22rem); }
}
@media (max-width: 900px) {
    .post-hero-band { padding-top: 6rem; }
    /* Stack prev/next in ONE column. The explicit grid-column:1/2 on the links
       (which pins them to opposite sides on desktop) would otherwise force a 2nd
       implicit column here, so a single `1fr` template left them side-by-side and
       cramped — reset both to column 1 so they actually stack. */
    .post-pagenav { grid-template-columns: 1fr; }
    .post-pagenav__prev,
    .post-pagenav__next { grid-column: 1; }
    .arc-author { flex-direction: column; }
    .arc-author__avatar { width: 72px; height: 72px; }
    .post-body { font-size: 1.08rem; }
    .post-container { padding: 0 var(--space-lg); }
    .authors-grid { grid-template-columns: minmax(0, 1fr); }
}
