/**
 * Blog post body
 *
 * Everything here is a descendant selector on .post-content, the wrapper around
 * {{ post.content|safe }}. That matters: the posts are CKEditor 5 output stored
 * as HTML, so the markup cannot be changed without re-authoring all of them.
 * Styling from outside means this applies retroactively to every existing post
 * and to everything written later, with no migration.
 *
 * CKEditor 5 emits a flat list of top-level elements -- p, h2, h3, ul, ol, and
 * <figure class="table"> / <figure class="image"> wrappers -- which is why the
 * measure below is set with a direct-child selector.
 */

/* ===================================================================
 * Post list rows
 *
 * Used by the blog index, category pages and tag pages. Rules between
 * rows rather than a card each: a stack of bordered boxes gives every
 * post the same weight and turns the titles into a wall of links.
 * =================================================================== */

.post-row {
    display: flex;
    gap: var(--spacing-6);
    padding: var(--spacing-6) 0;
    border-top: 1px solid var(--color-gray-200);
}

.post-row:first-of-type {
    border-top: 0;
    padding-top: 0;
}

.post-row-media {
    flex: 0 0 13rem;
    align-self: flex-start;
    display: block;
    overflow: hidden;
    border-radius: var(--radius-lg);
}

.post-row-media img {
    display: block;
    width: 100%;
    height: 9rem;
    object-fit: cover;
}

.post-row-body {
    flex: 1 1 0;
    min-width: 0;
}

/* Featured posts, three up. Same type as a row, stacked instead of side by
 * side, with a rule above so the group reads as a set. */
.post-feature {
    height: 100%;
    padding-top: var(--spacing-4);
    border-top: 2px solid var(--color-timber);
}

.post-feature-media {
    display: block;
    margin-bottom: var(--spacing-4);
    overflow: hidden;
    border-radius: var(--radius-lg);
}

.post-feature-media img {
    display: block;
    width: 100%;
    height: 10rem;
    object-fit: cover;
}

.post-feature .post-row-title {
    font-size: var(--font-size-lg);
}

.post-row-title {
    font-size: clamp(1.2rem, 2.2vw, 1.5rem);
    margin-bottom: var(--spacing-2);
}

/* Titles read as headings first and links second: ink coloured until you reach
 * for them. A page of green headlines is a page with no hierarchy. */
.post-row-title a {
    color: var(--color-gray-900);
    text-decoration: none;
}

.post-row-title a:hover,
.post-row-title a:focus-visible {
    color: var(--color-primary);
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

.post-row-excerpt {
    max-width: 62ch;
    margin-bottom: var(--spacing-3);
    color: var(--color-gray-700);
}

.post-row-meta {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
    color: var(--color-gray-500);
}

.post-row .section-eyebrow a {
    color: inherit;
    text-decoration: none;
}

.post-row .section-eyebrow a:hover {
    text-decoration: underline;
}

@media (max-width: 575.98px) {
    .post-row {
        flex-direction: column;
        gap: var(--spacing-4);
    }

    .post-row-media {
        flex-basis: auto;
    }
}

/* ===================================================================
 * Table of contents
 *
 * Sits inline above the body rather than in the sidebar: it works at
 * every width without a separate mobile treatment, and on a 7,500-word
 * guide the map belongs where the reader starts.
 * =================================================================== */

.post-toc {
    max-width: 62ch;
    margin: 0 0 2.5em;
    padding: var(--spacing-5) var(--spacing-6);
    background-color: var(--color-frost);
    border-left: 3px solid var(--color-contour);
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
}

.post-toc-title {
    margin: 0 0 var(--spacing-3);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
    font-weight: 600;
    font-stretch: normal;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-contour);
}

/* Numbered because the sections are read in order in a guide, and the count
 * tells the reader how long this is going to be. */
.post-toc-list {
    margin: 0;
    padding-left: 1.4em;
    columns: 2 18rem;
    column-gap: var(--spacing-8);
}

.post-toc-list li {
    margin-bottom: 0.35em;
    break-inside: avoid;
    color: var(--color-gray-500);
}

.post-toc-list a {
    color: var(--color-gray-800);
    text-decoration: none;
    text-underline-offset: 0.15em;
}

.post-toc-list a:hover,
.post-toc-list a:focus-visible {
    color: var(--color-primary);
    text-decoration: underline;
}

/* Bootstrap 5 sets scroll-behavior:smooth on :root (under a
 * prefers-reduced-motion:no-preference guard). On a 28,000px article that makes
 * every TOC jump a multi-second animation, and worse, an on-load fragment
 * navigation gets abandoned partway -- arriving at /post/#section left the page
 * at scrollY 20 instead of the heading. Instant is the right behaviour for
 * long-document anchors, and it is what an inbound deep link needs.
 *
 * Scope: blog.css loads on post pages and the blog/forum index pages. Those
 * index pages have no in-page anchors, so turning smooth scrolling off there is
 * inert; everything outside the blog keeps Bootstrap's default. */
:root {
    scroll-behavior: auto;
}

/* Jumping to a section should not tuck the heading under the sticky navbar,
 * and the target should be obvious once you land on it. */
