/* =============================================
   PLUNGE, A PLUMBING CO. — Blog
   For the generated pages in docs/blog/ (index + per-post).
   Extends styles.css and city.css — load those FIRST.
   Reuses the site's design language: Courier New, orange accents,
   dark-blue cards on the dark-grey background.
   ============================================= */


/* ---- Blog hero (title + intro) ---- */
.blog-hero {
    background: var(--bg-dark);
    color: var(--white);
    padding: var(--space-xl) 0 var(--space-lg);
}

.blog-hero-title {
    font-family: var(--font-heading);
    font-size: clamp(2.2rem, 6vw, 3.8rem);
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -1px;
    color: var(--white);
    margin: 0.4rem 0 var(--space-md);
}

.blog-intro {
    font-size: 1.05rem;
    line-height: 1.75;
    color: rgba(255, 255, 255, 0.85);
    max-width: 720px;
}
.blog-intro em {
    color: rgba(255, 255, 255, 0.55);
    font-style: italic;
}
/* Inline link in the intro (the Dino Diaries invitation) — orange on the dark
   background, white on hover, the same treatment inline links get on the legal
   pages. The site-wide default is --blue, which all but disappears here. */
.blog-intro a {
    color: var(--orange);
    text-decoration: underline;
    text-underline-offset: 0.2em;
}
.blog-intro a:hover {
    color: var(--white);
}

/* Hero layout: text on the left, video on the right. Collapses to a single
   stacked column on narrower screens (video drops below the text). */
.blog-hero-grid {
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    gap: var(--space-lg);
    align-items: center;
}
.blog-hero-text {
    min-width: 0;
}
/* The video (placeholder or real embed) fills its column here — override the
   city-page cap/spacing so it sits flush beside the header text. */
.blog-hero-media .video-placeholder,
.blog-hero-media .video-embed {
    max-width: none;
    margin-bottom: 0;
}
@media (max-width: 820px) {
    .blog-hero-grid {
        grid-template-columns: 1fr;
        gap: var(--space-md);
    }
}


/* ---- Post list ---- */
.blog-list-section {
    background: var(--bg-dark);
    padding: 0 0 var(--space-xl);
}

/* Label above the newest-posts row (owner request, July 28 2026) — it names
   what the cards are, so the page doesn't fall from the intro straight into
   untitled cards. Deliberately NOT improvised: this is the same treatment the
   service pages give a section heading on a dark background (.svc-h2 in
   service.css, which doesn't load here) — heading face, white, centered. */
.blog-list-title {
    font-family: var(--font-heading);
    font-size: clamp(1.4rem, 3vw, 2rem);
    font-weight: 800;
    color: var(--white);
    /* Left-justified on every screen (owner request, July 28 2026).
       max-width MATCHES .blog-list below (1040px, centered): the container is
       1180px, so a plain text-align:left would hang the title ~70px left of
       the cards it labels on a wide screen. Sharing the grid's width and
       centering keeps the title's first letter flush with the first card's
       left edge at every size. Change one of these widths, change both. */
    text-align: left;
    max-width: 1040px;
    margin: 0 auto var(--space-md);
}

/* Two-wide grid, centered. Cards flow in source order (posts are emitted
   newest-first), so the grid fills left-to-right then down: newest top-left,
   next to its right, then the following pair on the row below, and so on.
   Collapses to a single column on narrow screens. */
.blog-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-md);
    max-width: 1040px;
    margin: 0 auto;
}
@media (max-width: 700px) {
    .blog-list {
        grid-template-columns: 1fr;
        max-width: 640px;
    }
}

/* One card per post — mirrors the review/service cards (dark-blue with an
   orange top + left accent bar) so it feels native to the rest of the site. */
.blog-card {
    background: var(--blue-dark);
    border-radius: var(--radius-lg);
    border-top: 4px solid var(--orange);
    border-left: 4px solid var(--orange);
    box-shadow: var(--shadow-sm);
    transition: var(--ease);
}
.blog-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
}

/* Whole card is clickable */
.blog-card-link {
    display: block;
    padding: var(--space-md);
    color: inherit;
    text-decoration: none;
}

