@layer blahaj, reset, variables, base, utilities, components;

/* Fonts */

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("/fonts/inter-normal.woff2") format("woff2");
}

@font-face {
    font-family: "Inter";
    font-style: italic;
    font-weight: 100 900;
    font-display: swap;
    src: url("/fonts/inter-italic.woff2") format("woff2");
}

@font-face {
    font-family: "Nunito Sans";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("/fonts/nunito-sans-normal.woff2") format("woff2");
}

@font-face {
    font-family: "Nunito Sans";
    font-style: italic;
    font-weight: 100 900;
    font-display: swap;
    src: url("/fonts/nunito-sans-italic.woff2") format("woff2");
}

@font-face {
    font-family: "Fira Code";
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url("/fonts/fira-code-normal.woff2") format("woff2");
}

:root {
    --font-inter: "Inter";
    --font-nunito-sans: "Nunito Sans";
    --font-fira-code: "Fira Code";
}

/* ---- reset ---- */
@layer reset {
    /* Use a more-intuitive box-sizing model */
    *,
    *::before,
    *::after {
        box-sizing: border-box;
    }

    /* Remove default margin */
    *:not(dialog) {
        margin: 0;
    }

    /* Enable keyword animations */
    @media (prefers-reduced-motion: no-preference) {
        html {
            interpolate-size: allow-keywords;
        }
    }

    body {
        /* Looks better with Nunito Sans */
        -webkit-font-smoothing: auto;
    }

    /* Improve media defaults */
    img,
    picture,
    video,
    canvas,
    svg {
        display: block;
        max-width: 100%;
        vertical-align: middle;
    }

    /* Inherit fonts for form controls */
    input,
    button,
    textarea,
    select {
        font: inherit;
    }

    /* Avoid text overflows */
    p,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6 {
        overflow-wrap: break-word;
    }

    /* Improve line wrapping */
    p {
        text-wrap: pretty;
    }

    h1,
    h2,
    h3,
    h4,
    h5,
    h6 {
        text-wrap: balance;
    }

    /* Remove native button user agent */
    button {
        appearance: none; /* Removes platform-specific styling */
        background: transparent;
        border: none;
        padding: 0;
        margin: 0;
        font: inherit; /* Forces button to use the parent's font settings */
        color: inherit;
        cursor: pointer; /* Adds the hand icon back */
        outline: none; /* Be careful with this (see accessibility note) */
    }

    /* Create a root stacking context */
    #root {
        isolation: isolate;
    }
}

/* ---- variables (was styles/variables.css) ---- */
@layer variables {
    /* Colors come from blahaj-theme.css, which is linked before this file and
       copied from the blahaj-color-scheme repository. Contrast ratios are
       checked against --background and --surface in both schemes. */

    :root {
        --foreground: var(--blahaj-text);
        --foreground-inverted: var(--blahaj-text-inverted);
        --background: var(--blahaj-background);
        --surface: var(--blahaj-surface);
        --surface-raised: var(--blahaj-surface-raised);
        --border: var(--blahaj-border);
        --border-subtle: var(--blahaj-border-subtle);
        --muted: var(--blahaj-text-muted);
        --primary: var(--blahaj-primary);
        --accent: var(--blahaj-accent);
        --shadow: var(--blahaj-shadow);

        /* Base colors */
        --space-quarter: 0.0625rem;
        --space-half: 0.125rem;
        --space-1: 0.25rem;
        --space-2: 0.5rem;
        --space-3: 0.75rem;
        --space-4: 1rem;
        --space-5: 1.25rem;
        --space-6: 1.5rem;
        --space-8: 2rem;
        --space-10: 2.5rem;
        --space-12: 3rem;
        --space-14: 3.5rem;
        --space-16: 4rem;
        --space-18: 4.5rem;
        --space-char: 65ch;
        --text-1: clamp(1.75rem, 1.5rem + 1.1vw, 2.25rem);
        --text-2: clamp(1.5rem, 1.3rem + 0.8vw, 1.875rem);
        --text-3: clamp(1.25rem, 1.1rem + 0.5vw, 1.5rem);
        --text-4: clamp(1.125rem, 1.05rem + 0.3vw, 1.25rem);
        --text-5: 1.125rem;
        --text-6: 1rem;
        --text-7: 0.875rem;
        --text-8: 0.75rem;
        --text-9: 0.625rem;
        --text-10: 0.5rem;
        --text-11: 0.375rem;
        --text-12: 0.25rem;
        --radius-small: 0.125rem;
        --radius-medium: 0.375rem;
        --radius-large: 0.75rem;
        --radius-full: 9999px;

        /* Max widths */
        --width-sm: 640px;
        --width-md: 768px;
        --width-lg: 1120px;
        --width-sidebar: 25ch;
        --width-avatar: 200px;
        --sz: var(--width-avatar);

        /* Fonts */
        --font-text: var(--font-nunito-sans), system-ui, sans-serif;
        --font-heading: var(--font-inter), system-ui, sans-serif;
        --font-mono: var(--font-fira-code), ui-monospace, consolas, monospace;
        --leading-small: 1.25;
        --leading-snug: 1.375;
        --leading-normal: 1.5;
        --leading-relaxed: 1.75;
        --font-normal: 450;
        --font-medium: 500;
        --font-semibold: 600;
        --font-bold: 700;
        --text-regular: var(--text-5);
        --transition-fast: 120ms cubic-bezier(0.4, 0, 0.2, 1);
        --transition: 200ms cubic-bezier(0.4, 0, 0.2, 1);
        --color-info: var(--blahaj-info);
        --color-important: var(--blahaj-important);
        --color-warning: var(--blahaj-warning);
        --color-caution: var(--blahaj-caution);
        --color-tip: var(--blahaj-tip);
    }
}