.post-content h2[id],
.post-content h3[id] {
    scroll-margin-top: var(--spacing-16);
}

.post-content h2[id]:target,
.post-content h3[id]:target {
    animation: toc-target-flash 1.6s ease-out 1;
}

@keyframes toc-target-flash {
    from {
        background-color: rgb(240 75 10 / 0.14);
    }
    to {
        background-color: transparent;
    }
}

@media (prefers-reduced-motion: reduce) {
    .post-content h2[id]:target,
    .post-content h3[id]:target {
        animation: none;
        box-shadow: -0.6em 0 0 rgb(240 75 10 / 0.3);
    }
}

/* ===================================================================
 * Measure and rhythm
 *
 * Body text was running ~90 characters per line at the column's full
 * 736px. Prose gets a comfortable measure; tables and images are
 * exempt and keep the full column, because a rate table needs the room.
 * =================================================================== */

.post-content {
    font-size: 1.0625rem;
    line-height: 1.7;
    color: var(--color-gray-800);
}

/* 62ch, not the ~68 you might reach for: the ch unit is the width of "0", which
 * is narrower than the average lowercase glyph in Public Sans, so this measures
 * out at roughly 72 real characters per line. Verified, not assumed. */
.post-content > * {
    max-width: 62ch;
}

.post-content > figure,
.post-content > table,
.post-content > .table-responsive {
    max-width: none;
}

.post-content p,
.post-content ul,
.post-content ol {
    margin-bottom: 1.35em;
}

/* Bootstrap resets headings to margin-top:0, so 45 headings in a 7,500-word
 * guide did nothing to segment it. */
.post-content h2 {
    margin-top: 2.4em;
    margin-bottom: 0.6em;
    padding-top: 0.7em;
    border-top: 1px solid var(--color-gray-200);
    font-size: clamp(1.6rem, 3vw, 2rem);
}

.post-content h3 {
    margin-top: 1.9em;
    margin-bottom: 0.5em;
    font-size: clamp(1.25rem, 2.2vw, 1.4rem);
}

.post-content h4,
.post-content h5,
.post-content h6 {
    margin-top: 1.6em;
    margin-bottom: 0.4em;
}

.post-content > *:first-child {
    margin-top: 0;
}

.post-content h2:first-child {
    border-top: 0;
    padding-top: 0;
}

.post-content li {
    margin-bottom: 0.4em;
}

.post-content li > ul,
.post-content li > ol {
    margin-top: 0.4em;
}

.post-content a {
    color: var(--color-primary);
    text-underline-offset: 0.15em;
}

.post-content a:hover {
    color: var(--color-primary-dark);
}

.post-content strong,
.post-content b {
    font-weight: var(--font-weight-semibold);
    color: var(--color-gray-900);
}

/* ===================================================================
 * Tables
 *
 * The important one. CKEditor wraps tables as
 *   <figure class="table"><table>...</table></figure>
 * and puts no class on the <table> itself, so Bootstrap's .table rules
 * -- which require class="table" on the element -- have never applied.
 * These posts were rendering 160-cell county rate tables at the browser
 * default 1px cell padding with no header treatment at all.
 * =================================================================== */

