/* ─────────────────────────────────────────────────────────────
   inspiration.css - page-scoped styles for /inspiration/ surface
   Index (blog.php) + single (blog-post.php) + category (blog-category.php)
   + author (blog-author.php). Loaded inline by each template with
   filemtime() cache-bust. Tokens: design-tokens.css (Velvet Cinema).

   Block prefixes:
     .insp-hero  .insp-featured  .insp-filter  .insp-grid  .insp-card
     .insp-pagination  .insp-cta
     .cat-hero  .author-hero
     .post-hero  .post-body  .post-tags  .post-author-card
     .post-related  .post-prevnext
   ───────────────────────────────────────────────────────────── */

/* Shared helpers used inside this page-scope */
.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0;
}

/* ════════════════════════════════════════════════════════════
   1. INSPIRATION INDEX HERO  (blog.php)
   DOMINANT MOMENT: italic-accent "<em>Inspiration</em>" capped by
   a 3-tile floating meta band sitting on the cream gradient.
   ════════════════════════════════════════════════════════════ */
.insp-hero {
    position: relative;
    isolation: isolate;
    /* Tightened to leave room for the featured card in the initial
       viewport on standard 900-1000px desktops. */
    /* svh, not vw - the constraint is viewport HEIGHT (this hero ran 15px past
       the fold at 1280x720), so width-based padding charged a short laptop the
       same 112px as a tall monitor. Caps match the old maxima, so anything
       above ~1080px tall is unchanged. Same treatment as .chero, .team-hero
       and .reviews-hero. */
    padding-block: clamp(2rem, 5.5svh, 4.5rem) clamp(1.25rem, 3.5svh, 3rem);
    background:
        radial-gradient(ellipse at 15% 0%, rgba(212, 160, 160, 0.10) 0%, transparent 55%),
        radial-gradient(ellipse at 85% 30%, color-mix(in srgb, var(--color-accent-glow) 8%, transparent) 0%, transparent 60%),
        linear-gradient(to bottom, var(--color-bg-mid) 0%, var(--color-bg) 100%);
    overflow: hidden;
}
.insp-hero__grain {
    position: absolute; inset: 0;
    z-index: -1; pointer-events: none;
    opacity: 0.05;
    background-image: radial-gradient(circle at 1px 1px, var(--color-heading) 1px, transparent 0);
    background-size: 24px 24px;
}
.insp-hero__inner {
    position: relative;
    max-width: var(--container-wide);
    text-align: center;
}
.insp-hero__breadcrumbs {
    margin-bottom: var(--space-md);
    font-size: var(--text-xs);
}
.insp-hero__breadcrumbs ol {
    display: inline-flex; flex-wrap: wrap; justify-content: center;
    gap: 0.5rem; padding: 0; margin: 0; list-style: none;
    color: var(--color-muted);
}
/* Separator comes from the global `.breadcrumbs li + li::before` (style.css);
   a local ::after here rendered a second slash. */
.insp-hero__breadcrumbs a {
    color: var(--color-muted); text-decoration: none;
    transition: color var(--transition-fast);
}
.insp-hero__breadcrumbs a:hover { color: var(--color-accent); }

.insp-hero__eyebrow {
    display: inline-flex; align-items: center; gap: 0.5rem;
    margin-bottom: var(--space-md);
    color: var(--color-eyebrow);
}

.insp-hero__title {
    /* Velvet Cinema editorial serif hero (matches the pillar heroes:
       home .hero__heading, .svcs-hero__title). Fraunces, light weight,
       optical sizing, rose-deep serif-italic accent word. */
    font-family: var(--font-serif);
    font-optical-sizing: auto;
    font-size: clamp(2.4rem, 1.6rem + 4vw, 4rem);
    font-weight: 350;
    line-height: 1.02;
    letter-spacing: -0.015em;
    margin: 0 auto var(--space-md);
    max-width: 22ch;
    color: var(--color-heading);
    text-wrap: balance;
}
.insp-hero__title em {
    font-style: italic;
    font-weight: 480;
    color: var(--color-rose-deep);
}

.insp-hero__lead {
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.5;
    max-width: 56ch;
    margin: 0 auto var(--space-lg);
    color: var(--color-body);
    text-wrap: pretty;
}
.insp-hero__lead p:last-child { margin-bottom: 0; }

.insp-hero__meta {
    display: flex; align-items: center; justify-content: center;
    flex-wrap: wrap; gap: var(--space-md) var(--space-lg);
    margin-top: var(--space-md);
}
.insp-hero__meta-item {
    display: flex; flex-direction: column; align-items: center;
    min-width: 96px;
}
.insp-hero__meta-num {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 800;
    color: var(--color-heading);
    line-height: 1;
    letter-spacing: -0.02em;
}
.insp-hero__meta-label {
    margin-top: 0.25rem;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-muted);
}
.insp-hero__meta-divider {
    width: 1px; height: 36px;
    background: var(--color-border);
}

/* ════════════════════════════════════════════════════════════
   2. FEATURED POST  (blog.php, page 1 only)
   DOMINANT MOMENT: oversized magazine-style headline next to a
   3:4 hero portrait with a floating "Latest" badge.
   ════════════════════════════════════════════════════════════ */
.insp-featured {
    padding-block: clamp(1.5rem, 1rem + 1.5vw, 2.5rem);
    background: var(--color-bg);
}
.insp-featured__card {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1.25rem, 0.75rem + 1.5vw, 2rem);
    align-items: center;
}
.insp-featured__media {
    position: relative;
    display: block;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    background: var(--color-bg-alt);
}
.insp-featured__media img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: center;
    transition: transform var(--transition-slow);
}
@media (hover: hover) {
    .insp-featured__media:hover img { transform: scale(1.03); }
}
.insp-featured__body { padding-inline: 0; }
.insp-featured__cat {
    --hit-expander: 1;
    position: relative;
    display: inline-block;
    margin-bottom: var(--space-md);
    padding: 0.3rem 0.8rem;
    background: var(--color-bg-elevated);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    color: var(--color-eyebrow);
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 500;
    text-decoration: none;
    letter-spacing: 0.04em;
    transition: all var(--transition-fast);
}
/* Transparent hit-expander: lifts the tap target to the 44px floor without
   enlarging the visible kicker pill. Centered so it grows symmetrically. */
.insp-featured__cat::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 100%; height: 100%;
    min-width: 44px; min-height: 44px;
}
@media (hover: hover) {
    .insp-featured__cat:hover {
        border-color: var(--color-accent);
        color: var(--color-accent);
        transform: translateY(-1px);
    }
}
.insp-featured__title {
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -0.02em;
    margin: 0 0 var(--space-md);
    color: var(--color-heading);
    text-wrap: balance;
}
.insp-featured__title a {
    color: inherit; text-decoration: none;
    background-image: linear-gradient(var(--color-accent), var(--color-accent));
    background-size: 0% 2px; background-repeat: no-repeat;
    background-position: 0 100%;
    transition: background-size var(--transition-base);
}
@media (hover: hover) {
    .insp-featured__title a:hover { background-size: 100% 2px; }
}
.insp-featured__excerpt {
    font-size: var(--text-base);
    line-height: 1.55;
    color: var(--color-body);
    max-width: 56ch;
    margin: 0 0 var(--space-md);
    /* Cap at 3 lines to keep the card height bounded for viewport-fit. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.insp-featured__meta {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 0.4rem 1rem;
    margin-bottom: var(--space-md);
    font-size: var(--text-sm);
    color: var(--color-muted);
}
.insp-featured__meta > span {
    display: inline-flex; align-items: center; gap: 0.4rem;
}
.insp-featured__byline a {
    --hit-expander: 1;
    position: relative;
    color: var(--color-body);
    text-decoration: none;
    font-weight: 500;
    transition: color var(--transition-fast);
}
/* Vertical hit-expander: keeps the inline byline compact, lifts tap height to 44. */
.insp-featured__byline a::after {
    content: "";
    position: absolute;
    top: 50%; left: 0;
    transform: translateY(-50%);
    width: 100%; height: 100%;
    min-height: 44px;
}
@media (hover: hover) {
    .insp-featured__byline a:hover { color: var(--color-accent); }
}
.insp-featured__cta {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.85rem 1.5rem;
    background: var(--color-btn-primary-bg);
    color: var(--color-btn-primary-text);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.02em;
    text-decoration: none;
    border-radius: var(--radius-button);
    transition: transform var(--transition-base), box-shadow var(--transition-base);
}
@media (hover: hover) {
    .insp-featured__cta:hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-md);
    }
    .insp-featured__cta:hover .ph-icon { transform: translateX(3px); }
}
.insp-featured__cta .ph-icon { transition: transform var(--transition-base); }

@media (min-width: 768px) {
    .insp-featured__card {
        grid-template-columns: 1fr 1fr;
        gap: clamp(1.5rem, 1rem + 2vw, 2.5rem);
    }
    .insp-featured__media { aspect-ratio: 4 / 3; }
    .insp-featured__title { font-size: var(--text-3xl); }
}
@media (min-width: 1100px) {
    .insp-featured__card {
        grid-template-columns: 5fr 6fr;
    }
}

/* ════════════════════════════════════════════════════════════
   3. CATEGORY CHIP FILTER  (index + author archive)
   DOMINANT MOMENT: pill chips with sliding underline + count badge
   ════════════════════════════════════════════════════════════ */