/* ---- defaults ---- */
@layer base {
    * {
        border-color: var(--border);
    }

    body {
        color: var(--foreground);
        background-color: var(--background);
        font-family: var(--font-text);
        font-weight: var(--font-normal);
        font-size: var(--text-regular);
        line-height: var(--leading-normal);
    }

    /* Main layout placement */
    main {
        max-width: var(--width-lg);
        margin-inline: auto;
        padding-inline: var(--space-6);
        display: flex;
        flex-direction: column;
    }

    .site-header {
        max-width: var(--width-lg);
        margin-inline: auto;
        padding-block-start: var(--space-8);
        padding-inline: var(--space-6);
    }

    .sr-only {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }

    h1,
    h2,
    h3,
    h4,
    h5,
    h6 {
        font-family: var(--font-heading);
        font-weight: var(--font-semibold);
        line-height: 1.25;

        &:first-child {
            margin-block-start: 0;
        }
    }

    h1 {
        font-size: var(--text-1);
        margin: var(--space-10) 0 var(--space-6);
    }

    h2 {
        font-size: var(--text-2);
        margin: var(--space-8) 0 var(--space-5);
    }

    h3 {
        font-size: var(--text-3);
        margin: var(--space-6) 0 var(--space-4);
    }

    h4 {
        font-size: var(--text-4);
        margin: var(--space-5) 0 var(--space-3);
    }

    h5 {
        font-size: var(--text-5);
        margin: var(--space-4) 0 var(--space-2);
    }

    h6 {
        font-size: var(--text-regular);
        margin: var(--space-4) 0 var(--space-2);
    }

    p {
        margin-block-end: var(--space-4);

        &:last-child {
            margin-block-end: 0;
        }
    }

    a {
        color: var(--foreground);
        font-weight: var(--font-semibold);
        text-decoration: underline;
        text-decoration-color: var(--primary);
        text-underline-offset: var(--space-1);
        transition: color var(--transition-fast);

        &:hover {
            color: var(--primary);
        }
    }

    :focus-visible {
        outline: 2px solid var(--primary);
        outline-offset: var(--space-half);
    }

    strong,
    b {
        font-weight: var(--font-semibold);
    }

    em,
    i {
        font-style: italic;
    }

    ul,
    ol {
        padding-inline-start: var(--space-6);
        margin-block-end: var(--space-4);
    }

    ul {
        list-style-type: disc;
    }

    li {
        margin-block-end: var(--space-1);
    }

    ul li:not(:last-child) {
        margin-bottom: var(--space-2);
    }

    ol {
        list-style-type: decimal;
    }

    svg,
    img,
    video {
        max-width: 100%;
        height: auto;
    }

    figure > img,
    figure > svg {
        margin-inline: auto;
    }

    .katex-display {
        overflow: auto hidden;
        height: auto;
        padding-top: 0.1rem;
        padding-bottom: 0.1rem;
    }

    .katex * {
        display: inherit;
        width: initial;
        height: initial;
    }

    .katex svg {
        display: inline;
    }

    kbd {
        box-shadow:
            0 0 0 1px var(--border),
            0 3px 0 var(--border);
        border-radius: var(--radius-medium);
        padding: var(--space-1);
        font-family: var(--font-mono);
        font-size: var(--text-6);
    }
}