.blog-card-date {
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--orange);
    margin: 0 0 0.4rem;
}
/* The post's category, on the same line as the date — slightly dimmed so the
   line still scans date-first. */
.blog-card-cat {
    color: rgba(255, 255, 255, 0.6);
}

.blog-card-title {
    font-family: var(--font-heading);
    font-size: 1.35rem;
    font-weight: 800;
    line-height: 1.25;
    color: var(--white);
    margin: 0 0 0.5rem;
    transition: color 0.2s ease;
}
.blog-card:hover .blog-card-title {
    color: var(--orange);
}

.blog-card-excerpt {
    font-size: 0.95rem;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.82);
    margin: 0 0 0.75rem;
}

.blog-card-more {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--orange);
}
.blog-card-more .fa {
    font-size: 0.8rem;
    transition: transform 0.2s ease;
}
.blog-card:hover .blog-card-more .fa {
    transform: translateX(3px);
}

/* The landing page's permanent 4th card: "View All Blog Posts". Same card
   chrome as the post cards (background, accent bars, hover lift), but the
   content is centered and button-like — big book-and-pen icon, title, and
   the live post count (all filled in by generate.py). */
.blog-card--viewall {
    display: flex; /* lets the link stretch to the full card height */
}
.blog-card--viewall .blog-card-link {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 0.35rem;
}
.blog-card--viewall .blog-archive-icon {
    width: 46px;
    height: 46px;
    color: var(--orange);
    margin-bottom: 0.4rem;
}


/* ---- All-posts archive page (docs/blog/all-posts.html) ----
   EVERY category from blog-categories.json (which follows the services
   list — see that file's _notes) gets a block: heading + its posts, or a
   "Stay tuned for more!" line while the category has none. The blocks sit
   three across, echoing the city pages' 3-column services checklist; the
   rows keep that checklist's separator lines and hover-orange links, with
   the book-and-pen blog icon in place of the ✓ check mark. */
.blog-archive-section {
    background: var(--bg-dark);
    padding: 0 0 var(--space-xl);
}

/* Three category blocks per row (the category grid itself) */
.blog-archive-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-lg) 2.5rem;
    margin-bottom: var(--space-lg);
    /* Blocks DO stretch to their row's tallest (owner request, July 28 2026 —
       the page read busy and cramped). Each block now closes with a divider
       line, and stretching is what lets those lines land on one level across
       a row instead of stepping up and down with each block's post count.
       Nothing moves visually: a block's contents still start at its top. */
    align-items: stretch;
}

/* Divider closing each category block — the line the owner asked for between
   a block's "View All" and the next category. On phones (one column) it's
   literally that. On the wider grid it's the bottom edge of each block, and
   because the blocks stretch, the lines read as one rule across the row.
   Weight matters here: at 0.1 alpha it would be the same line the post rows
   already draw between themselves, so category boundaries would carry no
   more weight than post boundaries — which is exactly what made the page
   feel undifferentiated. This sits brighter, on purpose. */
.blog-archive-group {
    padding-bottom: var(--space-md);
    border-bottom: 1px solid rgba(255, 255, 255, 0.22);
}

/* …and the block's LAST post row drops its own hairline, so a block ends in
   one line instead of two stacked a few pixels apart. Scoped to the archive
   grid: on the by-date and category pages the list's closing line is still
   wanted, since nothing else there marks the end. */
.blog-archive-group .blog-archive-list li:last-child,
.blog-archive-group .blog-archive-empty {
    border-bottom: none;
}

/* Category heading above each block's list */
.blog-archive-cat {
    font-family: var(--font-heading);
    /* Nudged up from 1.15rem (owner request, July 28 2026) so the category
       reads as the block's title rather than as another row. The ceiling is
       the longest name — "Water Quality & Softening" — against the narrowest
       column it has to live in; at this size it still holds one line both in
       a 348px desktop column and at 375px on a phone. */
    font-size: 1.3rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--orange);
    margin: 0 0 0.5rem;
}

/* Post rows within a block: single column (the block is already 1/3 wide) */
.blog-archive-list {
    list-style: none;
    margin: 0;
}
.blog-archive-list li {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    /* 0.5rem reserved on the RIGHT — see the no-rewrap note below */
    padding: 0.55rem 0.5rem 0.55rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    color: rgba(255, 255, 255, 0.9);
    font-size: 0.95rem;
    transition: var(--ease);
}