.insp-grid {
    padding-block: clamp(3rem, 2rem + 4vw, 6rem);
}
.insp-grid__header {
    margin-bottom: var(--space-2xl);
}
.insp-grid__header--simple {
    display: flex; justify-content: space-between; align-items: baseline;
    flex-wrap: wrap; gap: var(--space-md);
}
/* Serif section title (two-voice: major SECTION titles are serif, not grotesk).
   Mirrors the established .kbp-band__title recipe. Dynamic ("Posts by {name}")
   so it stays plain - no rose-italic em accent (per decisions log). */
.insp-grid__heading {
    font-family: var(--font-serif);
    font-optical-sizing: auto;
    font-size: clamp(1.5rem, 1.05rem + 1.9vw, 2.5rem);
    font-weight: 350;
    color: var(--color-heading);
    margin: 0;
    letter-spacing: -0.015em;
    line-height: 1.05;
    text-wrap: balance;
}
.insp-grid__sub { margin: 0; }
.insp-grid__back {
    position: relative;
    display: inline-flex; align-items: center; gap: 0.35rem;
    color: var(--color-muted);
    font-size: var(--text-sm);
    text-decoration: none;
    transition: color var(--transition-fast);
}
/* Invisible vertical hit-expander -> 44px tap target; back-link stays compact */
.insp-grid__back::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
}
@media (hover: hover) {
    .insp-grid__back:hover { color: var(--color-accent); }
    .insp-grid__back:hover .ph-icon { transform: translateX(-3px); }
}
.insp-grid__back .ph-icon { transition: transform var(--transition-base); }

.insp-filter {
    display: flex; flex-wrap: wrap; gap: 0.6rem;
    justify-content: center;
    /* Clear breathing room above the chip row so it reads as a deliberate
       section divider between the featured post and the grid, not cramped
       under the Read-the-story button. */
    margin-top: clamp(2rem, 4vw, 3.5rem);
}
.insp-filter__chip {
    display: inline-flex; align-items: center; gap: 0.4rem;
    min-height: 44px;
    padding: 0.7rem 1.1rem;
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    color: var(--color-body);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    transition: all var(--transition-base);
}
.insp-filter__count {
    font-size: var(--text-2xs);
    color: var(--color-muted);
    font-variant-numeric: tabular-nums;
}
@media (hover: hover) {
    .insp-filter__chip:hover {
        border-color: var(--color-accent);
        color: var(--color-accent);
        transform: translateY(-2px);
        box-shadow: var(--shadow-sm);
    }
    .insp-filter__chip:hover .insp-filter__count { color: inherit; opacity: 0.85; }
}
.insp-filter__chip.is-active {
    background: var(--color-heading);
    color: var(--color-bg);
    border-color: var(--color-heading);
}
.insp-filter__chip.is-active .insp-filter__count { color: inherit; opacity: 0.75; }

.insp-filter__chip:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 3px;
}

/* ════════════════════════════════════════════════════════════
   4. POST GRID CARDS
   DOMINANT MOMENT: 3:4 portrait covers with subtle zoom + a kicker
   chip floating above the title. Card lifts on hover.
   ════════════════════════════════════════════════════════════ */
.insp-grid__cards {
    list-style: none;
    padding: 0; margin: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1.5rem, 1rem + 2vw, 2.5rem);
    /* A1: portrait cards span the full row width so the
       image-right / text-left magazine layout has room to breathe.
       Dense flow lets landscape tiles fill the row gaps cleanly. */
    grid-auto-flow: dense;
}
@media (min-width: 560px) {
    .insp-grid__cards { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 980px) {
    .insp-grid__cards { grid-template-columns: repeat(3, 1fr); }
}
.insp-card {
    display: flex; flex-direction: column;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card);
    overflow: hidden;
    transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base);
}
@media (hover: hover) {
    .insp-card:hover {
        transform: translateY(-4px);
        box-shadow: var(--shadow-lg);
        border-color: var(--color-border-hover);
    }
    .insp-card:hover .insp-card__media img { transform: scale(1.04); }
    .insp-card:hover .insp-card__title a { color: var(--color-accent); }
}
.insp-card[hidden] { display: none; }

.insp-card__media {
    display: block;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    background: var(--color-bg-alt);
    position: relative;
}
/* Landscape covers crop less aggressively at 3:2 - matches the
   shape of the source so subjects aren't sliced top/bottom. */
.insp-card--landscape > .insp-card__media {
    aspect-ratio: 3 / 2;
}

/* Featured lead card: the first post of each page spans two columns as a wide
   editorial tile with an oversized title - the grid's dominant moment that
   breaks the uniform 3-up wall. Desktop only; on 1-2 col layouts it reads as a
   normal card. */
@media (min-width: 980px) {
    .insp-grid__cards .insp-card--lead {
        grid-column: span 2;
    }
    .insp-card--lead > .insp-card__media {
        aspect-ratio: 16 / 9;
    }
    .insp-card--lead .insp-card__title {
        font-size: var(--text-2xl);
    }
}
.insp-card__media img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: center;
    transition: transform var(--transition-slow);
}
.insp-card__placeholder {
    width: 100%; height: 100%;
    display: grid; place-items: center;
    color: var(--color-muted);
    opacity: 0.5;
}
.insp-card__body {
    padding: var(--space-lg);
    display: flex; flex-direction: column; gap: var(--space-sm);
}
.insp-card__cat {
    --hit-expander: 1;
    position: relative;
    display: inline-flex; align-self: flex-start;
    padding: 0.25rem 0.7rem;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    color: var(--color-eyebrow);
    font-size: var(--text-2xs);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    text-decoration: none;
    transition: all var(--transition-fast);
}
/* Transparent hit-expander to the 44px floor; kicker stays visually small. */
.insp-card__cat::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 100%; height: 100%;
    min-width: 44px; min-height: 44px;
}
@media (hover: hover) {
    .insp-card__cat:hover {
        background: var(--color-accent);
        border-color: var(--color-accent);
        color: var(--color-btn-primary-text);
    }
}
.insp-card__title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.01em;
    margin: 0;
    color: var(--color-heading);
    text-wrap: balance;
}
.insp-card__title a {
    color: inherit; text-decoration: none;
    /* Underline-reveal on hover (ported from the featured card) so grid cards
       inherit a real signature move, not just a color shift. */
    background-image: linear-gradient(var(--color-accent), var(--color-accent));
    background-repeat: no-repeat;
    background-size: 0% 2px;
    background-position: 0 100%;
    padding-bottom: 2px;
    transition: color var(--transition-base), background-size var(--transition-base);
}
@media (hover: hover) {
    .insp-card:hover .insp-card__title a { background-size: 100% 2px; }
}
.insp-card__excerpt {
    font-size: var(--text-base);
    line-height: 1.55;
    color: var(--color-body);
    margin: 0;
    /* Cap excerpts to 3 lines so cards stay even */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.insp-card__meta {
    margin-top: auto;
    padding-top: var(--space-sm);
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem;
    font-size: var(--text-xs);
    color: var(--color-muted);
}
.insp-card__dot { opacity: 0.6; }

/* ────────────────────────────────────────────────────────────
   A1: PORTRAIT CARD VARIANT
   Portrait images get a full-row wide card with the image on the
   right and the editorial text on the left. Mobile + tablet
   collapse to the standard stacked layout (image top, text below)
   for readable column widths. Desktop (>=980px) activates the
   2-column inner layout so portrait covers display at native
   aspect without crop.
   DOMINANT MOMENT: oversized portrait cover paired with a calm,
   wide editorial text block. Visually anchors the row.
   ──────────────────────────────────────────────────────────── */
@media (min-width: 980px) {
    .insp-card--portrait {
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: minmax(0, 1fr) clamp(280px, 32%, 420px);
        align-items: stretch;
    }
    /* Visually swap: media goes to column 2, body to column 1.
       DOM order stays media-first for source-order reading. */
    .insp-card--portrait > .insp-card__media {
        grid-column: 2;
        grid-row: 1;
        aspect-ratio: 3 / 4;
        height: 100%;
    }
    .insp-card--portrait > .insp-card__body {
        grid-column: 1;
        grid-row: 1;
        padding: clamp(1.25rem, 0.75rem + 1.5vw, 2.5rem);
        gap: var(--space-md);
        justify-content: center;
    }
    /* Editorial scale-up of the headline so the wide card has presence. */
    .insp-card--portrait .insp-card__title {
        font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.25rem);
        line-height: 1.1;
        letter-spacing: -0.02em;
        max-width: 22ch;
    }
    .insp-card--portrait .insp-card__excerpt {
        font-size: var(--text-base);
        line-height: 1.65;
        -webkit-line-clamp: 4;
        max-width: 56ch;
    }
}

/* ────────────────────────────────────────────────────────────
   FEATURED LEAD CARD  (blog-category.php, first post i===0)
   DOMINANT MOMENT: full-width media/copy split that breaks the uniform 3-up
   category wall. Reuses the .insp-featured proportions (media ~5fr / copy ~6fr).
   The category grid inherited neither the index's featured card nor the author
   hero, so this is its one dominant moment. Media-left/copy-right; DOM order
   stays media-first for source-order reading.
   ──────────────────────────────────────────────────────────── */