/* ---- prose ---- */
@layer components {
    .prose {
        max-width: var(--space-char);

        p,
        h1,
        h2,
        h3,
        h4,
        h5,
        h6,
        figure,
        blockquote,
        pre,
        ul,
        table,
        aside {
            margin-bottom: var(--space-4);
        }

        h2 {
            line-height: var(--leading-snug);
            font-weight: var(--font-bold);
        }

        h2:not(:first-child) {
            margin-top: var(--space-10);
        }

        h3:not(:first-child) {
            margin-top: var(--space-8);
        }

        h4:not(:first-child) {
            margin-top: var(--space-6);
        }

        h5:not(:first-child) {
            margin-top: var(--space-4);
        }

        blockquote {
            padding-inline-start: var(--space-4);
            margin-top: var(--space-6);
            margin-bottom: var(--space-6);
            border-left: 4px solid var(--primary);

            p {
                font-style: italic;
            }
        }

        blockquote > :first-child::before {
            content: open-quote;
        }

        blockquote > :last-child::after {
            content: close-quote;
        }

        li {
            padding-inline-start: var(--space-2);
        }

        strong,
        b {
            font-weight: var(--font-bold);
        }

        em,
        i {
            font-style: italic;
        }

        code {
            font-family: var(--font-mono);
            font-weight: var(--font-semibold);
            font-size: var(--text-7);
        }

        kbd {
            font-variant-ligatures: none;
        }

        :not(pre) > code {
            font-weight: var(--font-medium);
            background-color: color-mix(in srgb, var(--primary) 20%, transparent);
            padding: var(--space-half) var(--space-1);
            border-radius: var(--radius-medium);
            overflow-wrap: break-word;
        }

        a:has(code) {
            text-decoration-color: var(--primary);
        }

        pre > code .ec-line {
            max-height: var(--space-5) !important;
        }

        svg,
        img,
        video {
            border-radius: var(--radius-medium);
        }

        figure:not(.lumis-figure) {
            @media (width >= 110ch) {
                margin-inline: auto;
                max-width: 75%;
            }
        }


        figure > img,
        figure > svg {
            margin-bottom: var(--space-4);
        }

        figure > figcaption {
            font-size: var(--text-6);
            color: var(--muted);
            text-align: center;
        }

        sup {
            white-space: nowrap;
            unicode-bidi: isolate;
            font-size: var(--text-7);

            a.footnote-ref {
                display: inline-block;
                text-decoration: none;
            }

            a.footnote-ref::before {
                content: "[";
            }

            a.footnote-ref::after {
                content: "]";
            }
        }

        table {
            width: 100%;
            border-collapse: collapse;
            /* A collapsed border never takes the radius, and the header bar and
               the cell borders would paint over the corners of the table, so
               the radius only shows once the content of the table is clipped.
               The frame of the table is the ring below: a border on the table
               or on a cell is drawn as a straight line and would be clipped
               mid-corner, leaving the arc of the corner unjoined. */
            border-radius: var(--radius-medium);
            overflow: hidden;
            box-shadow: 0 0 0 1px var(--border);
            font-size: var(--text-7);
            font-weight: var(--font-medium);
            
            code,
            p {
                font-size: inherit;
            }

            thead {
                background-color: var(--surface);
                border-bottom: 1px solid var(--border-subtle);
            }

            th {
                padding-inline: var(--space-2);
                padding-block: var(--space-2);
                text-align: center;
                vertical-align: middle;

                img {
                    margin-block: 0;
                }
            }

            td {
                padding-inline: var(--space-2);
                padding-block: var(--space-2);
                border-bottom: 1px solid var(--border-subtle);
            }

            /* The ring closes the table: the separator of the last row would
               sit one pixel inside it and read as a double line. */
            tbody tr:last-child td {
                border-bottom: 0;
            }
        }
    }
}

