@charset "UTF-8";

/* The whole stylesheet.
 *
 * This was five Sass partials until it was plain CSS; the sections below are
 * where the partial boundaries used to be.  Sass earned its place when the
 * only way to get variables and nesting was to compile for them.  Both are
 * native now -- custom properties everywhere, and nesting in Chrome 120,
 * Firefox 117 and Safari 17.2, all from 2023 -- so the transpiler was buying
 * a `&__suffix` shorthand and an @import that Hugo can do by reading one
 * file.  Dropping it also drops the hugo-extended requirement from
 * mise.toml, since SCSS was the only thing the site used it for.
 *
 * The one Sass feature with no native equivalent is `&` concatenation:
 * `.page { &__header {} }` cannot be expressed, because native `&` refers to
 * the parent selector rather than pasting its text.  So BEM names are
 * written out in full.  Nesting is kept for what it still does natively --
 * pseudo-classes and short descendant chains -- and every nesting parent
 * here is a single selector, not a list, so `:is()`-wrapping `&` does not
 * move any specificity.
 */

/* ------------------------------------------------------------------ theme */

/* Every color in the stylesheet resolves to one of the custom properties
 * below.  Keeping them as properties rather than build-time constants is
 * what lets one stylesheet carry both palettes: they are resolved by the
 * browser, so the single fingerprinted main.css holds light and dark and
 * `prefers-color-scheme` picks between them -- no toggle, no inline <style>,
 * and so no new CSP style-src hash.
 *
 * No rule below names a raw color.  Add colors here, not in the rules.
 *
 * The light values are the site's original palette, unchanged.  The dark set
 * keeps the same structure -- a green frame around a near-neutral reading
 * surface -- with the lightness relationships inverted rather than the hues
 * replaced, so the site reads as the same site with the lights off.
 */

:root {
    /* Tells the browser both palettes exist, so UA-painted chrome -- form
     * controls, scrollbars, the canvas behind the page -- follows the system
     * setting along with the colors below instead of staying stuck in light. */
    color-scheme: light dark;

    /* Surfaces, back to front: the frame the page sits on, the header band,
     * the reading surface, and the slightly raised surface on top of it.
     *
     * The frame is deeper than the #283 this site used through 2025.  The
     * footer is the only text that sits on it, and on #283 nothing between
     * white (4.53:1) and black (4.64:1) cleared WCAG AA -- so the footer's
     * #ddd byline sat at 3.33:1 with no room for #fff to read as a hover.
     * Darkening the ground rather than lightening the text buys headroom for
     * both: 5.07:1 at rest, 6.88:1 on hover. */
    --color-frame-bg: #1a6826;
    --color-header-bg: #dfd;
    --color-content-bg: #f9f9f9;
    --color-content-bg-alt: #fff;

    /* Text, in descending prominence: body copy, quotes and secondary text,
     * bylines and datelines, then icons and the faintest supporting marks. */
    --color-fg: #000;
    --color-fg-light: #333;
    --color-fg-xlight: #666;
    --color-fg-xxlight: #999;

    /* Rules and borders */
    --color-line: #aaa;
    --color-line-light: #ccc;
    --color-image-border: #333;
    --color-scrollbar-thumb: #ccc;

    /* Accents and links */
    --color-accent: #283;
    --color-accent-dark: #060;
    --color-link: #06c;
    --color-link-hover: #09f;
    --color-title-link-hover: #093;

    /* Footer, which sits on the frame rather than on the reading surface */
    --color-footer-fg: #ddd;
    --color-footer-fg-hover: #fff;
}

