/**
 * Shared page chrome (brand background, text color, heading font) for
 * blog surfaces with no dedicated stylesheet of their own -- the index
 * and tag landing pages (#125), the post detail page (#127), plus the
 * index/tag/category post-list layout (#126). Not core/css/brand_button.css
 * (that file is the CTA button component)
 * and not the full marketing/css/landing.css (apex-only hero/nav/footer
 * rules that would need the same bare-element audit BLOG-05 round 2
 * already did once for `footer{}` -- see #125 spec,
 * 2026-09-16-blog-index-tag-page-chrome.md §2).
 *
 * --bg-global/--text-primary are duplicated from landing.css's own
 * :root, same rationale as brand_button.css's header comment:
 * cheaper to keep two copies of two tokens in sync than to make
 * this file depend on landing.css's load order.
 */
:root {
    --bg-global:       #F8F9FA;
    --text-primary:    #2D3436;
    --accent-health:   #74B9FF;
    --accent-beauty:   #FD79A8;
    --accent-spa:      #55E6C1;
    --accent-grooming: #0EA5E9;
    --accent-pro:      #FFD369;
    --accent-hogar:    #A29BFE;
}

body {
    font-family: 'Inter', system-ui, sans-serif;
    background: var(--bg-global);
    color: var(--text-primary);
}

h1, h2, h3, h4 {
    font-family: 'Montserrat', system-ui, sans-serif;
    font-weight: 800;
}

/* Two-band hero (index page only) + post card grid, matching the
   live blogspot.com reference's own inline CSS byte-for-byte where
   the values are structural (sizes, radii, spacing) and reusing this
   repo's own brand tokens where the reference reused them too --
   --brand-primary/--brand-accent/--brand-accent-lt are already in
   scope via the co-loaded site_chrome.css (2026-09-21-blog-index-
   redesign.md §2.3, still true). --text-secondary is NOT co-loaded
   (it lives only in landing.css, apex-only, never loaded here) --
   several rules below need a muted text tone without it (four uses
   as of #132: .blog-post-card-excerpt, .blog-post-card-meta, s, and
   .blog-post-detail-meta), so they reuse #5C6B6D directly, the same
   purpose-built value 2026-09-21-blog-index-redesign.md's own §3.4
   already introduced and contrast-checked (5.56:1 on white, clears
   AA) rather than a second unverified value. The category label also
   does NOT reuse
   the raw --brand-accent token as a text colour (#C5A059 at this
   rule's 10.4px size is 2.46:1 on white, below the 4.5:1 AA minimum)
   -- it reuses #8A6D28, the same accessible gold
   2026-09-21-blog-index-redesign.md's own round 1 review already
   derived for exactly this failure mode (4.89:1 on this white card
   background). The six --accent-* tokens above are the one genuinely
   new addition: the apex's own sector-card palette (landing.css,
   apex-only, never loaded here), copied rather than loading that
   file wholesale -- same rationale as the two colours above. */
.blog-hero {
    position: relative;
    min-height: 45vh;
    background: var(--brand-primary);
    overflow: hidden;
    display: flex;
    align-items: center;
}

.blog-hero-grid {
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(rgba(197, 160, 89, 0.055) 1px, transparent 1px),
        linear-gradient(90deg, rgba(197, 160, 89, 0.055) 1px, transparent 1px);
    background-size: 64px 64px;
}

.blog-hero-blob-a {
    position: absolute;
    width: 400px;
    height: 400px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(197, 160, 89, 0.13) 0%, transparent 68%);
    top: -100px;
    right: -80px;
}

.blog-hero-blob-b {
    position: absolute;
    width: 300px;
    height: 300px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(116, 185, 255, 0.08) 0%, transparent 68%);
    bottom: -80px;
    left: -60px;
}

.blog-hero-inner {
    position: relative;
    z-index: 2;
    text-align: center;
    max-width: 800px;
    margin: 0 auto;
    padding: 3rem 1.5rem;
}

.blog-hero-title {
    color: #fff;
    font-weight: 800;
    font-size: clamp(2rem, 4vw, 3.5rem);
    line-height: 1.1;
    margin-bottom: 1rem;
}

.blog-hero-title span {
    color: var(--brand-accent);
}

.blog-hero-sub {
    color: rgba(255, 255, 255, 0.58);
    font-size: 1.1rem;
    max-width: 500px;
    margin: 0 auto;
    line-height: 1.75;
}