/* ---- utilities ---- */
@layer utilities {
    .align-left {
        text-align: start;
    }
    .align-center {
        text-align: center;
    }
    .align-right {
        text-align: end;
    }

    .inline {
        display: inline;
    }
    .flex {
        display: flex;
    }
    .inline-flex {
        display: inline-flex;
    }
    .wrap {
        flex-wrap: wrap;
    }
    .flex-col {
        flex-direction: column;
    }
    .items-center {
        align-items: center;
    }
    .items-start {
        align-items: flex-start;
    }
    .items-end {
        align-items: flex-end;
    }
    .items-baseline {
        align-items: baseline;
    }
    .justify-center {
        justify-content: center;
    }
    .justify-between {
        justify-content: space-between;
    }
    .justify-end {
        justify-content: flex-end;
    }

    /* Bootstrap inspired. */
    .hstack {
        display: flex;
        align-items: center;
        gap: var(--space-3);
        flex-wrap: wrap;
        align-content: flex-start;
        height: auto;

        > * {
            margin: 0;
        }
    }

    .vstack {
        display: flex;
        flex-direction: column;
        gap: var(--space-3);
    }

    .gap-1 {
        gap: var(--space-1);
    }
    .gap-2 {
        gap: var(--space-2);
    }
    .gap-4 {
        gap: var(--space-4);
    }
    .gap-6 {
        gap: var(--space-6);
    }
    .gap-8 {
        gap: var(--space-8);
    }

    .mx-auto {
        margin-left: auto;
        margin-right: auto;
    }

    .mt-2 {
        margin-block-start: var(--space-2);
    }
    .mt-4 {
        margin-block-start: var(--space-4);
    }
    .mt-6 {
        margin-block-start: var(--space-6);
    }

    .mb-2 {
        margin-block-end: var(--space-2);
    }
    .mb-4 {
        margin-block-end: var(--space-4);
    }
    .mb-6 {
        margin-block-end: var(--space-6);
    }
    .p-4 {
        padding: var(--space-4);
    }

    :is(ul, ol, a).unstyled {
        list-style: none;
        text-decoration: none;
        padding: 0;
    }

    .hide-md {
        @media (width <= 110ch) {
            display: none !important;
        }
    }

    .sidebar {
        position: sticky;
        top: var(--space-8);
        align-self: flex-start;
        padding-bottom: var(--space-4);
    }

    ul.list-no-decoration,
    .list-no-decoration ul {
        list-style: none;
        padding: 0;
    }

    a.link-no-decoration,
    .link-no-decoration a {
        text-decoration: none;
    }

    .hide-dark {
        display: block;
    }

    .hide-light {
        display: none;
    }

    .dark {
        .hide-dark {
            display: none;
        }

        .hide-light {
            display: block;
        }
    }

    .w-100 {
        width: 100%;
    }
    .w-23 {
        width: 25%;
    }
    .w-50 {
        width: 50%;
    }
    .w-33 {
        width: 33%;
    }

    .image-row p {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: var(--space-4);

        @media (width <= 110ch) {
            grid-template-columns: 100%;
        }
    }
}

/* ---- components: blog ---- */
@layer components {
    .blog-post-hero {
        h1 {
            margin-bottom: var(--space-2);
            text-wrap: auto;
        }
        h1 code {
            display: inline;
        }

        p {
            margin-bottom: 0;
        }

        .blog-post-metadata {
            color: var(--muted);
            font-size: var(--text-6);
        }

        .blog-post-tags {
            color: var(--accent);
        }

        .blog-post-discussion {
            margin-top: var(--space-1);
        }

        .discussion-label {
            color: var(--muted);
            font-size: var(--text-7);
        }

        .discussion-badge {
            --discussion-brand: var(--primary);
            --discussion-on-brand: var(--foreground-inverted);
            display: inline-flex;
            align-items: center;
            gap: var(--space-1);
            padding: 2px var(--space-2);
            min-height: 28px;
            border: 1px solid color-mix(in srgb, var(--discussion-brand) 88%, black);
            border-radius: var(--radius-medium);
            background-color: var(--discussion-brand);
            color: var(--discussion-on-brand);
            font-family: var(--font-heading);
            font-size: var(--text-7);
            font-weight: var(--font-semibold);
            text-decoration: none;
            transition:
                filter var(--transition-fast),
                box-shadow var(--transition-fast);
        }

        .discussion-badge[data-platform="hackernews"] {
            --discussion-brand: #ff6600;
            --discussion-on-brand: var(--blahaj-abyss);
        }

        .discussion-badge[data-platform="reddit"] {
            --discussion-brand: #ff4500;
            --discussion-on-brand: var(--blahaj-abyss);
        }

        .discussion-badge[data-platform="lobsters"] {
            --discussion-brand: #ac130d;
            --discussion-on-brand: var(--blahaj-white);
        }

        .discussion-badge-icon {
            flex: none;
            width: 16px;
            height: 16px;
        }

        .discussion-badge:hover {
            filter: brightness(0.94);
            box-shadow: 0 2px 8px rgb(from var(--discussion-brand) r g b / 0.3);
        }

        .discussion-badge:focus-visible {
            outline: 2px solid var(--discussion-brand);
            outline-offset: 2px;
        }

        .hero-tag {
            display: inline-block;

            .tag-label {
                font-size: var(--text-6);
            }

            .tag-label::before {
                content: "#";
                margin-right: 0;
            }
        }
    }

    .blog-content {
        width: 100%;
    }

    figure.d2 {
        margin-inline: auto;
        max-width: 100% !important;

        svg.d2-svg > rect {
            fill: var(--background) !important;
        }
    }

    .footnotes {
        margin-top: var(--space-10);

        ol {
            margin-top: var(--space-4);
        }
    }
}