/* Hover motion (owner request, July 2026): hovering a post's title slides
   the WHOLE row — book icon, title, and date — 0.5rem right and fades in
   an arrow at the row's end, matching the city pages' service links
   (city.css .services-checklist). The orange title color on hover (below)
   is untouched. :has() needs a modern browser; older ones just keep the
   color change.
   NO-REWRAP RULE (owner request, July 23 2026): the hover doesn't add
   padding, it MOVES the idle right-side padding to the left — the text's
   available width is identical in both states, so titles wrap the same
   way hovered or not. Don't "simplify" the padding swap away.

   MOUSE-ONLY (July 28 2026): the whole hover treatment — the slide AND the
   arrow — is now fenced behind `hover: hover`, so it exists only on devices
   that can actually hover. Two real phone bugs came from it being global:
   (1) the always-reserved arrow space could wrap to a line of its own,
   leaving an EMPTY line between a one-line title and its date (seen on
   "Water Heater Warranties, Decoded"); (2) a tap left the row stuck in the
   shifted, arrow-showing state, because touch browsers keep :hover after a
   tap. Neither can happen now, and a phone loses nothing — there is no
   pointer there to preview a link with. Keep new hover flourishes for these
   rows inside this query. */
@media (hover: hover) {

    .blog-archive-list li:has(a:hover) {
        padding-left: 0.5rem;
        padding-right: 0;
    }
    /* Arrow rides INLINE at the end of the TITLE's last line — snug against
       the final word, above the date line (owner preference, July 23 2026,
       matching the city pages' service links). Space always reserved
       (opacity 0 when idle), so appearing never reflows the title. */
    .blog-archive-list a::after {
        content: "\f061";                     /* fa-arrow-right */
        font-family: "Font Awesome 6 Free";
        font-weight: 900;
        font-size: 0.8em;
        display: inline-block;
        margin-left: 0.45em;
        color: var(--orange);
        opacity: 0;
        transform: translateX(-0.3em);
        transition: var(--ease);
    }
    .blog-archive-list a:hover::after {
        opacity: 1;
        transform: translateX(0);
    }

}

/* Touch devices: with no arrow to slide in, the reserved right-hand strip
   above has nothing to reserve — give the width back to the title. */
@media (hover: none) {
    .blog-archive-list li {
        padding-right: 0;
    }
}
.blog-archive-list .blog-archive-icon {
    color: var(--orange);
    width: 17px;
    height: 17px;
    flex-shrink: 0;
    margin-top: 0.15rem; /* optically aligns the icon with the first text line */
}
.blog-archive-list a {
    color: inherit;
}
/* Same mouse-only fence as the slide and the arrow above (July 28 2026):
   after a tap, a touch browser holds :hover, which left one title glowing
   orange as though it were still under a pointer. Touch gets :active
   instead — the title lights up while the finger is down and lets go when
   the finger does, which is what a tap should feel like. */
@media (hover: hover) {
    .blog-archive-list a:hover {
        color: var(--orange);
    }
}
.blog-archive-list a:active {
    color: var(--orange);
}

/* Categories with no posts yet — replaced automatically by the real list
   the moment a post lands in the category (generate.py). */
.blog-archive-empty {
    padding: 0.55rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    font-size: 0.95rem;
    font-style: italic;
    color: rgba(255, 255, 255, 0.45);
}

/* "View All" link under each archive block — leads to the category's own
   page. Same orange link language as the cards' "Read article" line, with
   the same nudging arrow on hover. */
.blog-archive-viewall {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.6rem;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--orange);
}
.blog-archive-viewall .fa {
    font-size: 0.8rem;
    transition: transform 0.2s ease;
}
.blog-archive-viewall:hover {
    color: var(--white);
}
.blog-archive-viewall:hover .fa {
    transform: translateX(3px);
}

/* The archive's foot-link row: "Back to the blog" hugs the left edge and
   "Every post by date" hugs the right — same distance from each edge, on
   one line. Wraps gracefully if a narrow screen can't fit both. */