.blog-intro {
    background: var(--brand-accent);
    padding: 2.1rem 0;
}

.blog-intro-inner {
    max-width: 700px;
    margin: 0 auto;
    padding: 0;
    text-align: center;
    font-weight: 600;
    color: var(--brand-primary);
}

@media (max-width: 768px) {
    .blog-intro-inner {
        padding: 0 1.5rem;
    }
}

/* The band has a literal <p> for its one sentence (gh#429); without
   this reset, Bootstrap's `p { margin-bottom: 1rem }` makes the band
   ~16px taller below the text than above (49.59px vs 33.59px, measured
   under #140's implementation review round 1, F1-2). */
.blog-intro-inner p {
    margin-bottom: 0;
    letter-spacing: 0.01em;
}

.blog-post-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 28px;
    margin-bottom: 2.5rem;
}

.blog-post-card {
    background: #fff;
    border-radius: 20px;
    padding: 1.9rem;
    border: 1px solid rgba(0, 0, 0, 0.055);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.04);
    transition: transform 0.35s ease, box-shadow 0.35s ease, border-color 0.35s ease;
    overflow: hidden;
    position: relative;
}

.blog-post-card:hover {
    transform: translateY(-7px);
    box-shadow: 0 18px 36px rgba(0, 0, 0, 0.09);
    border-color: var(--card-color, var(--brand-accent));
}

.blog-post-card:nth-child(6n+1) { --card-color: var(--accent-health); }
.blog-post-card:nth-child(6n+2) { --card-color: var(--accent-beauty); }
.blog-post-card:nth-child(6n+3) { --card-color: var(--accent-spa); }
.blog-post-card:nth-child(6n+4) { --card-color: var(--accent-grooming); }
.blog-post-card:nth-child(6n+5) { --card-color: var(--accent-pro); }
.blog-post-card:nth-child(6n+6) { --card-color: var(--accent-hogar); }

.blog-post-card-image {
    position: relative;
    height: 220px;
    margin: -1.9rem -1.9rem 1.75rem;
    width: calc(100% + 3.8rem);
    background: var(--brand-primary);
    overflow: hidden;
}

.blog-post-card-image a,
.blog-post-card-image picture {
    display: block;
    height: 100%;
}

.blog-post-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s cubic-bezier(0.23, 1, 0.32, 1);
}

.blog-post-card-image::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, transparent 50%, rgba(26, 26, 46, 0.3) 100%);
    pointer-events: none;
}

.blog-post-card:hover .blog-post-card-image img {
    transform: scale(1.05);
}

.blog-post-card-category {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: 'Montserrat', system-ui, sans-serif;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #8A6D28;
    margin-bottom: 0.85rem;
    text-decoration: none;
}

.blog-post-card-category::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #8A6D28;
}

.blog-post-card-title {
    font-size: 1.25rem;
    margin-bottom: 0.75rem;
    line-height: 1.25;
}

.blog-post-card-title a {
    color: var(--brand-primary);
    text-decoration: none;
}

.blog-post-card-excerpt {
    font-size: 0.9rem;
    color: #5C6B6D;
    line-height: 1.7;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-bottom: 1.25rem;
}

.blog-post-card-meta {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid rgba(0, 0, 0, 0.05);
    font-size: 0.78rem;
    color: #5C6B6D;
    margin-bottom: 1rem;
}

.blog-post-card-meta span {
    display: flex;
    align-items: center;
    gap: 6px;
}

.blog-read-more {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--brand-accent);
    color: var(--brand-primary);
    font-family: 'Montserrat', system-ui, sans-serif;
    font-weight: 700;
    font-size: 0.8rem;
    padding: 0.6rem 1.2rem;
    border-radius: 10px;
    text-decoration: none;
    transition: all 0.3s ease;
}

.blog-read-more:hover {
    background: var(--brand-primary);
    color: #fff;
    transform: translateY(-2px);
}

@media (max-width: 768px) {
    .blog-post-grid {
        grid-template-columns: 1fr;
    }
}

/* Post-detail page (#132) -- bounded outer column holding the
   unboxed title/byline/CTA/badges plus the white body card, matching
   the reference's own .single-post (unboxed, 780px, no background)
   wrapping .post-body (the white card, hero image + article body
   only). Separate class from .blog-post-card on purpose -- that
   class's hover transform, nth-child accent-cycling and bleed-out
   image treatment are grid/listing behaviour, dead weight on a
   single static article. */