/* ---- components: card ---- */
@layer components {
    .card {
        border: 1px solid var(--border-subtle);
        border-radius: var(--radius-large);
        background-color: var(--surface);
    }
}

/* ---- components: blog list ---- */
@layer components {
    .section-posts > h2 {
        margin-bottom: var(--space-4);
    }

    .section-posts .post-preview .post-date {
        color: var(--muted);
        font-family: var(--font-mono);
        font-size: var(--text-7);
        font-variant-numeric: tabular-nums;
    }

    .post-title {
        margin: 0 0 var(--space-1);
        font-family: var(--font-text);
        font-weight: var(--font-semibold);
        font-size: var(--text-4);
    }

    /* The row is a link, but the list is read as text: the title keeps the
       foreground color and only turns link-blue, underlined, on hover. */
    .post-title a {
        font-weight: inherit;
        text-decoration: none;
    }

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

    .section-posts p {
        color: var(--muted);
        font-size: var(--text-7);
    }

    .back-button {
        padding: var(--space-1) var(--space-3);
        border: 1px solid var(--border);
        border-radius: var(--radius-medium);
        background-color: var(--surface);
        color: var(--foreground);
        font-family: var(--font-text);
        font-size: var(--text-7);
        font-weight: var(--font-semibold);
        text-decoration: none;
    }

    .back-button:hover {
        background-color: var(--primary);
        border-color: var(--primary);
        color: var(--foreground-inverted);
    }

    .more-posts {
        display: flex;
        justify-content: flex-end;
    }

    .more-posts-link {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        padding: var(--space-1) var(--space-3);
        border: 1px solid var(--border);
        border-radius: var(--radius-medium);
        color: var(--foreground);
        font-family: var(--font-text);
        font-size: var(--text-7);
        font-weight: var(--font-semibold);
        text-decoration: none;
    }

    .more-posts-link:hover {
        background-color: var(--primary);
        border-color: var(--primary);
        color: var(--foreground-inverted);
    }

    .post-preview {
        display: grid;
        grid-template-columns: 96px minmax(0, 1fr) auto;
        gap: var(--space-4);
        align-items: baseline;
        padding-block: var(--space-4);
        border-bottom: 1px solid var(--border-subtle);
    }

    .post-preview:last-child {
        border-bottom: 0;
    }

    .post-preview-container {
        max-width: var(--space-char);
    }

    @media (max-width: 480px) {
        .post-preview {
            grid-template-columns: minmax(0, 1fr);
            gap: var(--space-1);
        }

        .post-date {
            display: none;
        }
    }

    .post-date-mobile {
        display: none;
        font-family: var(--font-mono);
        font-size: var(--text-7);
        font-variant-numeric: tabular-nums;
    }

    @media (max-width: 480px) {
        .post-date-mobile {
            display: block;
            color: var(--muted);
            margin-top: var(--space-1);
        }
    }

    /* The badge of the depth of a post: three bars, lit up to the level the
       post declares in its `depth` frontmatter. */
    .post-depth {
        display: inline-flex;
        align-self: start;
        justify-self: start;
        align-items: center;
        gap: var(--space-1);
        padding: 3px var(--space-2);
        border: 1.5px solid var(--border);
        border-radius: var(--radius-full);
        color: var(--muted);
        font-family: var(--font-heading);
        font-size: var(--text-8);
        font-weight: var(--font-semibold);
        white-space: nowrap;
    }

    .post-depth i {
        display: inline-flex;
        gap: 2px;
        align-items: flex-end;
    }

    .post-depth b {
        width: 3px;
        height: 5px;
        background-color: var(--border-subtle);
        border-radius: var(--radius-small);
    }

    .post-depth b:nth-child(2) {
        height: 8px;
    }

    .post-depth b:nth-child(3) {
        height: 11px;
    }

    .post-depth[data-depth='shallow'] b:nth-child(1),
    .post-depth[data-depth='mid'] b:nth-child(-n + 2),
    .post-depth[data-depth='deep'] b {
        background-color: var(--accent);
    }
}