.post-content figure.table,
.post-content .table-responsive {
    margin: 2em 0;
    /* Defensive: current tables fit a 390px screen, but a six-column regional
     * pricing table would not, and this beats a broken page layout. */
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.post-content table {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
    line-height: 1.5;
    /* Harvest counts and dollar figures sit in columns; lining figures keep
     * the digits aligned down the column. */
    font-variant-numeric: tabular-nums;
}

/* Standalone tables not wrapped in a figure (older posts, hand-written HTML). */
.post-content > table {
    display: block;
    overflow-x: auto;
    margin: 2em 0;
}

.post-content th {
    padding: 0.7rem 0.85rem;
    background-color: var(--color-timber);
    color: var(--color-white);
    font-family: var(--font-family-display);
    font-stretch: var(--font-stretch-display);
    font-weight: var(--font-weight-semibold);
    text-align: left;
    vertical-align: bottom;
    border: 0;
}

.post-content td {
    padding: 0.7rem 0.85rem;
    border-top: 1px solid var(--color-gray-200);
    vertical-align: top;
}

.post-content tbody tr:nth-child(odd) td {
    background-color: var(--color-gray-50);
}

/* Most of these tables are two-column label/value pairs where the label is a
 * <strong> inside a <td> rather than a <th>. Treat the first column as the
 * header it actually is, but only when the table has no real <thead>. */
.post-content table:not(:has(thead)) td:first-child {
    width: 34%;
    color: var(--color-gray-900);
    border-right: 1px solid var(--color-gray-200);
}

.post-content table caption,
.post-content figure.table figcaption {
    padding-top: 0.6rem;
    font-size: var(--font-size-sm);
    color: var(--color-gray-600);
    text-align: left;
    caption-side: bottom;
}

/* ===================================================================
 * Figures, quotes, code
 * =================================================================== */

.post-content figure.image {
    margin: 2em 0;
}

.post-content img {
    max-width: 100%;
    height: auto;
    border-radius: var(--radius-lg);
}

.post-content figure.image figcaption {
    padding-top: 0.6rem;
    font-size: var(--font-size-sm);
    color: var(--color-gray-600);
}

.post-content blockquote {
    margin: 2em 0;
    padding: 0.2em 0 0.2em 1.4em;
    border-left: 3px solid var(--color-contour);
    color: var(--color-gray-700);
    font-size: 1.125rem;
}

.post-content blockquote p:last-child {
    margin-bottom: 0;
}

.post-content code {
    padding: 0.15em 0.4em;
    background-color: var(--color-gray-100);
    border-radius: var(--radius-base);
    font-size: 0.9em;
    color: var(--color-gray-900);
}

.post-content pre {
    margin: 2em 0;
    padding: var(--spacing-4);
    background-color: var(--color-gray-900);
    color: var(--color-gray-100);
    border-radius: var(--radius-lg);
    overflow-x: auto;
}

.post-content pre code {
    padding: 0;
    background: none;
    color: inherit;
}

.post-content hr {
    margin: 2.5em 0;
    border-top: 1px solid var(--color-gray-300);
    opacity: 1;
}

@media (max-width: 575.98px) {
    .post-content {
        font-size: 1rem;
    }

    .post-content th,
    .post-content td {
        padding: 0.55rem 0.6rem;
    }

    /* A third of a 320px column is unusable for a label. */
    .post-content table:not(:has(thead)) td:first-child {
        width: auto;
    }
}

/* ===================================================================
 * Forum
 * =================================================================== */

/* Replies are a conversation, not a stack of filing cards. A rule between
 * them keeps the thread readable and lets the author line do the separating. */
.reply-row {
    padding: var(--spacing-5) 0;
    border-top: 1px solid var(--color-gray-200);
}

.reply-row:first-of-type {
    border-top: 0;
}

/* Topic and reply bodies are user-written prose and want the reading measure,
 * but inside a thread the rhythm should be tighter than an article. */
.topic-content.prose,
.reply-content.prose {
    font-size: var(--font-size-base);
}

.topic-content.prose p:last-child,
.reply-content.prose p:last-child {
    margin-bottom: 0;
}

/* ===================================================================
 * Partners
 * =================================================================== */

/* A partner card is a pitch, not a logo slot. It shipped as a logo, an
 * optional percentage and a button, which gave a reader no way to tell one
 * brand from the next or any reason to click a particular one. The two pieces
 * added below -- what the brand is, and the code to use at checkout -- are
 * what carry that. */
.partner-card {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.partner-head {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-2);
    margin-bottom: var(--spacing-3);
    text-align: center;
}

.partner-logo {
    max-height: 72px;
    max-width: 100%;
    object-fit: contain;
}

.partner-name {
    font-size: var(--font-size-lg);
    margin: 0;
}

.partner-description {
    color: var(--color-gray-700);
    font-size: var(--font-size-sm);
    line-height: 1.6;
    margin-bottom: var(--spacing-4);
}

/* The code is read off the screen and typed into someone else's checkout, so
 * it takes the mono face -- the same reason acreage and coordinates do -- and
 * a dashed border, which reads as "coupon" without needing a graphic. */
.partner-code {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-3);
    padding: var(--spacing-2) var(--spacing-3);
    margin-bottom: var(--spacing-3);
    border: 1px dashed var(--color-gray-400);
    border-radius: var(--radius-md);
    /* White, not frost -- it sits inside a .panel, which is already frost, so
     * the fill has to lift off the card for the dashed edge to read. */
    background-color: var(--color-white);
}

.partner-code-label {
    display: block;
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-gray-600);
}

.partner-code-value {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--color-gray-900);
    /* Long codes should wrap inside the card rather than widen it. */
    overflow-wrap: anywhere;
}

/* Injected by script, so it only appears where the clipboard API can back it.
 * Without JavaScript the code is still plain selectable text. */
.partner-code-copy {
    flex-shrink: 0;
    padding: var(--spacing-1) var(--spacing-2);
    border: 1px solid var(--color-gray-300);
    border-radius: var(--radius-base);
    background-color: var(--color-gray-100);
    font-size: var(--font-size-xs);
    color: var(--color-gray-700);
    cursor: pointer;
}

.partner-code-copy:hover,
.partner-code-copy:focus-visible {
    border-color: var(--color-gray-500);
    color: var(--color-gray-900);
}

.partner-banner {
    max-height: 120px;
    object-fit: cover;
    margin-top: var(--spacing-4);
    border-radius: var(--radius-base);
}

/* The inbound half of the partners page: brands sizing us up, rather than
 * shoppers looking for a deal. Centred and held to the reading measure so it
 * reads as a closing note under the grid, not another partner card. */
.partner-cta {
    margin-top: var(--spacing-4);
    text-align: center;
}

.partner-cta h2 {
    font-size: var(--font-size-xl);
    margin-bottom: var(--spacing-3);
}

.partner-cta p {
    max-width: 58ch;
    margin: 0 auto var(--spacing-4);
    color: var(--color-gray-700);
    font-size: var(--font-size-sm);
    line-height: 1.6;
}