.blog-post-detail {
    max-width: 780px;
    margin: 0 auto;
}

.blog-post-detail-body {
    background: #fff;
    border-radius: 16px;
    padding: 2rem;
    border: 1px solid rgba(0, 0, 0, 0.05);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04);
    line-height: 1.8;
}

.blog-post-detail-body p {
    margin-bottom: 1.25rem;
}

/* width: 100%, not max-width -- the rendered <img> carries a
   width="400" hint (height is whatever height the image's own aspect
   ratio maps to, e.g. 225 for a 16:9 upload, 210 for the 1200x630
   test fixture) from the smallest configured rendition
   (Picture.__html__ uses self.renditions[0]), mapped as a
   zero-specificity presentational hint. A max-width cap only clamps
   a computed width from above and cannot grow a 400px hint to fill
   this card's ~714px content box; width: 100% is required, height:
   auto then preserves the aspect ratio. Accepted trade-off
   (2026-09-22-blog-post-detail-visual-match.md §3.3): this also
   upscales a StreamField body image narrower than the card's ~714px
   content width, since Wagtail's width-N filters never upscale --
   deliberate, favouring "every image fills the card" like the
   reference over pixel-perfect fidelity for an undersized upload. */
.blog-post-detail-body img {
    width: 100%;
    height: auto;
    border-radius: 12px;
    margin: 1.5rem 0;
}

/* Icon-led byline for the post-detail page, values from the
   reference's own .post-meta-info -- a new class, not
   .blog-post-card-meta, which is a card-footer style (border-top,
   tighter 0.78rem text) that would draw an unwanted rule between the
   <h1> and the byline here. Sits on the page's --bg-global (#F8F9FA),
   outside .blog-post-detail-body -- #5C6B6D on #F8F9FA is 5.27:1,
   clearing AA. */
.blog-post-detail-meta {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
    font-size: 0.875rem;
    color: #5C6B6D;
    margin-bottom: 2rem;
}