@layer components {
    .navbar {
        margin-bottom: var(--space-6);
        font-family: var(--font-heading);
        flex-wrap: wrap;
        row-gap: var(--space-2);

        .navbar-home-link span {
            font-size: var(--text-5);
            font-weight: var(--font-bold);
            line-height: var(--leading-small);
        }

        /* The icons of the bar are sized against the text next to them, not
           against the 32px of their own file. */
        .navbar-home-link img {
            width: 28px;
            height: 28px;
        }

        /* The same half-filled circle as the website preview, sized for the
           bar. The button keeps a 24px target even though the mark is small. */
        #toggleDarkMode {
            display: grid;
            flex: none;
            place-items: center;
            width: 32px;
            height: 32px;
            padding: 0;
            border: 1px solid var(--border);
            border-radius: var(--radius-full);
            background-color: var(--surface-raised);
            color: var(--muted);
            transition:
                color var(--transition-fast),
                border-color var(--transition-fast);
        }

        #toggleDarkMode:hover {
            border-color: var(--primary);
            color: var(--primary);
        }

        .theme-switcher-icon {
            display: block;
            width: 18px;
            height: 18px;
            border: 1px solid currentColor;
            border-radius: var(--radius-full);
            background: linear-gradient(
                90deg,
                currentColor 50%,
                transparent 50%
            );
        }

        .navbar-secondary-links {
            margin-left: auto;
            a {
                font-size: var(--text-6);
                font-weight: var(--font-semibold);
                line-height: calc(var(--leading-small) * var(--text-5));
            }
        }

        .navbar-links {
            display: flex;
            align-items: center;
            gap: var(--space-4);
        }

        .navbar-menu-toggle {
            display: none;
            align-items: center;
            justify-content: center;
            padding: var(--space-1);
            border: none;
            background: none;
            color: var(--foreground);
            cursor: pointer;

            svg {
                width: 22px;
                height: 22px;
            }
        }

        /* On phones the links fold into a small menu under the bar, instead of
           wrapping the bar onto a second row. */
        @media (max-width: 560px) {
            .navbar-secondary-links {
                position: relative;
            }

            .navbar-links {
                position: absolute;
                top: calc(100% + var(--space-2));
                right: 0;
                z-index: 10;
                display: none;
                flex-direction: column;
                align-items: stretch;
                gap: var(--space-half);
                min-width: 12rem;
                padding: var(--space-2);
                border: 1px solid var(--border-subtle);
                border-radius: var(--radius-large);
                background-color: var(--surface);
                box-shadow: 0 10px 24px rgb(from var(--foreground) r g b / 0.14);

                &[data-open='true'] {
                    display: flex;
                }

                a {
                    padding: var(--space-2) var(--space-3);
                    border-radius: var(--radius-medium);
                }

                a:hover {
                    background-color: var(--background);
                }
            }

            .navbar-menu-toggle {
                display: inline-flex;
            }
        }
    }

    /* The bare `footer` selector is qualified with
       .site-footer so it cannot leak into page content. */
    .site-footer {
        max-width: calc(var(--width-lg) - 2 * var(--space-6));
        width: calc(100% - 2 * var(--space-6));
        margin-top: var(--space-8);
        margin-inline: auto;
        font-size: var(--text-7);
        color: var(--muted);
        border-top: 1px solid var(--border-subtle);
        padding-top: var(--space-4);
        padding-bottom: var(--space-4);

        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        row-gap: var(--space-3);
    }

    .footer-attributions {
        @media (max-width: 768px) {
            text-align: center;
            width: 100%;
        }
    }

    .footer-socials {
        margin-left: auto;

        @media (max-width: 768px) {
            margin-inline: auto;
        }

        /* The icons of this row are sized here, not in their file: the header
           shows the same ones at another size */
        svg {
            width: 24px;
        }
    }

    .social-connection {
        line-height: var(--leading-snug);
    }

    .social-connection a {
        font-weight: var(--font-normal);
    }
}