@media (min-width: 560px) {
    /* Span the full row from the 2-col breakpoint so it always reads as a lead. */
    .insp-grid__cards .insp-card--cat-lead { grid-column: 1 / -1; }
}
@media (min-width: 980px) {
    .insp-grid__cards .insp-card--cat-lead {
        display: grid;
        grid-template-columns: 5fr 6fr;
        align-items: stretch;
    }
    .insp-card--cat-lead > .insp-card__media {
        grid-column: 1;
        grid-row: 1;
        /* Bounded crop. height:100% in a content-sized row resolves to the cover's
           natural height, so a PORTRAIT cover would balloon the card (this grid
           looks fine only because beauty-tips' cover is landscape). aspect-ratio
           gives object-fit:cover a definite box for any cover orientation. */
        aspect-ratio: 5 / 4;
    }
    .insp-card--cat-lead > .insp-card__body {
        grid-column: 2;
        grid-row: 1;
        padding: clamp(1.5rem, 1rem + 2vw, 3rem);
        gap: var(--space-md);
        justify-content: center;
    }
    /* Editorial scale-up of the headline so the lead has real presence. */
    .insp-card--cat-lead .insp-card__title {
        font-size: clamp(1.6rem, 1.15rem + 1.7vw, 2.6rem);
        line-height: 1.06;
        letter-spacing: -0.02em;
        max-width: 20ch;
    }
    .insp-card--cat-lead .insp-card__excerpt {
        font-size: var(--text-base);
        line-height: 1.6;
        -webkit-line-clamp: 4;
        max-width: 54ch;
    }
}

/* ────────────────────────────────────────────────────────────
   RAISED/LOWERED CARD STAGGER  (playbook item 2 - grid rhythm)
   The MIDDLE column of each 3-up row drops by --space-2xl, giving a consistent,
   repeating arc rhythm instead of a flat wall. Opt-in via --stagger so it only
   applies to grids with this exact structure (full-width lead as child 1, then a
   uniform 3-up flow) - NOT the index/author grids whose lead spans differently.

   Why middle-column and not nth-child(even): a 3-col grid has an ODD column
   count, so nth-child(even) lands in different columns each row and the offsets
   flip row-to-row (looks broken). Targeting the middle column (child 3,6,9 =
   nth-child(3n), given the full-width lead is child 1) drops the SAME column
   every row. Uses margin (not transform) because the cards carry the
   insp-fade-up reveal whose `both` fill sets transform; margin also reserves
   space so the drop can't overlap the next row. Desktop 3-up only, reduced-
   motion gated. */
@media (min-width: 980px) {
    .insp-grid__cards--stagger { align-items: start; }
}
@media (min-width: 980px) and (prefers-reduced-motion: no-preference) {
    .insp-grid__cards--stagger > .insp-card:nth-child(3n):not(.insp-card--cat-lead):not(.insp-card--lead):not(.insp-card--portrait) {
        margin-block-start: var(--space-2xl);
    }
}

.insp-grid__empty,
.insp-grid__empty-state {
    text-align: center;
    color: var(--color-muted);
    font-size: var(--text-base);
    padding: var(--space-2xl) 0;
}
.insp-grid__reset {
    background: none; border: 0; padding: 0;
    color: var(--color-accent);
    text-decoration: underline; text-underline-offset: 3px;
    cursor: pointer; font: inherit;
}

/* ════════════════════════════════════════════════════════════
   5. PAGINATION
   ════════════════════════════════════════════════════════════ */
.insp-pagination {
    margin-top: clamp(2rem, 1.5rem + 2vw, 4rem);
    display: flex; justify-content: center;
}
.insp-pagination__list {
    list-style: none; padding: 0; margin: 0;
    display: inline-flex; flex-wrap: wrap; gap: 0.35rem;
    align-items: center;
}
.insp-pagination__item {
    display: inline-flex;
}
.insp-pagination__link,
.insp-pagination__link.is-current {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 44px; height: 44px;
    padding: 0 0.85rem;
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-button);
    color: var(--color-body);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 500;
    text-decoration: none;
    transition: all var(--transition-base);
}
@media (hover: hover) {
    .insp-pagination__link:hover {
        border-color: var(--color-accent);
        color: var(--color-accent);
        transform: translateY(-1px);
    }
}
.insp-pagination__link.is-current {
    background: var(--color-heading);
    color: var(--color-bg);
    border-color: var(--color-heading);
    cursor: default;
}
.insp-pagination__sep {
    padding: 0 0.25rem;
    color: var(--color-muted);
}

/* ════════════════════════════════════════════════════════════
   6. CLOSING CTA  (shared across all 4 templates)
   ════════════════════════════════════════════════════════════ */
.insp-cta {
    padding-block: clamp(3.5rem, 2.5rem + 4vw, 6rem);
    text-align: center;
    /* Honor .section--cta token rebinds in both themes. Without this the section
       has no background and the rebound --color-bg is bound but never painted,
       so the heading (which uses --color-heading, also rebound to a dark deep
       teal) shows on the underlying body --color-bg dark teal: dark-on-dark. */
    background-color: var(--color-bg);
    color: var(--color-body);
}
.insp-cta__eyebrow {
    color: var(--color-heading);
    opacity: 0.85;
}
.insp-cta__heading {
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -0.02em;
    margin: var(--space-md) auto var(--space-md);
    max-width: 20ch;
    color: var(--color-heading);
    text-wrap: balance;
}
.insp-cta__heading em {
    font-style: italic;
    font-weight: inherit;
    /* Rose italic accent word: reads on the warm cream ground in light and on
       the near-black navy band in dark (the CTA is no longer a teal field). */
    color: var(--color-rose);
}
.insp-cta__lead {
    max-width: 52ch;
    margin: 0 auto var(--space-xl);
    font-size: var(--text-base);
    line-height: 1.6;
    color: var(--color-body);
    opacity: 0.92;
}
.insp-cta__actions {
    display: flex; flex-wrap: wrap; justify-content: center;
    gap: var(--space-md);
}
/* Light-mode CTA: rebuild as a warm depth surface instead of the flat,
   fully-saturated teal wall the global [data-theme=light] .section--cta rebind
   paints (--color-bg: #4daab8). Cream ground + a soft teal-tinted radial glow;
   teal drops to the primary button + accents only (XC-4: never teal as a light
   section fill). Scoped to .insp-cta so the site-wide CTA token rebind used by
   other pages is untouched. (0,3,0) beats the [data-theme=light] .section--cta
   rebind (0,2,0). */
[data-theme="light"] .insp-cta.section--cta {
    --color-bg: #fdf6f0;
    --color-heading: #3a2828;
    --color-body: #6b5548;
    background:
        radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--color-accent-glow) 16%, transparent) 0%, transparent 62%),
        linear-gradient(to bottom, #fdf6f0 0%, #f8ede6 100%);
}

/* Dark-mode CTA: full theme swap.
   The global .section--cta utility rebinds tokens to a near-identical
   cyan in both light and dark, so toggling the theme on a page that
   ends in a CTA used to be a no-op visually. In dark mode we override
   the entire section to read as dark: navy gradient ground with a
   cyan radial glow at the base, white heading, rose outline button,
   cyan primary button. Light mode keeps the bright cyan field.
   Selector uses both classes for specificity (0,2,0) so we beat the
   global .section--cta token rebind (0,1,1) and inherit cleanly. */
[data-theme="dark"] .insp-cta.section--cta {
    background:
        radial-gradient(ellipse at 50% 100%, color-mix(in srgb, var(--color-accent-glow) 22%, transparent) 0%, transparent 65%),
        linear-gradient(to bottom, var(--color-bg-alt) 0%, var(--color-bg-footer) 100%);
    --color-heading: #ffffff;
    --color-body: #b8d2da;
    --color-eyebrow: var(--color-rose);
    --color-btn-primary-bg: var(--color-accent);
    --color-btn-primary-text: var(--color-bg-footer);
    --color-btn-outline-border: var(--color-rose);
    --color-btn-outline-text: var(--color-rose);
}

/* ════════════════════════════════════════════════════════════
   7. CATEGORY ARCHIVE HERO  (blog-category.php)
   DOMINANT MOMENT: single bold topic title on flat cream, framed by
   a rose-accent eyebrow tag and a back-link breadcrumb.
   ════════════════════════════════════════════════════════════ */
.cat-hero {
    position: relative;
    isolation: isolate;
    /* Toward the author-hero scale so the hero reads as the page's most spacious
       moment (was noticeably tighter than the sibling archives). */
    padding-block: clamp(2.75rem, 2rem + 3vw, 5rem) clamp(2rem, 1.5rem + 2vw, 3.5rem);
    background:
        radial-gradient(ellipse at 50% 0%, rgba(212, 160, 160, 0.10) 0%, transparent 60%),
        linear-gradient(to bottom, var(--color-bg-mid) 0%, var(--color-bg) 100%);
    overflow: hidden;
}
.cat-hero__grain {
    position: absolute; inset: 0; z-index: -1; pointer-events: none;
    opacity: 0.05;
    background-image: radial-gradient(circle at 1px 1px, var(--color-heading) 1px, transparent 0);
    background-size: 24px 24px;
}
.cat-hero__inner {
    max-width: var(--container-wide);
    text-align: center;
}
.cat-hero__breadcrumbs {
    margin-bottom: var(--space-xl);
    font-size: var(--text-xs);
}
.cat-hero__breadcrumbs ol {
    display: inline-flex; flex-wrap: wrap; gap: 0.5rem;
    justify-content: center;
    padding: 0; margin: 0; list-style: none;
    color: var(--color-muted);
}
/* Separator from the global `.breadcrumbs li + li::before` - see .insp-hero__breadcrumbs. */
.cat-hero__breadcrumbs a {
    color: var(--color-muted); text-decoration: none;
    transition: color var(--transition-fast);
}
.cat-hero__breadcrumbs a:hover { color: var(--color-accent); }