@media (prefers-color-scheme: dark) {
    :root {
        --color-frame-bg: #0e1f16;
        --color-header-bg: #14301f;
        --color-content-bg: #17191a;
        --color-content-bg-alt: #202324;

        /* Held a little below pure white: #fff on a near-black surface haloes
         * at the ~14px body size this site sets. */
        --color-fg: #e7e4e0;
        --color-fg-light: #c9c6c1;
        --color-fg-xlight: #a29f99;
        --color-fg-xxlight: #817e78;

        --color-line: #4b4e4d;
        --color-line-light: #333736;
        --color-image-border: #4b4e4d;
        --color-scrollbar-thumb: #55595a;

        /* The light palette's link blue (#06c) sits at about 2:1 against the
         * dark reading surface, so the ramp is lightened rather than reused. */
        --color-accent: #4e9d68;
        --color-accent-dark: #2d6440;
        --color-link: #7ab4ff;
        --color-link-hover: #a8cfff;
        --color-title-link-hover: #5fd98a;

        --color-footer-fg: #cfd6d0;
        --color-footer-fg-hover: #fff;
    }
}

/* -------------------------------------------------------------- typography */

/* Outside the palette block because these do not vary with the color scheme;
 * the media query above has nothing to say about them. */

:root {
    --font-serif: 'Noto Serif', 'Hoefler Text', 'Georgia', serif;
    --font-sans: 'Open Sans', Helvetica, Arial, sans-serif;
    --weight-bold: 700;
    --weight-light: 300;
}

/* --------------------------------------------------------------- base tags */

body {
    font: 14px/1.5 var(--font-serif);
    color: var(--color-fg);
    margin: 0;
    background-color: var(--color-frame-bg);
}

a {
    color: var(--color-link);
    text-decoration: underline;

    &:hover {
        color: var(--color-link-hover);
        text-decoration: underline;
    }
}

p { margin: 0 0 1.5em; }

table { margin: 0 auto 1.5em; }

img { border: 0; }

h1 {
    font: 1.5em var(--font-sans);
    margin: 1.25em 0 0.25em;
    font-weight: var(--weight-bold);
}

h2 {
    font: 1.2em var(--font-sans);
    margin: 1.55em 0 0.25em;
    font-weight: var(--weight-bold);
    font-style: italic;
}

h3 {
    font: 1.0em var(--font-sans);
    margin: 1.25em 0 0.25em;
    font-weight: var(--weight-bold);
    font-style: italic;
}

blockquote {
    border-left: 1px solid var(--color-accent);
    color: var(--color-fg-light);
    margin: 1.5em 0;
    padding-left: 1.5em;
}

code {
    font: 1em Inconsolata, Menlo, Monaco, 'Courier New', Courier, sans-serif;
}

pre {
    line-height: 1.2;
    margin: 0 0 1.5em;
    padding-left: 1.5em;
    overflow-x: scroll;

    /* The `&` is load-bearing.  A bare `::-webkit-scrollbar` nests to the
     * descendant `pre ::-webkit-scrollbar`, which styles the scrollbar of
     * something inside the <pre> -- but the overflow is on the <pre> itself,
     * so that selector has never matched anything.  A horizontal scrollbar is
     * also sized by height; the `width` these carried did nothing even once
     * the selector was right.
     *
     * WebKit and Blink only.  Firefox styles scrollbars through
     * `scrollbar-color`, which cannot express the rounded thumb, so it keeps
     * its default scrollbar here rather than an approximation of this one. */
    &::-webkit-scrollbar:horizontal {
        height: 12px;
    }

    &::-webkit-scrollbar-thumb:horizontal {
        background-color: var(--color-scrollbar-thumb);
        border-radius: 10px;
    }
}

hr {
    width: 10em;
    height: 1px;
    border: 0;
    background-color: var(--color-line);
}

sup, sub {
    vertical-align: 0;
    position: relative;
}
sup { bottom: 1ex; }
sub { top: 0.8ex; }

figure, .figure {
    margin: 0 auto;
    padding: 0;
    text-align: center;
}

figure img,
.figure img {
    border: 1px solid var(--color-image-border);
    max-width: 100%;
}

figure .caption,
.figure .caption {
    font-size: 0.75em;
    line-height: 2;
}

/* ------------------------------------------------------------------- page */