.blog-archive-footlinks {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem var(--space-md);
}
.blog-archive-footlinks .blog-back {
    margin-bottom: 0; /* the row aligns the pair; no extra offset */
}
.blog-archive-footlinks .blog-archive-bydate {
    margin-top: 0; /* override the viewall default so both sit level */
}

/* By-date page rows: title with its publish date on a small line beneath */
.blog-bydate-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}
.blog-bydate-date {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--orange);
}

/* Category pages (docs/blog/category-<slug>.html) and the by-date page: the
   full post list runs three columns wide — the checklist look at full width,
   not boxed into a 1/3-page block like on the archive. Same rows, same
   separators. */
.blog-archive-list--full {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.15rem 1.5rem;
    margin-bottom: var(--space-lg);
}
@media (max-width: 900px) {
    .blog-archive-list--full {
        grid-template-columns: repeat(2, 1fr);
    }
}
@media (max-width: 640px) {
    .blog-archive-list--full {
        grid-template-columns: 1fr;
        gap: 0;
    }
}

/* Same stepped collapse feel as the rest of the site: 3 -> 2 -> 1 columns */
@media (max-width: 900px) {
    .blog-archive-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}
@media (max-width: 640px) {
    .blog-archive-grid {
        grid-template-columns: 1fr;
        gap: var(--space-md);
    }
}


/* ---- Single post page ---- */
.blog-article-section {
    background: var(--bg-dark);
    padding: var(--space-lg) 0 var(--space-xl);
}

/* Text sits on the dark background like the service pages' body copy (no
   heavy card box around long-form reading). Centered with equal margins on
   both sides, and a little wider than before so there's room on the right for
   an optional magazine-style photo column (see .blog-figure below). */
.blog-article {
    max-width: 900px;
    margin: 0 auto;
}

/* BREADCRUMB ON A POST PAGE — flows like a sentence (owner request, July 28
   2026). Everywhere else the trail is a flex row, and each crumb wraps as a
   whole unit, which is right when every crumb is a short word. A post's last
   crumb is its ENTIRE title, so on a phone the flex version shoved the whole
   title down to its own line and then wrapped it again anyway — two dim lines
   pushing the headline off the screen. Plain inline flow instead: the title
   starts right after "Blog /" and breaks mid-title like ordinary prose.
   Flex `gap` doesn't apply here, so the spacing comes from the ordinary
   whitespace between the crumbs in the markup — don't strip it. */
.blog-article .city-breadcrumb {
    display: block;
    line-height: 1.55;
}

.blog-article-title {
    font-family: var(--font-heading);
    font-size: clamp(1.9rem, 5vw, 3rem);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -0.5px;
    color: var(--white);
    margin: 0.4rem 0 0.5rem;
}

.blog-article-meta {
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--orange);
    margin: 0 0 var(--space-md);
}

/* =============================================
   VIDEO POSTS (owner request, 12 August 2026)
   A post can be something to WATCH rather than something to read: the player
   sits above the article body, and on a video-only post the body is empty.
   The player itself is the shared .video-embed from styles.css — this only
   places it and dresses the caption.
   ============================================= */
.blog-article-video {
    margin: 0 0 var(--space-lg);
}
/* The city pages cap the player's width and add space below it; in an article
   it should fill the column and let the caption own the spacing instead. */
.blog-article-video .video-embed,
.blog-article-video .video-placeholder {
    max-width: none;
    margin-bottom: 0;
}
.blog-article-video figcaption {
    margin-top: 0.75rem;
    font-size: 0.95rem;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.72);
    /* Not centred: it reads as a caption rather than a heading, and it lines
       up with the article text that follows on a post that has both. */
    text-align: left;
}


.blog-article-body {
    font-size: 1.05rem;
    line-height: 1.8;
    color: rgba(255, 255, 255, 0.88);
}
.blog-article-body p {
    margin: 0 0 1.1rem;
}
/* Lead paragraph reads a touch larger, like the site's intro leads. Uses
   first-of-type (not first-child) so it still applies when an optional
   .blog-figure precedes the paragraphs in the body. */