/* ---- tooltips ---- */
@layer components {
    /* A small label for an icon-only control. Native title tooltips cannot
       take the palette, so the scripts write a data-tooltip instead. It sits
       below the control by default, and above controls at the bottom of a
       block. */
    [data-tooltip] {
        position: relative;
    }

    [data-tooltip]::after {
        content: attr(data-tooltip);
        position: absolute;
        top: calc(100% + var(--space-2));
        right: 0;
        z-index: 30;
        padding: var(--space-1) var(--space-2);
        border: 1px solid var(--border);
        border-radius: var(--radius-medium);
        background-color: var(--surface-raised);
        color: var(--foreground);
        box-shadow: 0 8px 24px var(--shadow);
        font-family: var(--font-text);
        font-size: var(--text-8);
        font-weight: var(--font-semibold);
        line-height: var(--leading-small);
        white-space: nowrap;
        opacity: 0;
        pointer-events: none;
        transform: translateY(calc(-1 * var(--space-half)));
        transition:
            opacity var(--transition-fast),
            transform var(--transition-fast);
    }

    [data-tooltip]:focus-visible::after {
        opacity: 1;
        transform: translateY(0);
    }

    @media (hover: hover) {
        [data-tooltip]:hover::after {
            opacity: 1;
            transform: translateY(0);
        }
    }

    /* The expand button sits at the bottom of its block, so its label goes
       above it rather than off the page. */
    .lumis-expand[data-tooltip]::after {
        top: auto;
        bottom: calc(100% + var(--space-2));
        transform: translateY(var(--space-half));
    }

    @media (hover: hover) {
        .lumis-expand[data-tooltip]:hover::after {
            transform: translateY(0);
        }
    }

    .lumis-expand[data-tooltip]:focus-visible::after {
        transform: translateY(0);
    }
}

/* ---- tall code blocks ---- */
@layer components {
    /* A code block which is taller than the window scrolls in its own frame,
       so that the text below it stays near. lumis.js adds the class to a block
       it measures as too tall. */
    .lumis-collapsible > pre.lumis {
        max-height: 60vh;
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    /* A reader who asked to see the whole block gets it. */
    .lumis-expanded > pre.lumis {
        max-height: none;
    }

    /* The button which shows the block whole, or folds it back. It holds one
       icon and sits in the bottom right corner of the block, as the copy
       button sits in its top right corner, and it takes no room of its own. */
    .lumis-expand {
        position: absolute;
        right: var(--space-2);
        bottom: var(--space-2);
        display: flex;
        align-items: center;
        justify-content: center;
        width: 1.75rem;
        height: 1.75rem;
        padding: 0;
        border: 0;
        border-radius: var(--radius-medium);
        background-color: var(--background);
        box-shadow: inset 0 0 0 1px var(--border);
        color: var(--muted);
        cursor: pointer;
    }

    .lumis-expand > svg {
        width: 1rem;
        height: 1rem;
    }

    .lumis-expand:hover {
        color: var(--foreground);
    }

    .lumis-expand:focus-visible {
        outline: 2px solid var(--primary);
        outline-offset: 2px;
    }
}

/* ---- code tabs ---- */
@layer components {
    /* A row of tabs above a group of code blocks, which the script of the page
       writes into a `div.code-tabs`. Nothing here hides a block: a reader with
       no script sees every block of the group. */
    .code-tabs-nav {
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-1);
    }

    .code-tabs-nav > [role="tab"] {
        padding: var(--space-1) var(--space-3);
        border: 1px solid transparent;
        border-radius: var(--radius-medium);
        background-color: transparent;
        color: var(--muted);
        font-family: var(--font-mono);
        font-size: var(--text-8);
        font-weight: var(--font-semibold);
        line-height: var(--leading-small);
        cursor: pointer;
        transition:
            color var(--transition-fast),
            background-color var(--transition-fast),
            border-color var(--transition-fast);
    }

    .code-tabs-nav > [role="tab"]:hover {
        color: var(--foreground);
    }

    /* The open tab reads as a key of the block below it, rather than as a
       word of the row. */
    .code-tabs-nav > [role="tab"][aria-selected="true"] {
        border-color: var(--border);
        background-color: var(--surface);
        color: var(--foreground);
    }

    .code-tabs-nav > [role="tab"]:focus-visible {
        outline: 2px solid var(--primary);
        outline-offset: 2px;
    }
}

/* A block follows its row of tabs closely, rather than at the room a block
   takes from the text. The frame of a block is written by lumis.css, which
   sits outside the layers of this file, so this rule sits outside them too, at
   a weight which wins over it. */