.page__main-container {
    background-color: var(--color-content-bg);
    padding: 1em 0;
    text-align: center;
}

.page main {
    margin: 0 auto;
    position: relative;
    text-align: left;
    max-width: 50em;
}

/* Header, Footer, Sidebar */

.page__header {
    box-sizing: border-box;
    text-align: center;
    padding: 1em 0;
    background-color: var(--color-header-bg);
}

.page__title {
    margin: 0;
    font-size: 2em;
    font-weight: 300;
    font-family: 'Open Sans Condensed', var(--font-sans);
}

.page__title__link {
    text-decoration: none;
    border-bottom: 0;

    &:link,
    &:visited {
        text-decoration: none;
        color: var(--color-link);
    }

    &:hover,
    &:active {
        text-decoration: none;
        color: var(--color-title-link-hover);
    }
}

.page__footer {
    border-top: 1px solid var(--color-accent-dark);
    color: var(--color-footer-fg);
    font-family: var(--font-sans);
    font-weight: var(--weight-light);
    margin: 0;
    padding: 1.5em;
    text-align: center;

    a {
        color: var(--color-footer-fg);
        text-decoration: underline;
    }

    a:hover {
        color: var(--color-footer-fg-hover);
    }
}

article {
    margin: 1em auto;

    & > header > h1 {
        margin: 0 0 0.5em;
        line-height: 1;
        font-size: 2em;
    }

    ul {
        padding-inline-start: 1.75rem;
    }
}

.page article ul.page-listing {
    padding: 0;
    margin: 1em 0;
    list-style-type: none;

    li {
        margin-bottom: 0.5em;
    }
}

/* ------------------------------------------------------------------- blog */

.page--blog__nav {
    background-color: var(--color-content-bg-alt);
    border-top: 1px solid var(--color-line-light);
    color: var(--color-fg-light);
    padding: 1.5em;
    text-align: center;

    ul {
        list-style: none;
        margin: 0;
        padding-left: 0;
    }

    li {
        display: inline-block;
        margin: 0 2em;
    }
}

.page--blog iframe {
    margin: 0 0 1.5em;
}

.page--blog article > header {
    h1 {
        margin: 0.75em 0 0.25em;
    }

    time, .post-category {
        color: var(--color-fg-xlight);
        display: inline-block;
        font-size: 1em;
        font-weight: 400;
        font-family: var(--font-sans);
        line-height: 1.5;
        margin: 0 0.5em 1.5em 0;
    }

    .post-category {
        margin-left: 0.5em;
    }

    .permalink {
        /* No font-family or font-feature-settings here: this anchor holds an
         * <svg><use> and no text, and the Symbolset face those settings were
         * shaping ("SSStandard", turned into glyphs by the `liga`/`dlig`
         * ligatures) is not among the fonts the site loads.  The properties
         * below are the ones that still position the inline SVG. */
        border: 0;
        font-style: normal;
        font-weight: normal;
        line-height: 1.25;
        padding: 0.2em 0.2em 0;
        text-decoration: none;
        vertical-align: -0.2em;
        white-space: nowrap;

        svg {
            fill: var(--color-fg-xxlight);
            height: 14px;
            width: 14px;
            vertical-align: top;
            margin-top: 3px
        }
        &:hover svg {
            fill: var(--color-link);
        }
    }

    & + h2 {
        margin-top: 0;
    }
}

.page--blog article {
    ul {
        margin: 1.5em 0 1.5em 1em;
        padding: 0 0 0 1em;
    }

    a {
        text-decoration: underline;
    }

    a.footnote-back, a.footnote-return {
        padding-left: 3px;
        text-decoration: none;
    }
}

/* Separates consecutive posts on the blog index, which lists five of them.
 * This was nested inside the block above, making it `article article +
 * article` -- two sibling posts inside a third -- and no template nests
 * <article> at all.  At the top level it matches the siblings it was for. */
.page--blog article + article {
    border-top: 1px solid var(--color-line-light);
}
