/* Blog Layout Styles */

.blog-article {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    padding-bottom: 60px;
}

.blog-header,
.blog-body,
.blog-reading-layout {
    grid-column: 1 / -1;
}

.blog-reading-layout {
    align-items: start;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.blog-reading-layout > .blog-body {
    display: block;
    grid-column: 2 / 4;
    min-width: 0;
}

.blog-toc-hover-zone {
    display: none;
}

.blog-toc {
    align-self: start;
    box-sizing: border-box;
    font-size: var(--type-blog-metadata-size, 0.5em);
    left: 0;
    line-height: 1.25;
    max-height: calc(100vh - 60px);
    overflow-y: auto;
    padding: 5px 2em 0 8px;
    position: fixed;
    top: calc(30px + 1em);
    transform: translateX(0);
    will-change: transform, opacity;
    z-index: 2;
}

body.blog-toc-motion-ready .blog-toc {
    transition:
        transform 500ms cubic-bezier(0.65, 0, 0.35, 1),
        opacity 320ms ease-out 40ms;
}

.blog-toc-title {
    margin-bottom: 0.75em;
}

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

.blog-toc-list li {
    margin: 0 0 0.75em;
}

.blog-toc-list a {
    display: block;
    font-weight: 400;
    opacity: 0.42;
}

body.blog-toc-motion-ready .blog-toc-list a {
    transition: opacity 260ms ease-out;
}

.blog-toc-list a.is-current,
.blog-toc-list a[aria-current="location"] {
    font-weight: 700;
    opacity: 1;
}

/* Subheaders: one tab of indentation per level, revealed only for the
   section that is currently in view. */
.blog-toc-subs {
    list-style: none;
    margin: 0;
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    padding: 0 0 0 1.25em;
    transition:
        max-height 180ms cubic-bezier(0.65, 0, 0.35, 1),
        opacity 150ms ease-out,
        margin-top 180ms cubic-bezier(0.65, 0, 0.35, 1);
}
.blog-toc-section.is-open .blog-toc-subs {
    margin: 0.75em 0 0;
    /* The runtime measures the exact content height into --subs-height so the
       slide maps 1:1 to the visible content (no giant-cap easing distortion). */
    max-height: var(--subs-height, 60em);
    opacity: 1;
    transition:
        max-height 380ms cubic-bezier(0.65, 0, 0.35, 1),
        opacity 220ms ease-out 80ms,
        margin-top 260ms cubic-bezier(0.65, 0, 0.35, 1);
}
.blog-toc-subs > li {
    margin: 0 0 0.6em;
    transform: translateY(6px);
    transition: transform 380ms cubic-bezier(0.65, 0, 0.35, 1);
}
.blog-toc-section.is-open .blog-toc-subs > li {
    transform: translateY(0);
}
.blog-toc-subs a.is-current {
    font-weight: 700;
    opacity: 1;
}
.blog-toc-subs a {
    font-size: 0.95em;
    padding-left: 0.25em;
}
@media (prefers-reduced-motion: reduce) {
    .blog-toc-section.is-open .blog-toc-subs {
        transition: none;
    }
}

/* The TOC bar: fixed under the navbar. It never participates in flow, so
   the body text never moves and the document height never changes. The
   toggle names the current heading; clicking expands the full list as a
   dropdown below the bar. */
.blog-toc-bar {
    background: #fff;
    box-sizing: border-box;
    display: none;
    left: 0;
    position: fixed;
    right: 0;
    top: 30px;
    z-index: 4;
    /* Hidden until the first separation line above the first image scrolls
       under the navbar; then it animates out from under the nav bar. */
    transform: translateY(-100%);
    opacity: 0;
    pointer-events: none;
    transition: transform 450ms cubic-bezier(0.16, 1, 0.3, 1), opacity 320ms ease-out;
}

body.blog-toc-past-rule .blog-toc-bar {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}

body:has(.cnavbar.is-collapsed) .blog-toc-bar {
    top: 0;
}

body:has(.cnavbar.is-collapsed) .blog-toc-bar {
    top: 0;
}

.blog-toc-bar-toggle {
    align-items: center;
    background: #fff;
    border: 0;
    cursor: pointer;
    display: flex;
    font: inherit;
    font-size: 0.5em;
    font-weight: 700;
    gap: 10px;
    justify-content: space-between;
    letter-spacing: 0.08em;
    padding: 10px 14px 3px;
    text-align: left;
    text-transform: uppercase;
    width: 100%;
}

body:has(.cnavbar.is-collapsed) .blog-toc-bar-toggle {
    padding-right: 62px;
    width: calc(100% - 54px);
}

.blog-toc-bar-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.blog-toc-bar-caret {
    flex: 0 0 auto;
    transform: rotate(0deg);
    transition: transform 260ms cubic-bezier(0.65, 0, 0.35, 1);
}

.blog-toc-bar.is-open .blog-toc-bar-caret {
    transform: rotate(90deg);
}

.blog-toc-bar-full {
    font-size: 0.5em;
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    padding: 0 14px;
    transition:
        max-height 380ms cubic-bezier(0.65, 0, 0.35, 1),
        opacity 220ms ease-out;
}

.blog-toc-bar.is-open .blog-toc-bar-full {
    max-height: var(--bar-toc-height, 60vh);
    opacity: 1;
    overflow-y: auto;
    padding: 10px 14px 3px;
}

.blog-toc-bar .blog-toc-title {
    margin-bottom: 0.75em;
}

.blog-toc-bar .blog-toc-list {
    margin-bottom: 0;
}

.blog-toc-bar .blog-toc-list a,
.blog-toc-bar .blog-toc-subs a {
    opacity: 1;
}

.blog-toc-bar .blog-toc-subs {
    max-height: none;
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    .blog-toc-bar-full,
    .blog-toc-bar-caret {
        transition: none;
    }
}

.blog-header {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin-bottom: 32px;
}

.blog-title-grid {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.blog-title {
    grid-column: 2 / 4;
    margin: 0 0 8px;
    padding: 0 0 0 3px;
    /* H1 semantics, H2 visuals: cancel display-title defaults and keep the
       section-size treatment the title had as an authored H2. */
    font-size: var(--type-section-size, 4em);
    font-weight: var(--type-section-weight, normal);
    line-height: var(--type-section-line-height, 1);
    overflow-wrap: anywhere;
    position: static;
    /* H1 semantics must never inherit the display-title marquee at the
       800px breakpoint, and never become a scroll container either: the
       marquee's overflow-x: auto would eat wheel input over the title. */
    animation: none;
    display: block;
    overflow-x: visible;
    white-space: normal;
}

.blog-header .tags2 {
    grid-column: 2 / 4;
    padding-left: 3px;
    margin-bottom: 8px;
}

.blog-meta {
    grid-column: 2 / 4;
    color: #888;
    font-size: var(--type-blog-metadata-size, 0.5em);
    display: flex;
    gap: 12px;
    align-items: center;
    padding-left: 3px;
}

.blog-meta time {
    white-space: nowrap;
}

.blog-reading-time {
    white-space: nowrap;
}

/* Related Writing */
.blog-related {
    grid-column: 2 / 4;
    padding-left: 3px;
    margin-top: 48px;
    margin-bottom: 40px;
}

.blog-related-title {
    font-size: var(--type-blog-related-label-size, 0.75em);
    text-transform: uppercase;
    letter-spacing: var(--type-blog-related-label-tracking, 0.1em);
    color: #888;
    margin-bottom: 12px;
}

.blog-related .cmain {
    background: transparent;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    padding-top: 0;
    padding-bottom: 8px;
}

.blog-related .cmain::after {
    content: none;
}

.blog-related .c2 {
    border: 1px solid var(--color-border-light);
    box-sizing: border-box;
    margin: 0;
    min-width: 0;
}

.blog-related .cimg2 {
    aspect-ratio: 16 / 9;
    width: 100%;
    height: auto;
    overflow: hidden;
}

.blog-related .cimg2 img,
.blog-related .cimg2 video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.blog-related-placeholder .cimg2 {
    background: var(--color-background-light);
}

.blog-lede {
    grid-column: 2 / 4;
    padding-left: 3px;
    margin-bottom: 32px;
}

.blog-description-rule {
    width: 100%;
    margin: 1em 0 0;
    border: 0;
    border-top: 1px solid #ccc;
}

.blog-section-heading {
    grid-column: 2 / 4;
    padding-left: 3px;
    margin-top: 1em;
    margin-bottom: 0.5em;
}

/* Only the authored-H2 sections take the raised section size; H3/H4/H5
   subheaders keep their own element scales, so the article hierarchy reads
   at every breakpoint (h3-size is flat, so the ratio never inverts). */
h2.blog-section-heading {
    font-size: calc(var(--type-subsection-h3-size, 1.17em) * 1.5);
    font-weight: var(--type-subsection-weight, bold);
    overflow-wrap: anywhere;
}

.blog-section-heading[id] {
    scroll-margin-top: calc(30px + 0.5em);
}

.blog-body {
    overflow-wrap: anywhere;
}

.blog-body figure {
    grid-column: 2 / 4;
    width: 100%;
    margin: 2em 0;
    text-align: center;
}

.blog-body figure img,
.blog-body figure video {
    max-width: 100%;
    height: auto;
    display: block;
    margin: 0 auto;
}

.blog-body figcaption {
    font-size: var(--type-blog-caption-size, 0.85em);
    color: #888;
    margin-top: 8px;
    text-align: center;
}

.blog-body blockquote {
    border-left: 3px solid #ccc;
    margin: 1.5em 0;
    padding: 0.5em 0 0.5em 1.25em;
    color: #555;
    font-style: italic;
}

.blog-body blockquote p {
    margin-bottom: 0;
}

.blog-body pre {
    background: #f5f5f5;
    padding: 16px;
    overflow-x: auto;
    margin: 1.5em 0;
    border-radius: 4px;
}

.blog-body code {
    font-family: var(--type-blog-code-family, monospace);
    font-size: var(--type-blog-code-size, 0.9em);
    background: #f5f5f5;
    padding: 2px 5px;
    border-radius: 3px;
}

.blog-body pre code {
    background: none;
    padding: 0;
}

.blog-body a {
    text-decoration: underline;
}

.blog-body ul,
.blog-body ol {
    margin-bottom: 1.25em;
    padding-left: 1.5em;
}

.blog-body li {
    margin-bottom: 0.4em;
}

/* Footer */
.blog-footer {
    grid-column: 2 / 4;
    padding-left: 3px;
    margin-top: 48px;
    font-size: var(--type-blog-footer-size, 0.9em);
    color: #888;
}

/* The rule spans the content box, never the padded box, so it can never
   stretch across columns that have no body. */
.blog-footer::before {
    border-top: 1px solid #eee;
    content: "";
    display: block;
    margin-bottom: 24px;
}

/* Blog Index */
.blog-index {
    padding-bottom: 60px;
}

.blog-index-title {
    margin-bottom: 0;
}

.blog-card-placeholder .cimg2 {
    background: var(--color-background-light);
}

@media (min-width: 801px) and (max-width: 1200px) {
    /* Fractional grid lines are invalid CSS, so the half-column reading
       inset is full-span items with 12.5% side padding (half a column);
       the +3px keeps the optical alignment with section headings. Section
       headings and figures live inside the padded body and inherit the
       inset, so they carry no padding of their own. */
    .blog-title,
    .blog-header .tags2,
    .blog-meta,
    .blog-footer,
    .blog-related,
    .blog-lede {
        grid-column: 1 / -1;
        padding-left: calc(12.5% + 3px);
        padding-right: 12.5%;
    }

    .blog-reading-layout > .blog-body {
        grid-column: 1 / -1;
        padding-left: 12.5%;
        padding-right: 12.5%;
    }
}

@media (min-width: 1201px) {
    /* Long headings wrap inside the first column so they can never
       render under the body. */
    .blog-toc {
        max-width: 25vw;
    }

    .blog-toc-list a,
    .blog-toc-subs a {
        overflow-wrap: anywhere;
    }

    body.blog-toc-past-hero .blog-toc-hover-zone {
        bottom: 0;
        display: block;
        left: 0;
        position: fixed;
        top: 30px;
        width: 25vw;
        z-index: 1;
    }

    body.blog-toc-past-hero .blog-toc {
        opacity: 0;
        pointer-events: none;
        transform: translateX(calc(-100% - 2em));
        z-index: 2;
    }

    body.blog-toc-past-hero.blog-toc-pointer-in-zone .blog-toc,
    body.blog-toc-past-hero .blog-toc-hover-zone:hover + .blog-toc,
    body.blog-toc-past-hero .blog-toc:focus-within,
    body.blog-toc-past-hero .blog-toc:hover {
        opacity: 1;
        pointer-events: auto;
        transform: translateX(0);
    }

    /* Past the By-author footer the TOC is gone for good, even while the
       panel is hovered or focused. */
    body.blog-toc-cta-reached .blog-toc {
        opacity: 0 !important;
        pointer-events: none !important;
        transform: translateX(calc(-100% - 2em)) !important;
    }
}

@media (max-width: 1200px) {
    .blog-reading-layout > .blog-toc {
        display: none;
    }

    .blog-toc-bar {
        display: block;
    }

    .blog-article {
        padding-top: 46px;
    }

    body.blog-toc-cta-reached .blog-toc-bar {
        display: none;
    }
}

@media (max-width: 800px) {
    .blog-title,
    .blog-header .tags2,
    .blog-meta,
    .blog-footer,
    .blog-related,
    .blog-lede,
    .blog-section-heading {
        grid-column: 1 / -1;
        padding-left: 10px;
    }

    .blog-body figure {
        grid-column: 1 / -1;
    }

    .blog-toc-hover-zone {
        display: none;
    }

    .blog-reading-layout {
        display: block;
    }

    .blog-reading-layout > .blog-body {
        display: grid;
    }

}

@media (max-width: 600px) {
    .blog-article,
    .blog-index {
        padding-bottom: 40px;
    }

    .blog-related .cmain {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (prefers-reduced-motion: reduce) {
    body.blog-toc-motion-ready .blog-toc,
    body.blog-toc-motion-ready .blog-toc-list a {
        transition: none;
    }
}