.code-tabs > :is(.lumis-figure, .lumis-block, pre.lumis) {
    margin-top: var(--space-2);
}

/* A theme marks keywords bold, and lumis writes that weight into the style
   attribute of the token, so only an important rule can soften it. Fira Code
   is a variable font: 500 is one step above the 400 of the code, which keeps
   the keywords apart without the blot of the 700 the theme asks for. */
pre.lumis span[style*="font-weight"] {
    font-weight: 500 !important;
}

html[data-theme="dark"] .prose .svg-invert, html.dark .prose .svg-invert {
    filter: invert(1);
}

/* The theme switch. View Transitions keeps a snapshot of the old page and
   paints the new one over it; clipping the new snapshot with a moving wave
   makes the new theme wash in. Light yields to dark with a wave rising from
   the bottom, and dark yields to light with one falling from the top. The
   polygon points are a three-cycle sine, sampled so the edge stays smooth
   when it is interpolated. A clip-path animation runs on the compositor,
   unlike a colour transition on every element of the page. */
::view-transition-old(root),
::view-transition-new(root) {
    mix-blend-mode: normal;
}

::view-transition-old(root) {
    animation: none;
}

::view-transition-new(root) {
    animation: theme-wave-up 800ms cubic-bezier(0.65, 0, 0.35, 1) both;
}

:root[data-theme="light"]::view-transition-new(root) {
    animation-name: theme-wave-down;
}

@keyframes theme-wave-up {
    from {
        clip-path: polygon(
            0% 100%, 0% 104%, 4.17% 106.12%, 8.33% 107%, 12.5% 106.12%,
            16.67% 104%, 20.83% 101.88%, 25% 101%, 29.17% 101.88%, 33.33% 104%,
            37.5% 106.12%, 41.67% 107%, 45.83% 106.12%, 50% 104%,
            54.17% 101.88%, 58.33% 101%, 62.5% 101.88%, 66.67% 104%,
            70.83% 106.12%, 75% 107%, 79.17% 106.12%, 83.33% 104%,
            87.5% 101.88%, 91.67% 101%, 95.83% 101.88%, 100% 104%, 100% 100%
        );
    }
    to {
        clip-path: polygon(
            0% 100%, 0% -6%, 4.17% -3.88%, 8.33% -3%, 12.5% -3.88%,
            16.67% -6%, 20.83% -8.12%, 25% -9%, 29.17% -8.12%, 33.33% -6%,
            37.5% -3.88%, 41.67% -3%, 45.83% -3.88%, 50% -6%, 54.17% -8.12%,
            58.33% -9%, 62.5% -8.12%, 66.67% -6%, 70.83% -3.88%, 75% -3%,
            79.17% -3.88%, 83.33% -6%, 87.5% -8.12%, 91.67% -9%,
            95.83% -8.12%, 100% -6%, 100% 100%
        );
    }
}

@keyframes theme-wave-down {
    from {
        clip-path: polygon(
            0% 0%, 0% -6%, 4.17% -3.88%, 8.33% -3%, 12.5% -3.88%,
            16.67% -6%, 20.83% -8.12%, 25% -9%, 29.17% -8.12%, 33.33% -6%,
            37.5% -3.88%, 41.67% -3%, 45.83% -3.88%, 50% -6%, 54.17% -8.12%,
            58.33% -9%, 62.5% -8.12%, 66.67% -6%, 70.83% -3.88%, 75% -3%,
            79.17% -3.88%, 83.33% -6%, 87.5% -8.12%, 91.67% -9%,
            95.83% -8.12%, 100% -6%, 100% 0%
        );
    }
    to {
        clip-path: polygon(
            0% 0%, 0% 104%, 4.17% 106.12%, 8.33% 107%, 12.5% 106.12%,
            16.67% 104%, 20.83% 101.88%, 25% 101%, 29.17% 101.88%, 33.33% 104%,
            37.5% 106.12%, 41.67% 107%, 45.83% 106.12%, 50% 104%,
            54.17% 101.88%, 58.33% 101%, 62.5% 101.88%, 66.67% 104%,
            70.83% 106.12%, 75% 107%, 79.17% 106.12%, 83.33% 104%,
            87.5% 101.88%, 91.67% 101%, 95.83% 101.88%, 100% 104%, 100% 0%
        );
    }
}

@media (prefers-reduced-motion: reduce) {
    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation: none;
    }
}
