/**
 * Post header and body frame: patterns/post-header.php, the content of the
 * GP element "Single post template". The reading column itself is styled in
 * css/article.css.
 *
 * Two GP elements: the header is a hook element on generate_after_header
 * (patterns/post-header*.php, one per variant, only one with the display
 * rule post:post) and the body is the content-template element
 * (patterns/post-body.php). The header prints before .site-content, so the
 * body section never follows it as a sibling.
 *
 * Header structure:
 *   .post-header-section.color-section > inner
 *     .post-header                     centered, --article-width
 *       p.post-label                   category (dynamic terms)
 *       h1.post-title                  dynamic post title
 *       p.post-lead                    excerpt
 *       .post-meta                     [applari_post_meta] in a container
 *     figure > img.post-image          featured image, --article-wide-width,
 *                                      figure owns the box (16:9, 4:3 on mobile)
 * Body structure:
 *   .post-body-section.color-section > inner
 *     .post-body                       grid: 1 column; from 1280px
 *                                      1fr | column | 1fr
 *       details.post-toc--top          [applari_toc], collapsed, below 1280px
 *       nav.post-toc--side             same list, sticky beside the column from 1280px;
 *                                      article-toc.js marks the current heading and
 *                                      hides it (.is-covered) under wide media
 *       .post-content                  the column (article.css):
 *                                      [applari_author start], GP dynamic content,
 *                                      the default next-steps (dropped when the
 *                                      post has its own), [applari_author end]
 *
 * Header variants (a class on the header section):
 *   (none)                  editorial: text, then the image below
 *   post-header--band       the header is a palette band (wrapper class on the
 *                           section); the image sits in its own
 *                           .post-image-section after it and rises into the
 *                           band (--post-band-overlap)
 *   post-header--split      text left on its own palette, the image right,
 *                           bleeding to the screen edge from 990px
 *                           (structure: .post-header-split grid with
 *                           .post-header-split-text + .post-header-split-image)
 *
 * Animation: the header texts chain (label, title, lead, meta, 0.4s each);
 * the meta fires the event post-header-ready and the image fades in on it.
 * In the split variant the image slides in from the right at once. The body
 * never animates.
 *
 * Tuning: --post-toc-width (240px), --post-image-ratio (16 / 9),
 *   --post-band-overlap (120px, 64px below 768px)
 */

:root {
    --post-toc-width: 240px;
    --post-image-ratio: 4 / 3;
    --post-band-overlap: 64px;
}

/* Top and bottom only: the side gutter of .alignfull (base.css) stays. */
.gb-container.color-section.post-header-section {
    padding-top: 48px;
    padding-bottom: 0;
}

.post-header {
    max-width: var(--article-width);
    margin: 0 auto;
}

.post-label {
    margin: 0 0 16px;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent-clr);
}

.post-label a {
    color: inherit;
    text-decoration: none;
}

.post-label a:hover {
    text-decoration: underline;
}

.post-title {
    margin: 0 0 20px;
    font-size: var(--h1-size);
    text-wrap: balance;
}

.post-lead {
    margin: 0 0 24px;
    font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
    line-height: 1.5;
    text-wrap: pretty;
}

.post-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 12px;
    font-size: 0.875rem;
    opacity: 0.85;
}

.post-meta > span + span::before {
    content: "·";
    margin-right: 12px;
    opacity: 0.6;
}

/* GB puts the global class on the img of a dynamic image, so the figure is
   found through it. */
figure:has(> img.post-image) {
    position: relative;
    max-width: var(--article-wide-width);
    margin: 40px auto 0;
    aspect-ratio: var(--post-image-ratio);
    overflow: hidden;
}

img.post-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Body: the grid that holds the table of contents and the column. The body
   section has no top padding of its own; the gap after the header is here. */
.gb-container.color-section.post-body-section {
    padding-top: 0;
}

.post-body {
    padding-top: 40px;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
}

/* Table of contents */
.post-toc {
    font-size: 0.9375rem;
}

.post-toc ol {
    margin: 0;
    padding: 0;
    list-style: none;
}

.post-toc li {
    margin: 0;
}