.cat-hero__eyebrow {
    display: inline-flex; align-items: center; gap: 0.5rem;
    margin-bottom: var(--space-lg);
    color: var(--color-eyebrow);
}
.cat-hero__title {
    /* Velvet Cinema editorial serif hero (matches .svcs-hero__title). */
    font-family: var(--font-serif);
    font-optical-sizing: auto;
    font-size: clamp(2.1rem, 1.5rem + 2.5vw, 3.25rem);
    font-weight: 350;
    line-height: 1.04;
    letter-spacing: -0.015em;
    margin: 0 auto var(--space-md);
    color: var(--color-heading);
    text-wrap: balance;
    max-width: 22ch;
}
.cat-hero__title em {
    font-style: italic;
    font-weight: 480;
    color: var(--color-rose-deep);
}
.cat-hero__lead {
    font-size: var(--text-base);
    line-height: 1.65;
    color: var(--color-body);
    margin-left: auto; margin-right: auto;
    max-width: 58ch;
    margin-bottom: var(--space-xl);
}
.cat-hero__lead p { margin: 0 0 0.75em; }
.cat-hero__lead p:last-child { margin-bottom: 0; }
/* Body content may contain h2/h3 from the page->body field. Rescale them
   to subhead size in the hero context so they don't compete with the page H1. */
.cat-hero__lead h2,
.cat-hero__lead h3,
.cat-hero__lead h4 {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: 0;
    color: var(--color-heading);
    margin: 0 0 0.5em;
    text-wrap: balance;
}
/* DOMINANT MOMENT: oversized post-count stat - .cat-hero__stat
   Gives the text-only category hero a focal element beyond centered type, in
   the serif voice (matches the index hero's stat treatment). Sits under the
   title/lead as the hero's signature. */
.cat-hero__stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    /* The global `p { max-width: 70ch }` measure rule constrains this <p>, so
       without auto side-margins it pinned to the left content edge (off-centre).
       margin-inline: auto re-centres the constrained block under the hero. */
    margin: 0 auto var(--space-lg);
}
.cat-hero__stat-num {
    font-family: var(--font-serif);
    font-optical-sizing: auto;
    font-size: clamp(2.75rem, 2rem + 4vw, 4rem);
    font-weight: 300;
    line-height: 0.95;
    letter-spacing: -0.02em;
    color: var(--color-heading);
}
.cat-hero__stat-label {
    max-width: 30ch;
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    line-height: 1.4;
    color: var(--color-eyebrow);
    text-wrap: balance;
}
/* Same constraint as the stat: the global p{max-width:70ch} rule sizes this <p>,
   so without auto side-margins the back-link pinned to the left edge. Centre it. */
.cat-hero__meta { margin: 0 auto; }
.cat-hero__back {
    /* Audit opt-in for the 44px ::after below. An earlier run reported this
       failing at 768; that was a measurement artefact (the probe read stale
       coordinates without scrolling the link into view). Re-tested properly it
       passes both sides at 390 and 768, with the nearest reachable interactive
       neighbour 48px+ away. */
    --hit-expander: 1;
    position: relative;
    display: inline-flex; align-items: center; gap: 0.35rem;
    color: var(--color-muted);
    font-size: var(--text-sm);
    text-decoration: none;
    transition: color var(--transition-fast);
}
/* Invisible vertical hit-expander -> 44px tap target; back-link stays compact */
.cat-hero__back::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
}
@media (hover: hover) {
    .cat-hero__back:hover { color: var(--color-accent); }
    .cat-hero__back:hover .ph-icon { transform: translateX(-3px); }
}
.cat-hero__back .ph-icon { transition: transform var(--transition-base); }

/* ════════════════════════════════════════════════════════════
   8. AUTHOR ARCHIVE HERO  (blog-author.php)
   DOMINANT MOMENT: large circular portrait paired with the
   author's name in display weight + a stat number + dual CTAs.
   Asymmetric 5/7 layout on desktop.
   ════════════════════════════════════════════════════════════ */
.author-hero {
    position: relative; isolation: isolate;
    padding-block: clamp(3rem, 2rem + 5vw, 6rem) clamp(2rem, 1.5rem + 3vw, 4rem);
    background:
        radial-gradient(ellipse at 75% 0%, color-mix(in srgb, var(--color-accent-glow) 10%, transparent) 0%, transparent 55%),
        linear-gradient(to bottom, var(--color-bg-mid) 0%, var(--color-bg) 100%);
    overflow: hidden;
}
.author-hero__grain {
    position: absolute; inset: 0; z-index: -1; pointer-events: none;
    opacity: 0.05;
    background-image: radial-gradient(circle at 1px 1px, var(--color-heading) 1px, transparent 0);
    background-size: 24px 24px;
}
.author-hero__inner { max-width: var(--container-wide); }
.author-hero__breadcrumbs { margin-bottom: var(--space-xl); font-size: var(--text-xs); }
.author-hero__breadcrumbs ol {
    display: flex; flex-wrap: wrap; gap: 0.5rem;
    padding: 0; margin: 0; list-style: none;
    color: var(--color-muted);
}
/* Separator from the global `.breadcrumbs li + li::before` - see .insp-hero__breadcrumbs. */
.author-hero__breadcrumbs a {
    color: var(--color-muted); text-decoration: none;
    transition: color var(--transition-fast);
}
.author-hero__breadcrumbs a:hover { color: var(--color-accent); }

.author-hero__layout {
    display: grid; grid-template-columns: 1fr;
    gap: clamp(1.5rem, 1rem + 2vw, 3rem);
    align-items: center;
}
.author-hero__photo {
    position: relative;
    /* Bumped floor + ceiling so the portrait carries enough visual weight
       to anchor the asymmetric layout against the display-size name. */
    width: clamp(200px, 32vw, 340px);
    aspect-ratio: 1;
    border-radius: var(--radius-full);
    overflow: hidden;
    background: var(--color-bg-alt);
    box-shadow: var(--shadow-lg);
    isolation: isolate;
}
.author-hero__photo::after {
    /* Subtle accent ring on hover (desktop) keeps the photo
       feeling clickable without adding chrome at rest. */
    content: '';
    position: absolute; inset: 0;
    border-radius: inherit;
    box-shadow: inset 0 0 0 2px var(--color-border);
    pointer-events: none;
}
.author-hero__photo img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: center;
}
.author-hero__photo-placeholder {
    width: 100%; height: 100%;
    display: grid; place-items: center;
    color: var(--color-muted);
    opacity: 0.5;
}
.author-hero__copy { min-width: 0; }
.author-hero__eyebrow {
    display: inline-flex; align-items: center; gap: 0.5rem;
    margin-bottom: var(--space-md);
    color: var(--color-eyebrow);
}
.author-hero__title {
    /* Velvet Cinema editorial serif hero (matches .svcs-hero__title). */
    font-family: var(--font-serif);
    font-optical-sizing: auto;
    font-size: clamp(2.2rem, 1.5rem + 3vw, 4rem);
    font-weight: 350;
    line-height: 1.02;
    letter-spacing: -0.015em;
    margin: 0 0 var(--space-sm);
    color: var(--color-heading);
    text-wrap: balance;
}
.author-hero__title em {
    font-style: italic;
    font-weight: 480;
    color: var(--color-rose-deep);
}
.author-hero__role {
    margin: 0 0 var(--space-md);
    color: var(--color-muted);
    font-size: var(--text-base);
    font-weight: 500;
}
.author-hero__bio {
    color: var(--color-body);
    font-size: var(--text-base);
    line-height: 1.65;
    max-width: 58ch;
    margin-bottom: var(--space-lg);
}
.author-hero__bio p { margin: 0 0 0.75em; }
.author-hero__bio p:last-child { margin-bottom: 0; }
/* Inline links in the imported staff-bio excerpt are decorative
   here - tone them down so the hero copy reads as one block instead
   of a noisy list of highlighted phrases. */
.author-hero__bio a {
    color: var(--color-body);
    text-decoration: none;
    border-bottom: 1px dotted var(--color-border-hover);
    transition: color var(--transition-fast), border-color var(--transition-fast);
}
@media (hover: hover) {
    .author-hero__bio a:hover {
        color: var(--color-accent);
        border-bottom-color: var(--color-accent);
    }
}
.author-hero__bio h2,
.author-hero__bio h3 {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: 1.3;
    color: var(--color-heading);
    margin: 0 0 0.4em;
}

/* Inline pill chip replacing the old hairline-bracketed stat block.
   Reads as one editorial credit line ("12 stories published") rather
   than a metadata footer, and frees the hero of the visual frame that
   previously made the stat compete with the H1. */