.blog-article-body > p:first-of-type {
    font-size: 1.12rem;
    color: var(--white);
}

/* ---- Magazine photo figures ----
   Each photo floats into the body text; figures alternate sides down the
   article (first right, next left, and so on — set by generate.py). The text
   wraps around each one, then runs full-width once it passes the bottom.
   'clear: both' makes every figure start below the previous one, so photos
   cascade down the page and never end up side by side — unless a figure is an
   explicit group (multiple photos), which sit together inside a single float.
   Each .blog-photo-frame is a fixed-ratio box showing a "Picture coming soon"
   placeholder until a real <img> is dropped in (via a post's "photos" list) —
   same box either way, so turning a photo on causes no layout shift. */
.blog-figure {
    clear: both;
    width: 46%;
    max-width: 420px;
    margin-top: 0.35rem;
    margin-bottom: var(--space-md);
    display: flex;
    flex-flow: row wrap; /* a lone photo fills the figure; a group sits side by side */
    gap: var(--space-sm);
}
.blog-figure--right {
    float: right;
    margin-left: var(--space-lg); /* text wraps down the left */
}
.blog-figure--left {
    float: left;
    margin-right: var(--space-lg); /* text wraps down the right */
}
.blog-photo {
    margin: 0;
    flex: 1 1 130px; /* one photo fills the figure; grouped photos share the width */
    min-width: 0;
}
.blog-photo-frame {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    aspect-ratio: 4 / 3;
    background: var(--blue-dark);
    border: 2px dashed rgba(255, 255, 255, 0.3);
    border-radius: var(--radius-lg);
    color: rgba(255, 255, 255, 0.6);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.85rem;
    text-align: center;
    overflow: hidden;
}
.blog-photo-frame .fa {
    font-size: 2.1rem;
    color: rgba(255, 255, 255, 0.45);
}
/* Real photo (once a "src" is supplied) fills the exact same box */
.blog-photo-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: var(--radius-lg);
    display: block;
}
.blog-photo-caption {
    margin-top: 0.4rem;
    font-size: 0.78rem;
    font-style: italic;
    line-height: 1.45;
    color: rgba(255, 255, 255, 0.55);
}

/* On narrow screens a float would crush the text column, so every figure
   drops the float and goes full width, sitting inline between paragraphs. */
@media (max-width: 760px) {
    .blog-figure,
    .blog-figure--left,
    .blog-figure--right {
        float: none;
        width: 100%;
        max-width: none;
        margin: 0 0 var(--space-md);
    }
}

/* ---- Legal pages (privacy.html, terms.html) ----
   These extend the blog article components for long-form legal text.
   .legal-summary uses the site's signature card accent (blue-dark with
   orange top+left edges — same language as .blog-card / the booking
   fallback box). The two "pending" styles mark UNCONFIRMED items from
   the owner's legal draft (today only the after-hours rates in Terms §6);
   generate.py counts them and prints a launch reminder until every one
   is resolved and removed. */
.legal-summary {
    background: var(--blue-dark);
    border-top: 4px solid var(--orange);
    border-left: 4px solid var(--orange);
    box-shadow: var(--shadow-sm);
    border-radius: var(--radius-lg);
    padding: var(--space-md);
    margin: 0 0 var(--space-lg);
    font-size: 1.02rem;
    line-height: 1.75;
    color: rgba(255, 255, 255, 0.92);
}
.legal-summary strong {
    color: var(--white);
}
.legal-summary a,
.legal-body a {
    color: var(--orange);
}
.legal-summary a:hover,
.legal-body a:hover {
    color: var(--white);
}
.legal-body h2 {
    font-family: var(--font-heading);
    font-size: 1.3rem;
    font-weight: 800;
    color: var(--white);
    margin: 1.8rem 0 0.6rem;
}
/* Inline unconfirmed value — impossible to miss during review */
.legal-pending {
    background: rgba(235, 149, 74, 0.18);
    border-bottom: 2px dashed var(--orange);
    padding: 0 0.25em;
    border-radius: 3px;
}
/* Block-level internal reminder for larger open questions */
.legal-pending-note {
    border: 2px dashed var(--orange);
    border-radius: var(--radius-lg);
    padding: 0.7rem 1rem;
    color: var(--orange);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.9rem;
    line-height: 1.6;
}
.legal-pending-note .fa {
    margin-right: 0.35rem;
}