.blog-post-detail-meta span {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Post-detail tags (#131) -- lighter, subordinate pill next to the
   reused .blog-post-card-category above (no new CSS needed for the
   category itself -- the class already produces the gold/uppercase/
   dot-bullet treatment used on the listing cards, and its own text sits
   on bare #F8F9FA at 4.63:1, unaffected by this rule). Unlike the
   category, this pill's text sits over its own tinted fill, not bare
   #F8F9FA -- #8A6D28 composited over rgba(138, 109, 40, 0.06)/0.14 only
   reaches 4.31:1/3.89:1, both below the 4.5:1 AA minimum for this
   0.75rem/500 (normal, not large) text (review round 1, F-1). #7A6023
   is the same hue darkened enough to pass against both fills --
   5.25:1 at rest, 4.75:1 on hover/focus. */
.blog-post-detail-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
}

.blog-post-detail-tag {
    display: inline-flex;
    align-items: center;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 0.75rem;
    font-weight: 500;
    color: #7A6023;
    border: 1px solid rgba(138, 109, 40, 0.35);
    border-radius: 999px;
    padding: 0.25rem 0.75rem;
    text-decoration: none;
    background: rgba(138, 109, 40, 0.06);
}

.blog-post-detail-tag:hover,
.blog-post-detail-tag:focus-visible {
    background: rgba(138, 109, 40, 0.14);
}

/* Mid-article CTA panel (#133) -- navy break-out card, chosen over a
   gold-tinted centered card and a white-card-with-accent-stripe
   after a local mockup comparison against these same tokens
   (2026-09-27-gh133-blog-cta-panel-redesign.md Sec.2). var(--brand-
   primary)/var(--brand-accent-lt) are declared on :root by both
   brand_button.css and site_chrome.css, both loaded before this file
   on blog_page.html -- same precedent as .blog-hero above, no
   redeclaration needed here. */
.blog-post-cta {
    margin-top: 2.5rem;
    background: var(--brand-primary);
    border-radius: 16px;
    padding: 2.25rem 2rem;
    display: flex;
    align-items: center;
    gap: 1.5rem;
}

/* #d4b577 (--brand-accent-lt) on this tile's own rgba(197,160,89,
   0.16) fill -- which composites to #352f35 over the card's navy,
   not bare #1A1A2E -- is 6.63:1, clearing the 3:1 WCAG 1.4.11
   non-text minimum for the icon glyph with room to spare. */
.blog-post-cta-icon {
    flex-shrink: 0;
    width: 56px;
    height: 56px;
    border-radius: 14px;
    background: rgba(197, 160, 89, 0.16);
    color: var(--brand-accent-lt);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
}

.blog-post-cta-copy {
    flex: 1;
}

.blog-post-cta-heading {
    font-family: 'Montserrat', system-ui, sans-serif;
    font-weight: 800;
    font-size: 1.15rem;
    margin: 0 0 0.35rem;
    color: #fff;
}

/* rgba(255,255,255,0.72) composited on #1A1A2E renders as
   ~rgb(191,191,196) -- 9.31:1 against the same navy, clearing AA for
   this 0.9rem/400 text with room to spare. */
.blog-post-cta-subtext {
    margin: 0;
    font-size: 0.9rem;
    color: rgba(255, 255, 255, 0.72);
}

/* Stacks below Bootstrap's own md edge (768px, matching the existing
   `@media (max-width: 768px)` at :302 in this file), not a narrower
   620px -- round 1 review (F-1) found the inline layout squeezes
   between 621px and 767px: Bootstrap's vendored .container caps at
   540px starting at the 576px breakpoint, and after the card's 2rem
   padding, the 56px icon, two 1.5rem gaps and the button's own
   ~280-290px footprint, the copy column was left with as little as
   ~60px in that band -- exactly the tablet/landscape-phone range the
   original 620px breakpoint did not cover. */
@media (max-width: 768px) {
    .blog-post-cta {
        flex-direction: column;
        text-align: center;
    }

    .blog-post-cta .btn-primary-gold {
        width: 100%;
        justify-content: center;
    }
}

/* Rich text inline elements (BLOG-06). Three HTML elements land on
   the public blog post page from the widened `paragraph`
   RichTextBlock features list -- inline code, blockquote (plain),
   and strikethrough -- and were never styled by `page_chrome.css` or
   `landing.css`. Bare selectors were an explicit choice only after a
   bare-element audit (spec review round 2, F2-3): the `code` and `s`
   selectors are collision-free across the four templates that load
   this stylesheet (`blog_page.html`, `blog_index_page.html`,
   `tag_page.html`, `category_page.html`) plus the shared partials
   and `marketing/base.html`. The `blockquote` selector is scoped
   with `:not(.blockquote)` because `blog_page.html:65` renders the
   distinct `quote` StructBlock as `<blockquote class="blockquote">`,
   which must keep its own Bootstrap-derived styling plus
   `.blockquote-footer`. The CSS here covers the rich-text blockquote
   only -- short un-attributed quotes entered directly from the
   toolbar; the `quote` StructBlock remains the canonical route for
   styled callouts with attribution (spec review round 3, F3-1). */

/* Rich text inline code -- backtick-wrapped text from the toolbar
   `</>` button. Distinct background + border is what actually
   separates it from the page; relying on monospace + colour alone
   is the failure mode #127's own implementation review already caught
   once. Since #132, the post body renders on `.blog-post-detail-body`'s
   own `#FFFFFF`, not the page's --bg-global #F8F9FA -- the 1.18:1
   contrast between #ECECEC and #FFFFFF is intentional -- the chip's
   1px border (#D0D0D0) is the visible edge (1.54:1 on the same
   background). The chip's #C0392B text on #ECECEC is 4.6:1, clearing
   AA at font-size 0.875em (unaffected by the background change). */
code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.875em;
    background: #ECECEC;
    padding: 0.1em 0.3em;
    border-radius: 3px;
    border: 1px solid #D0D0D0;
    color: #C0392B;
}

/* Rich text blockquote -- short quotes without attribution. Spares
   `blog_page.html:65`'s `<blockquote class="blockquote">` (the
   `quote` StructBlock, with `.blockquote-footer` attribution). Since
   #132, the post body renders on `.blog-post-detail-body`'s own
   `#FFFFFF`, not the page's --bg-global #F8F9FA -- text colour #555
   reads at 7.46:1 against #FFFFFF, clearing AA. */
blockquote:not(.blockquote) {
    border-left: 4px solid var(--brand-accent);
    margin: 1.5rem 0;
    padding: 0.5rem 1rem;
    color: #555;
}

/* Strikethrough -- no rule for the literal <s> would have left it
   indistinguishable from body text; #5C6B6D is the muted text tone
   already used by `.blog-post-card-excerpt` and `.blog-post-card-meta`
   (review round 1 MINOR-1: an earlier draft introduced #636E72 here
   and mis-attributed the contrast to .blog-post-card-excerpt's hex,
   which is actually #5C6B6D -- switched), so the visual hierarchy is
   consistent rather than introducing a fourth colour. Since #132,
   `<s>` renders inside the post body, on `.blog-post-detail-body`'s
   own `#FFFFFF` rather than the page's --bg-global #F8F9FA -- 5.56:1
   on #FFFFFF, clears AA. This is the byte-identical hex `.blog-post-
   detail-meta` (2026-09-22-blog-post-detail-visual-match.md §3.2)
   also uses for its own, separate, #F8F9FA byline -- that one is
   5.27:1, also AA -- the same colour has two
   different correct ratios recorded in this file depending on which
   element uses it; do not conflate them. */
s {
    color: #5C6B6D;
}

/* Blog breadcrumb (#134): recolors Bootstrap's stock .breadcrumb with the
   brand tokens already loaded via site_chrome.css on every blog template
   -- navy link text, the accessible #8A6D28 gold already used for
   .blog-post-card-category above (that class's own header comment
   derived #8A6D28 because raw --brand-accent measures 2.46:1 on a white
   card, below the 4.5:1 AA minimum for text -- a contrast ratio does not
   depend on font size, only the AA pass/fail threshold does) for the
   active crumb and link hover. This breadcrumb sits on a different
   background -- body's own #F8F9FA, not a white card -- where #8A6D28 is
   4.63:1 (still passes AA) and raw --brand-accent would be 2.33:1 (still
   fails); --brand-accent is therefore reused only as a *decorative* "›"
   divider glyph, never a text color, so the AA text threshold doesn't
   apply to it at all. Wins against Bootstrap's own same-specificity
   rules by load order alone (marketing/base.html:10-12, same precedent
   as site_chrome.css's .navbar, docs/implemented/
   2026-09-16-blog-shared-site-chrome.md F-1) -- no !important needed.
   Chosen over two rejected mockup alternatives (uppercase Montserrat +
   dot bullets; a navy pill bar) -- 2026-09-24-blog-breadcrumb-
   redesign.md §4. */
.breadcrumb-item + .breadcrumb-item::before {
    content: "\203A";
    color: var(--brand-accent);
    font-weight: 700;
}

.breadcrumb-item a {
    color: var(--brand-primary);
    text-decoration: none;
    font-weight: 500;
}

.breadcrumb-item a:hover,
.breadcrumb-item a:focus-visible {
    color: #8A6D28;
}

.breadcrumb-item.active {
    color: #8A6D28;
    font-weight: 600;
}

/* Fix for #134's mobile-first check: Bootstrap's .breadcrumb is
   `display: flex; flex-wrap: wrap` by default, so a long post title
   wraps the active crumb to a second line whenever the row doesn't fit,
   with the gold divider floating awkwardly at the start of the wrapped
   line. A fixed max-width on the active item alone does not fix this:
   `inline-block`/`vertical-align` have no effect on a flex child, so the
   browser still wraps before any shrinking takes effect. Scoping the fix
   to a mobile-only media query is also not enough: the site's actual
   production post title still wraps between the sm and md breakpoints.
   Fix: apply these three rules unconditionally, with no media query --
   keep the row on one line (`flex-wrap: nowrap`), pin the non-active
   items to their natural width (`flex-shrink: 0` + `white-space: nowrap`
   -- without this, "Blog" itself wraps inside its own <li> once the row
   is squeezed), and let only the active item shrink and ellipsise.
   Verified a true no-op wherever the row already fits on one line. The
   full title is never actually lost on
   blog_page.html/tag_page.html/category_page.html -- it repeats
   verbatim in the <h1> immediately below; blog_index_page.html's active
   crumb is the fixed literal "Blog", short enough that this rule is
   inert there in practice. */
.breadcrumb {
    flex-wrap: nowrap;
}

.breadcrumb-item {
    flex-shrink: 0;
    white-space: nowrap;
}

.breadcrumb-item.active {
    flex-shrink: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