.author-hero__stat-chip {
    display: inline-flex; align-items: baseline; gap: 0.5rem;
    margin: var(--space-md) 0 var(--space-lg);
    padding: 0.5rem 0.95rem;
    background: var(--color-bg-elevated);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    color: var(--color-muted);
    font-family: var(--font-body);
    font-size: var(--text-2xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    line-height: 1;
}
.author-hero__stat-num {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 800;
    color: var(--color-heading);
    letter-spacing: -0.02em;
    line-height: 1;
}
.author-hero__stat-label { color: var(--color-muted); }
.author-hero__actions {
    display: flex; flex-wrap: wrap; gap: var(--space-md);
}

@media (min-width: 720px) {
    .author-hero__layout {
        grid-template-columns: auto 1fr;
        gap: clamp(2rem, 1.5rem + 2vw, 3rem);
    }
}

/* ════════════════════════════════════════════════════════════
   9. SINGLE POST HERO  (blog-post.php)  -  B3 text-first
   DOMINANT MOMENT: oversized H1 on cream radial-gradient backdrop,
   with rose-accent eyebrow + framed byline strip. No background
   photo - the cover appears in a contained band below the hero so
   landscape AND portrait covers can both shine at native aspect.
   Theme-safe: every color resolves through design-tokens.css.
   ════════════════════════════════════════════════════════════ */
.post-hero {
    position: relative;
    isolation: isolate;
    /* Quieter framing - tightened the top floor so the cover band below
       gets meaningful presence in the initial 900px viewport. */
    padding-block: clamp(2rem, 1.5rem + 3vw, 4.5rem) clamp(1.25rem, 1rem + 1.5vw, 2.5rem);
    background:
        radial-gradient(ellipse at 15% 0%, rgba(212, 160, 160, 0.10) 0%, transparent 55%),
        radial-gradient(ellipse at 85% 35%, color-mix(in srgb, var(--color-accent-glow) 8%, transparent) 0%, transparent 60%),
        linear-gradient(to bottom, var(--color-bg-mid) 0%, var(--color-bg) 100%);
    color: var(--color-heading);
    overflow: hidden;
}
.post-hero__grain {
    position: absolute; inset: 0; z-index: -1; pointer-events: none;
    opacity: 0.05;
    background-image: radial-gradient(circle at 1px 1px, var(--color-heading) 1px, transparent 0);
    background-size: 24px 24px;
}
.post-hero__inner {
    position: relative;
    width: 100%;
    max-width: var(--container-wide);
}
.post-hero__breadcrumbs {
    font-size: var(--text-xs);
    margin-bottom: var(--space-lg);
    color: var(--color-muted);
}
.post-hero__breadcrumbs ol {
    display: flex; flex-wrap: wrap; gap: 0.5rem;
    padding: 0; margin: 0; list-style: none;
}
/* Separator from the global `.breadcrumbs li + li::before` - see .insp-hero__breadcrumbs. */
.post-hero__breadcrumbs a {
    position: relative;
    color: var(--color-muted); text-decoration: none;
    transition: color var(--transition-fast);
}
/* Invisible vertical hit-expander -> 44px tap target; crumb stays compact */
.post-hero__breadcrumbs a::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
}
.post-hero__breadcrumbs a:hover { color: var(--color-accent); }

.post-hero__eyebrow {
    display: inline-flex; align-items: center; gap: 0.4rem;
    margin-bottom: var(--space-md);
    color: var(--color-eyebrow);
}
.post-hero__eyebrow a {
    color: inherit; text-decoration: none;
    text-transform: uppercase; letter-spacing: 0.12em;
    font-size: var(--text-xs); font-weight: 600;
    /* Category link in the post hero: 97x18. Wide enough already, only the
       height is short, so a height-only expander is enough. */
    --hit-expander: 1;
    position: relative;
}
/* Invisible vertical hit-expander -> 44px tap height; the eyebrow stays compact.
   Anchored UPWARD, not centred: .post-hero__title sits directly below and paints
   over the lower half of a centred zone (measured - a probe 20px below centre
   returned h1.post-hero__title, leaving ~42px hit-testable). Winning that with
   z-index would overlay the heading's top edge and would still depend on paint
   order that a scroll-animation transform can change. Growing up into the
   container's padding is deterministic: nothing interactive is up there, the
   nearest target is 53px away, and the full 44px stays reachable. Same reasoning
   as .photo-credit__chip--stylist in style.css. */
.post-hero__eyebrow a::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: auto; bottom: 0; height: 44px;
}
@media (hover: hover) {
    .post-hero__eyebrow a:hover { color: var(--color-accent); }
}

.post-hero__title {
    /* Velvet Cinema editorial serif hero (matches .svcs-hero__title). */
    font-family: var(--font-serif);
    font-optical-sizing: auto;
    font-size: clamp(2.2rem, 1.5rem + 3.5vw, 4rem);
    font-weight: 350;
    line-height: 1.04;
    letter-spacing: -0.015em;
    margin: 0 0 var(--space-md);
    color: var(--color-heading);
    max-width: 24ch;
    text-wrap: balance;
}
.post-hero__title em {
    font-style: italic;
    font-weight: 480;
    color: var(--color-rose-deep);
}
.post-hero__excerpt {
    font-size: var(--text-lg);
    line-height: 1.55;
    margin: 0 0 var(--space-lg);
    max-width: 62ch;
    color: var(--color-body);
}

.post-hero__byline {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 0.5rem 1rem;
    font-size: var(--text-sm);
    color: var(--color-muted);
    padding-top: var(--space-md);
    border-top: 1px solid var(--color-border);
}
.post-hero__author {
    position: relative;
    display: inline-flex; align-items: center; gap: 0.65rem;
    color: var(--color-body); text-decoration: none;
    transition: color var(--transition-fast);
    /* 40px tall (the avatar sets the height), four short of the touch floor.
       Nearest reachable interactive neighbour is 34px away at 390, so a 44px
       zone clears it. */
    --hit-expander: 1;
}
.post-hero__author::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
}
@media (hover: hover) {
    .post-hero__author:hover { color: var(--color-accent); }
    .post-hero__author:hover .post-hero__author-avatar { transform: scale(1.05); }
}
.post-hero__author-avatar {
    width: 40px; height: 40px;
    border-radius: var(--radius-full);
    object-fit: cover; object-position: center;
    border: 2px solid var(--color-border-hover);
    transition: transform var(--transition-base);
}
.post-hero__author-name { display: flex; flex-direction: column; line-height: 1.2; }
.post-hero__author-label {
    font-size: var(--text-2xs);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-muted);
}
.post-hero__author-name strong {
    font-weight: 600;
    color: var(--color-heading);
}

/* ════════════════════════════════════════════════════════════
   9b. POST COVER BAND  (blog-post.php)
   DOMINANT MOMENT: full-bleed cover image between hero + body,
   wrapped in a rounded frame. Adapts to native aspect (landscape
   AND portrait) via max-height cap rather than crop.
   ════════════════════════════════════════════════════════════ */
.post-cover {
    margin: 0;
    padding: 0 0 clamp(2rem, 1.5rem + 2vw, 3rem);
    background: var(--color-bg);
}
.post-cover__frame {
    max-width: var(--container-wide);
    margin: 0 auto;
    padding-inline: var(--container-padding);
    aspect-ratio: auto;
}
.post-cover__frame img {
    display: block;
    width: 100%;
    height: auto;
    max-height: 70vh;
    object-fit: cover;
    object-position: center;
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
}
.post-cover__caption {
    display: block;
    margin: var(--space-md) auto 0;
    max-width: 68ch;
    color: var(--color-muted);
    font-size: var(--text-sm);
    font-style: italic;
    text-align: center;
}

/* ════════════════════════════════════════════════════════════
   9c. POST BODY WRAP + STICKY TABLE OF CONTENTS
   DOMINANT MOMENT: vertical accent rail on the active TOC item
   glides in via IntersectionObserver as the reader scrolls. The
   TOC is hidden under 1024px (anchors still work in body).
   ════════════════════════════════════════════════════════════ */
.post-body-wrap__inner {
    display: block;
}
.post-body-wrap__main {
    /* Single-column mode: keep prose centered within the container. */
    max-width: 68ch;
    margin: 0 auto;
}
.post-toc {
    /* Hidden by default; shown on desktop only via the with-toc grid. */
    display: none;
}
@media (min-width: 1024px) {
    .post-body-wrap--with-toc .post-body-wrap__inner {
        display: grid;
        grid-template-columns: minmax(0, 68ch) minmax(220px, 260px);
        gap: clamp(2rem, 1rem + 3vw, 4rem);
        /* Default stretch alignment is required - align-items: start collapses
           the TOC column to its content height, which kills position:sticky
           (sticky needs room within its containing block to actually stick). */
        justify-content: center;
    }
    /* DOM order is TOC then body for source-order semantics; visually the
       body lives in column 1 and the TOC rail in column 2. Explicit
       grid-column placements override the default row flow. */
    .post-body-wrap--with-toc .post-body-wrap__main {
        grid-column: 1;
        grid-row: 1;
        max-width: none;
        min-width: 0;
        margin: 0;
    }
    .post-body-wrap--with-toc .post-toc {
        grid-column: 2;
        grid-row: 1;
    }
    .post-toc { display: block; }
}