.post-toc a {
    display: block;
    padding: 6px 0 6px 12px;
    border-left: 2px solid transparent;
    color: inherit;
    text-decoration: none;
    transition: border-color var(--transition-speed) var(--transition-timing-function),
                color var(--transition-speed) var(--transition-timing-function);
}

.post-toc a:hover,
.post-toc a[aria-current="true"] {
    border-left-color: var(--accent-clr);
    color: var(--accent-clr);
}

.post-toc a[aria-current="true"] {
    font-weight: 600;
}

.post-toc--top {
    width: 100%; /* grid item: no shrink-to-fit with the auto margins */
    max-width: var(--article-width);
    margin: 0 auto 32px;
    border: 1px solid color-mix(in srgb, currentColor 15%, transparent);
    border-radius: 4px;
}

.post-toc--top summary {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}

.post-toc--top summary::-webkit-details-marker {
    display: none;
}

.post-toc--top summary::after {
    content: "+";
    font-size: 1.25em;
    line-height: 1;
}

.post-toc--top[open] summary::after {
    content: "–";
}

.post-toc--top nav {
    padding: 0 16px 12px;
}

.post-toc--side {
    display: none;
}

/* ---------- Variant: band ---------- */

.gb-container.color-section.post-header-section.post-header--band {
    padding-top: 64px;
    padding-bottom: calc(var(--post-band-overlap) + 40px);
}

.post-header--band .post-title {
    font-size: clamp(2.6rem, 1.8rem + 2.6vw, 4.2rem);
}

/* The image section after the band: no padding, the image rises into the band. */
.gb-container.color-section.post-image-section {
    padding: 0;
}

.post-image-section figure:has(> img.post-image) {
    margin-top: calc(-1 * var(--post-band-overlap));
    box-shadow: var(--box-shadow);
}

/* ---------- Variant: split ---------- */

.gb-container.color-section.post-header-section.post-header--split {
    padding: 0;
}

.post-header-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
}

.post-header-split-text {
    padding: 56px var(--mobile-side-padding) 48px;
}

.post-header--split .post-header {
    margin: 0;
}

.post-header--split .post-title {
    font-size: clamp(2.4rem, 1.7rem + 2.2vw, 3.8rem);
}

.post-header-split-image {
    position: relative;
}

.post-header--split figure:has(> img.post-image) {
    max-width: none;
    margin: 0;
}

@media only screen and (min-width: 768px) {
    :root {
        --post-band-overlap: 120px;
    }
}

@media only screen and (min-width: 990px) {
    .post-header-split {
        grid-template-columns: minmax(0, 7fr) minmax(0, 6fr);
    }

    /* Text aligns with the site's 1280px grid, the image runs to the edge. */
    .post-header-split-text {
        display: flex;
        flex-direction: column;
        justify-content: center;
        padding: 80px 64px 80px max(var(--mobile-side-padding), calc((100vw - var(--container-width)) / 2));
    }

    .post-header-split-image {
        min-height: 480px;
    }

    .post-header--split figure:has(> img.post-image) {
        position: absolute;
        inset: 0;
        aspect-ratio: auto;
    }
}

@media only screen and (min-width: 768px) {
    :root {
        --post-image-ratio: 16 / 9;
    }

    .post-body {
        padding-top: 64px;
    }
}

@media only screen and (min-width: 1280px) {
    .post-body {
        grid-template-columns: minmax(0, 1fr) min(var(--article-width), 100%) minmax(0, 1fr);
        column-gap: 40px;
    }

    .post-body > .post-content {
        grid-column: 2;
        grid-row: 1;
        margin: 0;
    }

    .post-toc--top {
        display: none;
    }

    .post-toc--side {
        display: block;
        grid-column: 1;
        grid-row: 1;
        justify-self: end;
        align-self: start;
        width: var(--post-toc-width);
        position: sticky;
        top: calc(var(--post-sticky-offset) + 32px);
        transition: opacity var(--transition-speed) var(--transition-timing-function);
    }

    .post-toc--side.is-covered {
        opacity: 0;
        pointer-events: none;
    }

    .post-toc-title {
        margin: 0 0 8px 12px;
        font-size: 0.8rem;
        font-weight: 600;
        letter-spacing: 0.08em;
        text-transform: uppercase;
        opacity: 0.7;
    }
}