/* Foot of the article: back link + call-to-action buttons */
.blog-article-foot {
    clear: both; /* drop below the floated photo column if the body is short */
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.blog-back {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--orange);
    margin-bottom: var(--space-md);
}
.blog-back:hover {
    color: var(--white);
}


/* =============================================
   LEGAL PAGES ON PHONES (mobile pass, July 27 2026)
   The pages were already sound — no overflow, clean hierarchy, and the
   larger body type is RIGHT for long-form reading, so it stays. This is
   a modest tightening only: slightly closer lines and less air above
   each section heading, which trims a long document without making
   legal text harder to read.
   ============================================= */
@media (max-width: 620px) {

    .legal-body p {
        line-height: 1.7;
    }
    .legal-body h2 {
        font-size: 1.2rem;
        margin: 1.35rem 0 0.45rem;
    }
    .legal-summary {
        padding: var(--space-sm) var(--space-md);
        line-height: 1.65;
    }

}


/* =============================================
   BLOG PAGES ON PHONES (mobile pass, July 28 2026)
   The blog was already structurally sound at 375px — the card grid and the
   archive columns collapse to one column on their own, and nothing
   overflows sideways. So this is spacing work, not layout work: article
   text reads a little tighter, and the blog's front page stops spending a
   whole screen before the first thing you can tap.
   (The two hover bugs this pass also fixed live up in the
   `@media (hover: ...)` blocks above, not here — they were never about
   screen width.)
   ============================================= */
@media (max-width: 620px) {

    /* ---- Article pages ----
       Type SIZE is untouched: these are meant to be read, same call the
       legal pages got. Only the air between lines and paragraphs comes in,
       from 1.8 to 1.68 — on a monospace face at this width, 1.8 reads as
       gappy rather than generous, and it stretched short posts over extra
       screens of scrolling. */
    .blog-article-body {
        line-height: 1.68;
    }
    .blog-article-body p {
        margin-bottom: 0.95rem;
    }
    .blog-article-body h2 {
        font-size: 1.2rem;
        margin: 1.35rem 0 0.45rem;
    }
    /* The trail, the title, and the date line are three different type
       treatments stacked in a row; on a phone they need less air between
       them than on a wide screen, or the post starts below the fold. */
    .blog-article .city-breadcrumb {
        margin-bottom: 0.5rem;
    }
    .blog-article-meta {
        margin-bottom: var(--space-sm);
    }

    /* ---- Blog front page ----
       Goal: the newest post's card peeks above the fold instead of the page
       opening on a full screen of headline, intro, and video box. The
       headline and the video box are left alone — the intro simply reads at
       body size with tighter lines, and the gap between the hero and the
       first card closes up. */
    .blog-hero {
        padding-bottom: var(--space-md);
    }
    .blog-intro {
        font-size: 0.98rem;
        line-height: 1.62;
    }
    .blog-hero-grid {
        gap: var(--space-sm);
    }

    /* ---- Archive, by-date, and category lists ----
       Same idea, smaller dose: these are scan-lists, so they only need
       enough room to separate one row from the next. */
    .blog-archive-list li {
        padding-top: 0.5rem;
        padding-bottom: 0.5rem;
    }

    /* ---- Archive foot links on one line (owner request, July 28 2026) ----
       "Back to the blog" and "Every post by date" wrapped to two lines on a
       phone: 156px + 162px + an 18.75px gap = 337px in 311px of room. The
       row is allowed to wrap (and still is, as a failsafe), but it doesn't
       need to — trimming the gap and stepping both links down one notch
       fits the pair with room to spare, and keeps them level on one line
       down to a 360px screen. Both links get the SAME size here so they
       read as a matched pair; sizes are scoped to this row, so the "Back to
       the blog" link on article pages is untouched. */
    .blog-archive-footlinks {
        column-gap: 0.5rem;
    }
    .blog-archive-footlinks .blog-back,
    .blog-archive-footlinks .blog-archive-bydate {
        font-size: 0.82rem;
    }

}