.post-toc__sticky {
    position: sticky;
    /* --sticky-top, not a spacing token. calc(--space-2xl + 1rem) is 64px, which
       was never header-aware: measured on staging at 1280x800 this TOC sat 93px
       behind the 157px header with 16% of it hidden. Same family as the seven
       sticky components fixed on 2026-08-02 - see reference_sticky_top_token.

       It survived that sweep because the audit only visited hub pages, and this
       component only exists on blog-post.php article pages. The harness now
       discovers sticky elements in the DOM and walks article pages, which is how
       this was found.

       Height guard tracks the same token deliberately: raising the offset
       without raising it pushes the panel off the bottom instead, trading an
       overlap for an overflow. Mirrors .faq-toc and .rfc-panel. */
    top: var(--sticky-top);
    max-height: calc(100svh - var(--sticky-top) - 1rem);
    /* Vertical only, declared on both axes deliberately. `overflow-y: auto` on its
       own computes overflow-x to `auto` (CSS Overflow 3 - a `visible` value cannot
       survive alongside a non-visible companion), and the global 11px
       ::-webkit-scrollbar in style.css makes those bars take real layout width in
       Chrome on Windows. That was enough for a sub-pixel column width to raise a
       horizontal scrollbar under a rail that has nothing to scroll sideways.
       Ben reported it 2026-08-28. Headless Chromium uses OVERLAY scrollbars and
       reports 0px overflow here even for a hand-made scroller, so do not "verify"
       this from a headless measurement - it cannot see the bug. */
    overflow-x: hidden;
    overflow-y: auto;
    /* Reaching the end of a short TOC should not start scrolling the article. */
    overscroll-behavior: contain;
    padding: 0;
}
.post-toc__label {
    margin: 0 0 var(--space-md);
    padding: 0 0 var(--space-sm);
    border-bottom: 1px solid var(--color-border);
    font-family: var(--font-body);
    font-size: var(--text-2xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-muted);
}
.post-toc__list {
    list-style: none;
    padding: 0;
    margin: 0;
    counter-reset: toc;
}
.post-toc__item {
    position: relative;
    margin: 0;
}
.post-toc__link {
    position: relative;
    display: grid;
    /* minmax(0, 1fr), not a bare 1fr: a bare `1fr` track floors at min-content, so a
       single long unbreakable heading word would push the link wider than the rail.
       With overflow-x hidden above, that would now clip instead of scroll. */
    grid-template-columns: 1.75rem minmax(0, 1fr);
    align-items: baseline;
    align-content: center;
    min-height: 44px;
    gap: 0.25rem;
    padding: 0.45rem 0.75rem 0.45rem 0.75rem;
    border-left: 2px solid var(--color-border);
    color: var(--color-muted);
    text-decoration: none;
    font-size: var(--text-sm);
    line-height: 1.4;
    transition:
        color var(--transition-base),
        border-color var(--transition-base),
        background var(--transition-base),
        transform var(--transition-base);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.post-toc__num {
    font-family: var(--font-body);
    font-size: var(--text-2xs);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--color-border-hover);
    transition: color var(--transition-base);
}
.post-toc__text {
    color: inherit;
    /* Last-resort break for a word longer than the rail (a product name, a URL).
       Paired with the minmax(0, 1fr) track above so nothing can escape the box now
       that overflow-x is hidden. */
    overflow-wrap: anywhere;
    /* Cap long h2s to 3 lines in the rail. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
@media (hover: hover) {
    .post-toc__link:hover {
        color: var(--color-heading);
        background: linear-gradient(
            to right,
            color-mix(in srgb, var(--color-accent) 6%, transparent),
            transparent 80%
        );
        transform: translateX(2px);
    }
    .post-toc__link:hover .post-toc__num { color: var(--color-rose); }
}
.post-toc__link.is-active {
    color: var(--color-heading);
    border-left-color: var(--color-accent);
    background: linear-gradient(
        to right,
        color-mix(in srgb, var(--color-accent) 8%, transparent),
        transparent 70%
    );
    font-weight: 600;
}
.post-toc__link.is-active .post-toc__num { color: var(--color-accent); }
.post-toc__link:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 2px;
}

.post-hero__sep {
    width: 4px; height: 4px;
    border-radius: var(--radius-full);
    background: currentColor; opacity: 0.4;
}
.post-hero__date,
.post-hero__readtime {
    display: inline-flex; align-items: center; gap: 0.4rem;
    opacity: 0.85;
}

/* ════════════════════════════════════════════════════════════
   10. POST BODY  (typography rules + drop cap)
   DOMINANT MOMENT: 4-line drop cap on the opening paragraph in the
   display font + accent rose, plus blockquote with rose left rule.
   ════════════════════════════════════════════════════════════ */
.post-body-wrap {
    padding-block: clamp(3rem, 2rem + 4vw, 6rem);
    background: var(--color-bg);
}
/* Dark theme: a soft teal glow anchored to the top of the body keeps the long
   article from reading as one flat navy field (the palette rule the audit flags). */
[data-theme="dark"] .post-body-wrap {
    background:
        radial-gradient(ellipse 65% 24% at 50% 0%, color-mix(in srgb, var(--color-accent-glow) 9%, transparent) 0%, transparent 55%),
        var(--color-bg);
}
.post-body {
    max-width: 68ch;
    margin: 0 auto;
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.75;
    color: var(--color-body);
    counter-reset: post-section;
}
.post-body > p,
.post-body > ul,
.post-body > ol,
.post-body > blockquote,
.post-body > figure,
.post-body > pre,
.post-body > hr,
.post-body > h2,
.post-body > h3,
.post-body > h4 {
    margin-block: 0 1.25em;
}
/* Drop cap lands on the article's first paragraph whether the body opens with
   a <p> or (as most posts do) a leading <h2> followed by the first <p>. The two
   selectors are mutually exclusive, so the cap only ever fires once. */
.post-body > p:first-child::first-letter,
.post-body > h2:first-child + p::first-letter {
    float: left;
    font-family: var(--font-display);
    font-size: 4.5em;
    line-height: 0.85;
    font-weight: 800;
    color: var(--color-rose);
    margin: 0.08em 0.12em 0 0;
    padding: 0;
}
.post-body h2 {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.015em;
    color: var(--color-heading);
    margin-block: 2.5em 0.75em;
    text-wrap: balance;
    /* Numbered chapter marker + hairline rule turn a flat ladder of equal-weight
       H2s into distinct, sequenced sections - the article's reading rhythm. */
    position: relative;
    padding-top: 1.15em;
    border-top: 1px solid var(--color-border);
}
.post-body h2::before {
    counter-increment: post-section;
    content: counter(post-section, decimal-leading-zero);
    display: block;
    font-family: var(--font-mono, var(--font-body));
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: 0.18em;
    color: var(--color-rose);
    margin-bottom: 0.6em;
}
/* The opening H2 sits right under the hero figure - no rule/number/big gap there
   so the article starts clean (and the drop cap on the following <p> leads). */
.post-body > h2:first-child {
    margin-top: 0.5em;
    padding-top: 0;
    border-top: 0;
}
.post-body > h2:first-child::before { content: none; }
.post-body h3 {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    line-height: 1.2;
    color: var(--color-heading);
    margin-block: 2em 0.5em;
}
.post-body h4 {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--color-heading);
    margin-block: 1.75em 0.4em;
}
.post-body a {
    color: var(--color-link);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    transition: color var(--transition-fast), text-decoration-thickness var(--transition-fast);
}
@media (hover: hover) {
    .post-body a:hover {
        color: var(--color-accent-hover);
        text-decoration-thickness: 2px;
    }
}
.post-body strong { color: var(--color-heading); font-weight: 700; }
.post-body em { font-style: italic; }

.post-body ul,
.post-body ol { padding-left: 1.5em; }
.post-body li { margin-bottom: 0.5em; }
.post-body li::marker { color: var(--color-rose); }

.post-body blockquote {
    margin: 2em 0;
    padding: 0.5em 0 0.5em 1.5em;
    border-left: 3px solid var(--color-rose);
    font-family: var(--font-display);
    font-style: italic;
    font-size: var(--text-lg);
    line-height: 1.5;
    color: var(--color-heading);
    text-wrap: pretty;
}
.post-body blockquote p:last-child { margin-bottom: 0; }
.post-body blockquote cite {
    display: block;
    margin-top: 0.5em;
    font-family: var(--font-body);
    font-style: normal;
    font-size: var(--text-sm);
    color: var(--color-muted);
    letter-spacing: 0.04em;
}

.post-body img,
.post-body figure {
    max-width: 100%; height: auto;
    border-radius: var(--radius-image);
}
.post-body figure { margin: 2em 0; }
.post-body figure img { display: block; width: 100%; }
.post-body figcaption {
    margin-top: 0.6em;
    font-size: var(--text-sm);
    font-style: italic;
    color: var(--color-muted);
    text-align: center;
}

.post-body hr {
    border: 0; height: 1px;
    background: var(--color-border);
    margin: 3em 0;
}

.post-body pre,
.post-body code {
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.9em;
}
.post-body pre {
    background: var(--color-bg-alt);
    padding: 1em 1.25em;
    border-radius: var(--radius-md);
    overflow-x: auto;
    line-height: 1.5;
}
.post-body code {
    background: var(--color-bg-alt);
    padding: 0.1em 0.3em;
    border-radius: 4px;
}
.post-body pre code { background: transparent; padding: 0; }

/* Tags + share footer */
.post-tags {
    max-width: 68ch;
    margin: 3em auto 0;
    padding-top: 1.5em;
    border-top: 1px solid var(--color-border);
    display: flex; flex-wrap: wrap; align-items: center;
    /* Row gap 0.875rem, not 0.75rem: the chips are ~31px and carry a 44px
       expander, so at the old 12px gap a post with enough tags to wrap would
       put two rows on a 43px pitch and let the zones overlap. 31 + 14 = 45. */
    gap: 0.875rem 0.75rem;
}
.post-tags__label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-muted);
}
.post-tags__list {
    list-style: none; padding: 0; margin: 0;
    display: flex; flex-wrap: wrap; gap: 0.5rem;
}
.post-tags__chip {
    /* ~30px tall. Expander rather than real height: these are deliberate small
       pills and growing them changes the tag row's rhythm. */
    --hit-expander: 1;
    position: relative;
    display: inline-flex; padding: 0.3rem 0.8rem;
    background: var(--color-bg-elevated);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    color: var(--color-body);
    font-size: var(--text-xs);
    text-decoration: none;
    transition: all var(--transition-fast);
}
.post-tags__chip::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
}
@media (hover: hover) {
    .post-tags__chip:hover {
        border-color: var(--color-accent);
        color: var(--color-accent);
        transform: translateY(-1px);
    }
}

/* ════════════════════════════════════════════════════════════
   11. AUTHOR CARD (end of single post)
   DOMINANT MOMENT: large circular portrait flanked by stacked
   meta + dual CTAs on a cream-tinted card with shadow elevation.
   ════════════════════════════════════════════════════════════ */
.post-author-card {
    padding-block: clamp(3rem, 2rem + 3vw, 5rem);
}
.post-author-card__inner {
    display: grid; grid-template-columns: 1fr;
    gap: clamp(1.5rem, 1rem + 2vw, 2.5rem);
    align-items: center;
    max-width: 920px; margin: 0 auto;
    padding: clamp(1.5rem, 1rem + 2vw, 3rem);
    background: var(--color-bg-elevated);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-md);
}
.post-author-card__photo {
    display: block;
    width: clamp(120px, 25vw, 200px);
    aspect-ratio: 1;
    border-radius: var(--radius-full);
    overflow: hidden;
    margin: 0 auto;
    background: var(--color-bg-alt);
}
.post-author-card__photo img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: center;
    transition: transform var(--transition-base);
}
@media (hover: hover) {
    .post-author-card__photo:hover img { transform: scale(1.03); }
}
.post-author-card__photo--placeholder {
    display: grid; place-items: center;
    color: var(--color-muted); opacity: 0.5;
}
.post-author-card__body { text-align: center; }
.post-author-card__eyebrow { margin-bottom: 0.5rem; }
.post-author-card__name {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -0.02em;
    margin: 0 0 0.25rem;
    color: var(--color-heading);
    text-wrap: balance;
}
/* Author name links to the bio. 238x29 at 320 - wide enough, 15px short on
   height. Nearest targets are the portrait 54px above and the CTA 221px below,
   so a centred 44px zone clears both.
   The anchor stays display:inline deliberately: inline-block would stop a long
   name breaking across lines. The trade-off is that if a name DOES wrap, the
   absolutely positioned zone covers the first line only - still an improvement
   over 29px, never a regression. */
.post-author-card__name a {
    color: inherit; text-decoration: none;
    --hit-expander: 1;
    position: relative;
}
.post-author-card__name a::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
}
@media (hover: hover) {
    .post-author-card__name a:hover { color: var(--color-accent); }
}
.post-author-card__role {
    margin: 0 0 var(--space-md);
    color: var(--color-muted);
    font-size: var(--text-sm);
}
.post-author-card__bio {
    margin-bottom: var(--space-lg);
    color: var(--color-body);
    font-size: var(--text-base);
    line-height: 1.65;
    max-width: 56ch; margin-left: auto; margin-right: auto;
}
.post-author-card__bio p:last-child { margin-bottom: 0; }
/* Two-tier action cluster: primary booking CTA owns the row, the two
   informational links sit below as a separator-joined text pair. Solves
   the prior layout where text-link + button + text-link read as three
   competing actions of unequal weight. */
.post-author-card__actions {
    display: flex; flex-direction: column;
    align-items: center;
    gap: var(--space-md);
}
.post-author-card__cta {
    align-self: center;
}
.post-author-card__links {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    /* Row gap raised from 0.4rem to give the wrapped 320px rows a >=44px pitch
       (20.72px link + 24px = 44.72px), so the two 44px ::after zones below tile
       instead of overlapping. Measured on staging: zones overlapped by 16.89px
       before, now clear by 0.72px.
       The earlier note here read the failed experiment correctly but drew the
       wrong conclusion. Raising the gap by INJECTION really does nothing - not
       because a more specific rule owns the declaration (enumerating every
       matching rule finds only this one, unprefixed and not !important) but
       because this stylesheet is <link>ed from inside <main>, so it sits AFTER
       <head> in document order. A head-injected rule of equal specificity loses
       that tie; only !important wins. Nothing outranks the rule itself, so
       editing its value here - which is what this is - takes effect normally.
       Beware when testing any inspiration.css value from devtools or a script:
       injected overrides need !important to be believed. */
    column-gap: 0.85rem;
    row-gap: 24px;
    margin: 0;
    font-size: var(--text-sm);
}
.post-author-card__link {
    /* Now flagged. The blocker described here previously - "raising the row gap
       could not be verified" - was a document-order effect that only defeated
       INJECTED overrides, not a source edit; see the note on
       .post-author-card__links above. With row-gap: 24px the 320px wrapped pitch
       is 44.72px, so the two 44px ::after zones below clear each other by 0.72px
       instead of overlapping by 16.89px as they did at the old 27.1px pitch.
       The flag is honest now: at 390/768 the links share one row (no wrap, no
       neighbour), and at 320 the zones no longer collide. */
    --hit-expander: 1;
    position: relative;
    display: inline-flex; align-items: center; gap: 0.35rem;
    color: var(--color-muted);
    font-weight: 500;
    text-decoration: none;
    transition: color var(--transition-fast);
}
/* Invisible vertical hit-expander -> 44px tap target; link text stays compact */
.post-author-card__link::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
}
.post-author-card__link .ph-icon {
    color: var(--color-border-hover);
    transition: transform var(--transition-base), color var(--transition-base);
}
@media (hover: hover) {
    .post-author-card__link:hover { color: var(--color-heading); }
    .post-author-card__link:hover .ph-icon {
        transform: translateX(3px);
        color: var(--color-accent);
    }
}
.post-author-card__link-sep {
    color: var(--color-border-hover);
    user-select: none;
    font-weight: 300;
}

@media (min-width: 720px) {
    .post-author-card__actions {
        align-items: flex-start;
    }
    .post-author-card__cta {
        align-self: flex-start;
    }
    .post-author-card__links {
        justify-content: flex-start;
    }
}

@media (min-width: 720px) {
    .post-author-card__inner {
        grid-template-columns: auto 1fr;
        text-align: left;
    }
    .post-author-card__body { text-align: left; }
    .post-author-card__bio { margin-left: 0; margin-right: 0; }
    .post-author-card__photo { margin: 0; }
}

/* ════════════════════════════════════════════════════════════
   12. RELATED POSTS  (single post bottom)
   ════════════════════════════════════════════════════════════ */
.post-related {
    padding-block: clamp(3rem, 2rem + 3vw, 5rem);
    background: var(--color-bg);
}
.post-related__header {
    text-align: center;
    margin-bottom: clamp(2rem, 1.5rem + 2vw, 3rem);
}
.post-related__heading {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.02em;
    margin: var(--space-md) 0 0;
    color: var(--color-heading);
    text-wrap: balance;
}
.post-related__heading em {
    font-style: italic;
    font-weight: inherit;
    color: var(--color-rose-deep);
}
.post-related__cards {
    list-style: none; padding: 0; margin: 0;
    display: grid; grid-template-columns: 1fr;
    gap: clamp(1.5rem, 1rem + 2vw, 2.5rem);
}
@media (min-width: 720px) {
    .post-related__cards { grid-template-columns: repeat(3, 1fr); align-items: start; }
}
/* Editorial raised/lowered stagger, matching the hub grid (playbook item 2 -
   apply the offset rhythm consistently). Related is a capped set of 3 uniform
   .insp-card tiles (clamped excerpt + fixed media) in a plain 3-col grid with NO
   lead, so nth-child(even) = the middle card takes the lower offset for a centred
   magazine cadence. Uses margin-block-start (NOT translateY) because .insp-card's
   `transform` is owned by the scroll-reveal - same mechanism the hub stagger uses.
   Needs align-items:start (above) to offset within the track. Desktop 3-col only;
   reduced-motion opts out. */
@media (prefers-reduced-motion: no-preference) {
    @media (min-width: 720px) {
        .post-related__cards .insp-card:nth-child(even) {
            margin-block-start: var(--space-2xl);
        }
    }
}
/* Related grid uses adaptive aspect-ratio per cover orientation, but unlike
   the index grid each card stays in its own 1-of-3 column - no full-row
   editorial span (would break the 3-up layout). Portrait covers get a
   tall 3:4 crop within the column; landscape stays at the 3:2 default. */
@media (min-width: 980px) {
    .post-related__cards .insp-card--portrait {
        grid-column: auto;
        display: flex;
        flex-direction: column;
    }
    .post-related__cards .insp-card--portrait > .insp-card__media {
        aspect-ratio: 3 / 4;
        grid-column: auto;
        grid-row: auto;
        height: auto;
    }
    .post-related__cards .insp-card--portrait > .insp-card__body {
        grid-column: auto;
        grid-row: auto;
        padding: var(--space-lg);
        gap: var(--space-sm);
    }
    .post-related__cards .insp-card--portrait .insp-card__title {
        font-size: var(--text-xl);
        line-height: 1.15;
        letter-spacing: -0.01em;
        max-width: none;
    }
    .post-related__cards .insp-card--portrait .insp-card__excerpt {
        font-size: var(--text-sm);
        line-height: 1.55;
        -webkit-line-clamp: 3;
        max-width: none;
    }
}

/* ════════════════════════════════════════════════════════════
   13. PREV / NEXT NAV
   ════════════════════════════════════════════════════════════ */
.post-prevnext {
    padding-block: clamp(2rem, 1.5rem + 2vw, 3rem);
}
.post-prevnext__inner {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--space-md);
}
.post-prevnext__link {
    /* ~32px tall. Prev and next are COLUMNS of a `1fr auto 1fr` grid, not
       stacked rows, so a 44px zone cannot collide with the other one - the
       "row pitch" my sweep reported here was a baseline offset between two
       side-by-side items, which the metric misreads. Nearest reachable
       interactive neighbour above/below is 24px away, clear of the 6px the
       zone adds. */
    --hit-expander: 1;
    position: relative;
    display: inline-flex; align-items: center; gap: 0.75rem;
    color: var(--color-body);
    text-decoration: none;
    transition: color var(--transition-base);
    /* Cap the text width so both sides wrap consistently at long titles
       rather than one going single-line wide and the other stacking to two. */
    max-width: min(32ch, 100%);
}
.post-prevnext__link::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
}
.post-prevnext__link > span {
    display: flex; flex-direction: column; line-height: 1.2;
    min-width: 0;
    flex: 1;
}
.post-prevnext__label {
    font-size: var(--text-2xs);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-muted);
}
.post-prevnext__link strong {
    font-family: var(--font-display);
    font-size: var(--text-base);
    color: var(--color-heading);
    font-weight: 600;
    text-wrap: balance;
    /* clamp long titles to 2 lines */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.post-prevnext__link--prev { justify-self: start; }
.post-prevnext__link--next { justify-self: end; text-align: right; }
.post-prevnext__link--next span { align-items: flex-end; }
.post-prevnext__spacer { display: block; }

@media (hover: hover) {
    .post-prevnext__link:hover strong { color: var(--color-accent); }
    .post-prevnext__link--prev:hover .ph-icon { transform: translateX(-3px); }
    .post-prevnext__link--next:hover .ph-icon { transform: translateX(3px); }
}
.post-prevnext__link .ph-icon {
    color: var(--color-muted);
    transition: transform var(--transition-base);
}

.post-prevnext__home {
    width: 44px; height: 44px;
    display: inline-grid; place-items: center;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    color: var(--color-body);
    background: var(--color-bg);
    transition: all var(--transition-base);
}
@media (hover: hover) {
    .post-prevnext__home:hover {
        border-color: var(--color-accent);
        color: var(--color-accent);
        transform: translateY(-2px);
    }
}

@media (max-width: 559px) {
    .post-prevnext__inner { grid-template-columns: 1fr; gap: var(--space-lg); justify-items: center; }
    .post-prevnext__link--prev,
    .post-prevnext__link--next { justify-self: center; }
    .post-prevnext__link--next { text-align: center; }
    /* Stranded by the re-centring above: the span keeps align-items: flex-end from the
       desktop right-aligned card (:2063), which pinned the shrink-wrapped "NEXT" eyebrow
       to the card's right edge while its own title centred underneath - 126px apart. */
    .post-prevnext__link--next span { align-items: center; }
    /* The spacer exists to balance the desktop 1fr auto 1fr row. In one column it is a
       zero-height track that still consumes a full gap, making the band 24px taller than
       its contents on the two posts that render it (no prev, or no next). */
    .post-prevnext__spacer { display: none; }
}

/* ════════════════════════════════════════════════════════════
   14. PAGE-LOAD ENTRY ANIMATIONS  (reduced-motion safe)
   Tier 1 - hero copy fade-up, featured + grid cards subtle stagger.
   ════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference) {
    .insp-hero__title,
    .insp-hero__lead,
    .insp-hero__meta,
    .cat-hero__title,
    .cat-hero__lead,
    .author-hero__title,
    .author-hero__bio,
    .post-hero__title,
    .post-hero__excerpt,
    .post-hero__byline {
        animation: insp-fade-up 700ms cubic-bezier(0.16, 1, 0.3, 1) both;
    }
    .insp-hero__lead { animation-delay: 80ms; }
    .insp-hero__meta { animation-delay: 160ms; }
    .cat-hero__lead,
    .author-hero__bio,
    .post-hero__excerpt { animation-delay: 80ms; }
    .post-hero__byline { animation-delay: 160ms; }

    .insp-featured__card {
        animation: insp-fade-up 800ms cubic-bezier(0.16, 1, 0.3, 1) both;
        animation-delay: 100ms;
    }

    .insp-card {
        animation: insp-fade-up 600ms cubic-bezier(0.16, 1, 0.3, 1) both;
        animation-delay: calc(var(--card-index, 0) * 60ms);
    }
}
@keyframes insp-fade-up {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ════════════════════════════════════════════════════════════
   14b. SECTION HANDOFFS  (author-hero → grid breathing room)
   The "Posts by [author]" + back-link header was sitting flush
   against the hero. Lift it off with extra top padding when the
   grid follows the author hero directly. No hairline divider -
   the cream section break already provides the seam.
   ════════════════════════════════════════════════════════════ */
.author-hero + .insp-grid {
    padding-block-start: clamp(2.5rem, 1.5rem + 3vw, 4.5rem);
}

/* ════════════════════════════════════════════════════════════
   14c. CATEGORY "ABOUT THIS TOPIC" DISCLOSURE
   Long body copy that used to live in the hero now collapses into
   a compact disclosure block between the grid and the closing CTA.
   Keeps SEO content on the page without burying the post cards.
   DOMINANT MOMENT: muted summary chip that opens into a calmly
   formatted prose well using the existing post-body typography.
   ════════════════════════════════════════════════════════════ */
.cat-about {
    padding-block: clamp(2rem, 1.5rem + 2vw, 3.5rem);
    background: var(--color-bg);
}
.cat-about__details {
    max-width: 68ch;
    margin: 0 auto;
    background: var(--color-bg-elevated);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}
.cat-about__summary {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-md);
    padding: var(--space-md) var(--space-lg);
    cursor: pointer;
    list-style: none;
    color: var(--color-heading);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    transition: background var(--transition-base);
}
.cat-about__summary::-webkit-details-marker { display: none; }
.cat-about__summary-icon {
    display: inline-flex; align-items: center;
    color: var(--color-muted);
    transition: transform var(--transition-base), color var(--transition-base);
}
.cat-about__details[open] .cat-about__summary-icon {
    transform: rotate(180deg);
    color: var(--color-accent);
}
@media (hover: hover) {
    .cat-about__summary:hover {
        background: color-mix(in srgb, var(--color-accent) 4%, transparent);
    }
    .cat-about__summary:hover .cat-about__summary-icon { color: var(--color-accent); }
}
.cat-about__summary:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: -2px;
}
.cat-about__body {
    padding: 0 var(--space-lg) var(--space-lg);
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.7;
    color: var(--color-body);
}
.cat-about__body > * { margin-block: 0 1em; }
.cat-about__body > *:last-child { margin-bottom: 0; }
.cat-about__body h2,
.cat-about__body h3,
.cat-about__body h4 {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.01em;
    color: var(--color-heading);
    margin-block: 1.5em 0.5em;
    text-wrap: balance;
}
.cat-about__body a {
    color: var(--color-link);
    text-decoration: underline;
    text-underline-offset: 3px;
    transition: color var(--transition-fast);
}
@media (hover: hover) {
    .cat-about__body a:hover { color: var(--color-accent-hover); }
}
@media (prefers-reduced-motion: reduce) {
    .cat-about__summary-icon { transition: none; }
}
/* Disclosure open animation: the body fades + slides in on [open] so the reveal
   reads as designed rather than a bare native details toggle (the caret rotate
   already fires above). Reduced-motion users get an instant reveal. */
@media (prefers-reduced-motion: no-preference) {
    .cat-about__details[open] .cat-about__body {
        animation: cat-about-reveal 0.32s ease both;
    }
}
@keyframes cat-about-reveal {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ════════════════════════════════════════════════════════════
   15. FOCUS RING (consistency across all interactives)
   ════════════════════════════════════════════════════════════ */
.insp-card a:focus-visible,
.insp-featured__media:focus-visible,
.insp-featured__title a:focus-visible,
.insp-featured__cta:focus-visible,
.insp-filter__chip:focus-visible,
.insp-pagination__link:focus-visible,
.post-tags__chip:focus-visible,
.post-author-card__photo:focus-visible,
.post-author-card__link:focus-visible,
.post-author-card__more:focus-visible,
.post-prevnext__link:focus-visible,
.post-prevnext__home:focus-visible,
.post-hero__author:focus-visible,
.post-body a:focus-visible,
.cat-hero__back:focus-visible,
.author-hero__copy a:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}
