:root {
    color-scheme: light dark;
    --content-gap: 15px;
    --radius: 3px;
    --article-max-width: 56rem;
    --page-gutter: clamp(0.75rem, 3vw, 2rem);
    --bar-height: 3.6rem;
    /* The article's text size and its page title size. The top bar sits outside
     * the article, so it needs the same values spelled out to match them.
     */
    --article-font-size: clamp(1rem, calc(0.96rem + 0.2vw), 1.08rem);
    --page-title-size: clamp(
        calc(1.5 * var(--article-font-size)),
        3vw,
        calc(1.8 * var(--article-font-size))
    );
    --text-font-family: "Libertinus Serif", "Noto Serif SC", "Noto Serif CJK SC", "Source Han Serif SC", "Songti SC", "SimSun", serif;
    --ui-font-family: "Inria Sans", "Noto Sans SC", "Noto Sans CJK SC", sans-serif;
    --code-font-family: "Iosevka", "JetBrains Mono", "SFMono-Regular", Consolas, monospace;

    --text-color: #292925;
    --background-color: #fdfcf9;
    --background-color-pre: rgba(60, 60, 50, 0.04);
    --background-color-code: rgba(60, 60, 50, 0.045);
    --rule-color: rgba(60, 60, 50, 0.16);
    --hover-bar-color: rgba(60, 60, 50, 0.2);
    --hover-color-link: rgba(60, 85, 115, 0.07);
    --target-color: #526b8e;
    --link-color: #292925;
    --slug-color: #75756e;
    --logo-color: #63635d;
    --logo-hover-color: #292925;
    --span-taxon-color: #575750;
    --article-taxon-color: #75756e;
    --mark-color: #f2e8b7;
    --auto-filter: none;
}

@media (prefers-color-scheme: dark) {
    :root {
        --text-color: #e0dfd8;
        --background-color: #242523;
        --background-color-pre: rgba(200, 200, 180, 0.055);
        --background-color-code: rgba(200, 200, 180, 0.07);
        --rule-color: rgba(220, 220, 200, 0.17);
        --hover-bar-color: rgba(220, 220, 200, 0.24);
        --hover-color-link: rgba(150, 175, 200, 0.12);
        --target-color: #a8bfdc;
        --link-color: #e0dfd8;
        --slug-color: #aaa99f;
        --logo-color: #aaa99f;
        --logo-hover-color: #e0dfd8;
        --span-taxon-color: #c1c0b7;
        --article-taxon-color: #aaa99f;
        --mark-color: #655b2b;
        --auto-filter: invert(100%);
    }
}

html {
    font-size: 18px;
}

body {
    box-sizing: border-box;
    width: calc(100% - 2 * var(--page-gutter));
    max-width: var(--article-max-width);
    margin: calc(var(--bar-height) + clamp(1rem, 3vw, 2.25rem)) auto 4rem;
    background-color: var(--background-color);
    color: var(--text-color);
    font-family: var(--text-font-family);
    font-optical-sizing: auto;
    line-height: 1.82;
    hyphens: manual;
    overflow-wrap: anywhere;
    word-break: normal;
    -webkit-text-size-adjust: 100%;
}

#grid-wrapper > article {
    min-width: 0;
    max-width: 100%;
    font-size: var(--article-font-size);
}

p {
    margin: 0 0 1em;
    text-wrap: pretty;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    margin: 1.5em 0 0.55em;
    font-family: var(--text-font-family);
    font-weight: 600;
    line-height: 1.45;
    text-wrap: balance;
}

h1 { font-size: 1.7em; }
h2 { font-size: 1.35em; }
h3 { font-size: 1.18em; }
h4,
h5,
h6 { font-size: 1em; }

pre,
code {
    font-family: var(--code-font-family);
    font-optical-sizing: auto;
    hyphens: none;
}

article code {
    font-size: 0.82em;
}

article pre {
    box-sizing: border-box;
    max-width: 100%;
    margin: 0 0 1em;
    padding: 0.8em 1em;
    border: 1px solid var(--rule-color);
    border-radius: var(--radius);
    background-color: var(--background-color-pre);
    font-size: 0.82em;
    line-height: 1.65;
    white-space: pre;
    overflow-x: auto;
    overflow-wrap: normal;
    tab-size: 4;
}

article pre code {
    font-size: inherit;
}

/* An indivisible inline formula may be wider than a phone. Scroll its
 * wrapper, never the paragraph or the whole reading column.
 */
article span:has(> math:not([display="block"])) {
    display: inline-block;
    max-width: 100%;
    overflow-x: auto;
    vertical-align: baseline;
}

/* Scrolling this wrapper moves its baseline to the bottom margin edge, which
 * pushes the formula below the surrounding text. Prefer the first line's
 * baseline and leave room so tall ink is neither clipped nor scrolled.
 */
@supports (baseline-source: first) {
    article span:has(> math:not([display="block"])) {
        baseline-source: first;
        overflow-y: hidden;
        padding-block: 0.3em;
        margin-block: -0.3em;
    }
}

/* Non-math inline SVG demos also keep their own scroll area. Mathematical
 * SVGs and figures already have purpose-specific wrappers.
 */
article .auto-sized-svg:not(.math-visual *, .formal-figure *) {
    max-width: 100%;
    overflow-x: auto;
}

article .auto-filter:has(> .auto-sized-svg):not(.math-visual *, .formal-figure *) {
    max-width: 100%;
}

/* Diagrams that should shrink to the reading column instead of scrolling. */
article .svg-fit .auto-sized-svg {
    overflow: visible;
}

article .svg-fit .auto-sized-svg > svg {
    max-width: 100%;
    height: auto !important;
}

.formal-figure {
    max-width: 100%;
    margin: 1.4em 0;
    overflow-x: auto;
    text-align: center;
}

/* Typst sets a fixed width and height in em on the figure's SVG. Let it
 * shrink to the reading column first, keeping its aspect ratio through the
 * viewBox; the wrapper above still scrolls if it cannot.
 */
.formal-figure :is(.auto-filter, .auto-sized-svg) {
    max-width: 100%;
}

.formal-figure svg[viewBox] {
    max-width: 100%;
    height: auto !important;
}

article math[display="block"] {
    margin: 1em 0;
    max-width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
}

ul,
ol {
    margin: 0;
}

article ul,
article ol {
    margin-bottom: 1em;
    padding-inline-start: 1.5em;
}

article li + li {
    margin-top: 0.3em;
}

article li > ul,
article li > ol {
    margin-top: 0.3em;
    margin-bottom: 0;
}

table {
    display: block;
    max-width: 100%;
    margin: 1em 0 1.4em;
    border-collapse: collapse;
    overflow-x: auto;
    text-align: left;
    line-height: 1.65;
}

th,
td {
    padding: 0.4em 0.8em;
    border-bottom: 1px solid var(--rule-color);
    vertical-align: top;
}

th {
    font-weight: 600;
}

thead {
    border-top: 1px solid var(--text-color);
    border-bottom: 1px solid var(--text-color);
}

.auto-filter svg {
    filter: var(--auto-filter);
}

.footnote-definition {
    font-size: 0.88em;
    line-height: 1.65;
}

.footnote-definition:last-child {
    margin-bottom: 1em;
}

.footnote-definition > p {
    display: inline;
}

.footnote-definition-label {
    margin-right: 0.3em;
}

.footnote-reference:target,
.footnote-definition:target > .footnote-definition-label {
    outline: 1px solid var(--target-color);
}

.svg-footnote-reference:target .target-highlight {
    stroke: var(--target-color);
    stroke-width: 1;
}

.display-none {
    display: none;
}

/* Upright CJK quotations keep their letterforms, with a quiet marginal rule. */
blockquote {
    margin: 1.2em 0 1.2em 0.8em;
    padding: 0.1em 0 0.1em 1em;
    border-left: 2px solid var(--rule-color);
    color: var(--text-color);
    font-size: 0.96em;
    font-style: normal;
    unicode-bidi: isolate;
}

blockquote > p:last-child {
    margin-bottom: 0;
}

details > summary {
    position: relative;
    margin-bottom: 0.45em;
    outline: none;
    list-style: none;
    line-height: 1.55;
    cursor: pointer;
}

details > summary:focus-visible {
    outline: 2px solid var(--target-color);
    outline-offset: 3px;
    border-radius: var(--radius);
}

details > summary > header {
    display: inline;
}

details > summary::marker,
details > summary::-webkit-details-marker {
    display: none;
}

details h1 {
    display: inline;
    font-size: 1.15em;
}

.section-heading {
    font-size: 1.12em;
    font-weight: 600;
}

/* Collection introductions remain visible while their contents are folded. */
.section-description {
    margin: 0.55em 0 1.2em;
    color: var(--slug-color);
    font-family: var(--text-font-family);
    font-size: 0.92em;
    font-weight: 400;
    line-height: 1.75;
    text-wrap: pretty;
}

.section-description:empty {
    display: none;
}

article .embed > details > summary > .section-description {
    margin: 0.55em 0 0.15em;
    font-size: 0.85em;
}

/* Punctuation is visual only: JS continues to read native numeric counters. */
.heading-numbering:not(:empty) {
    font-variant-numeric: lining-nums tabular-nums;
    white-space: nowrap;
}

.heading-numbering:not(:empty)::after {
    content: ".";
}

/* An unnumbered heading still carries its anchor id here, and the table of
 * contents jumps to it. display: none would leave the anchor without a box
 * to scroll to, so keep it as a zero-size, out-of-flow element instead.
 */
.heading-numbering:empty {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
    pointer-events: none;
}

span.taxon {
    color: var(--span-taxon-color);
    font-weight: 600;
}

.taxon[data-taxon=""] {
    display: none;
}

header .metadata {
    display: none;
}

header[show-metadata="true"] .metadata {
    display: block;
}

.page-root > details > summary > .top-header {
    display: block;
    margin-bottom: 1.15em;
    padding-bottom: 0.7em;
    border-bottom: 1px solid var(--rule-color);
}

.top-header > h1 {
    font-size: var(--page-title-size);
}

.top-header > h1 > .taxon {
    color: var(--article-taxon-color);
}

section.block > details {
    margin-bottom: 0.45em;
}

section.block > details[open] {
    margin-bottom: 1.1em;
}

.link-list > section.block > details {
    margin-bottom: 0.3em;
}

.block {
    box-sizing: border-box;
    width: 100%;
    padding: 0 0.35em 0.1em 0.65em;
    border-left: 2px solid transparent;
    transition: border-color 0.15s ease;
    min-width: 0;
}

.page-root {
    padding: 0;
    border-left: 0;
}

@media (hover: hover) {
    .block:hover:not(.page-root, :has(.block:hover)) {
        border-left-color: var(--hover-bar-color);
    }
}

img {
    object-fit: cover;
    max-width: 100%;
    height: auto;
}

/* Embedded objects such as images, videos and frames cannot wrap like text.
 * Whatever size they ask for, they must first fit inside the article's
 * maximum width, keeping their aspect ratio. SVGs generated by Typsite
 * (inline math, auto-sized demos, formal figures) already have wrappers
 * that shrink or scroll them, so they are left to those rules.
 */
article :is(img, picture, video, canvas, iframe, object, embed) {
    box-sizing: border-box;
    max-width: 100%;
}

article :is(img, video, canvas) {
    height: auto;
}

/* A bare SVG that is not inside one of those wrappers follows the same rule. */
article svg:not(.auto-sized-svg *, .math-inline *, .math-block *, .formal-figure *, .math-visual *) {
    max-width: 100%;
}

article svg[viewBox]:not(.auto-sized-svg *, .math-inline *, .math-block *, .formal-figure *, .math-visual *) {
    height: auto;
}

figure {
    max-width: 100%;
    margin: 1.4em 0;
    overflow-x: auto;
    text-align: center;
}

figcaption {
    padding: 0.4em 0;
    color: var(--slug-color);
    font-size: 0.88em;
    line-height: 1.6;
}

mark {
    background-color: var(--mark-color);
    color: inherit;
}

hr {
    width: 100%;
    height: 1px;
    margin: 1.5em 0;
    border: 0;
    background-color: var(--rule-color);
}

/* Top bar: a fixed strip with the title of the current page and, except on
 * the root page, a round back button hanging to the left of the title. The
 * title starts at the same place on every page, whether or not there is a
 * button: at the article's left edge, or, on a narrow screen, far enough in to
 * leave room for the button. While the article's own heading is on screen the
 * title stays out of sight; bar-title.js slides it in as that heading scrolls
 * under the bar.
 */
.header {
    --bar-inset: 0.75rem;
    --bar-icon: 2rem;
    --bar-button: 2.2rem;
    --bar-gap: 0.6rem;
    /* Room for the site icon and the back button, which every page reserves
     * so the title starts in the same place with or without the button.
     */
    --bar-title-start: max(
        calc((100% - var(--article-max-width)) / 2),
        calc(var(--bar-inset) + var(--bar-icon) + var(--bar-gap) + var(--bar-button) + var(--bar-gap))
    );
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 8;
    box-sizing: border-box;
    display: flex;
    align-items: stretch;
    height: var(--bar-height);
    padding-inline-start: var(--bar-title-start);
    padding-inline-end: 3.45rem;
    background-color: var(--background-color);
    border-bottom: 1px solid var(--rule-color);
    font-family: var(--ui-font-family);
}

/* Where the browser can blur what is behind it, the bar turns into frosted
 * glass: the article scrolls under it, softened and tinted with the page
 * colour so the title stays readable. There is no rule line; the glass sits on
 * a layer that reaches a little below the bar and fades out with a mask, so
 * the article goes from sharp to blurred without a hard edge. The layer is
 * separate so the fade never touches the title or the buttons. Elsewhere the
 * opaque bar above, with its rule, stays.
 */
@supports (backdrop-filter: blur(1px)) and (background: color-mix(in srgb, red 50%, transparent)) {
    :root {
        --bar-fade: 1.6rem;
    }

    .header {
        background: none;
        border-bottom: 0;
    }

    .header::before {
        content: "";
        position: absolute;
        z-index: -1;
        top: 0;
        left: 0;
        right: 0;
        height: calc(100% + var(--bar-fade));
        background-color: color-mix(in srgb, var(--background-color) 38%, transparent);
        -webkit-backdrop-filter: blur(14px) saturate(1.15);
        backdrop-filter: blur(14px) saturate(1.15);
        -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - var(--bar-fade) - 0.5rem), transparent 100%);
        mask-image: linear-gradient(to bottom, #000 calc(100% - var(--bar-fade) - 0.5rem), transparent 100%);
        pointer-events: none;
    }

    .header .bar-back > a {
        background-color: color-mix(in srgb, var(--background-color) 55%, transparent);
    }

    #grid-wrapper > .toc-button,
    #grid-wrapper > .math-text-toggle {
        background-color: color-mix(in srgb, var(--background-color) 55%, transparent);
        -webkit-backdrop-filter: blur(14px);
        backdrop-filter: blur(14px);
    }
}

/* The site icon sits at the bar's far left edge, with the same inset as the
 * contents button on the right. It links to the author's home page. The icon
 * has no background of its own, so it only gets a focus ring and a hover tint.
 */
.bar-site {
    position: absolute;
    top: 50%;
    left: var(--bar-inset);
    display: block;
    width: var(--bar-icon);
    height: var(--bar-icon);
    border-radius: var(--radius);
    transform: translateY(-50%);
    transition: filter 0.15s ease, transform 0.15s ease;
}

.bar-site > img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

@media (hover: hover) {
    .bar-site:hover {
        filter: brightness(1.1) saturate(1.1);
        transform: translateY(-50%) scale(1.06);
    }
}

.bar-site:focus-visible {
    outline: 2px solid var(--target-color);
    outline-offset: 2px;
}

/* The back button sits right after the site icon, at the bar's far left. The
 * title's start already leaves room for both, so the title never moves for it.
 * It is a round button with only a chevron.
 */
.bar-back {
    position: absolute;
    top: 50%;
    left: calc(var(--bar-inset) + var(--bar-icon) + var(--bar-gap));
    transform: translateY(-50%);
}

.header[parent="false"] .bar-back {
    display: none;
}

.bar-back > a {
    display: grid;
    place-items: center;
    box-sizing: border-box;
    width: var(--bar-button);
    height: var(--bar-button);
    border: 1px solid var(--rule-color);
    border-radius: 50%;
    color: var(--logo-color);
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.bar-back-icon {
    width: 0.5rem;
    height: 0.5rem;
    margin-inline-start: 0.2rem;
    border-left: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
}

/* The parent's title names the link for assistive technology and shows as
 * the tooltip; only the chevron is drawn.
 */
.bar-back-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

@media (hover: hover) {
    .bar-back > a:hover {
        border-color: var(--hover-bar-color);
        background-color: var(--hover-color-link);
        color: var(--logo-hover-color);
    }
}

.bar-back > a:focus-visible {
    outline: 2px solid var(--target-color);
    outline-offset: 2px;
}

/* The bar clips the title, so shifting it down by the bar's height hides it. */
.bar-title {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    margin: 0;
    overflow: hidden;
    color: var(--text-color);
    font-family: var(--text-font-family);
    font-size: var(--page-title-size);
    font-weight: 600;
    line-height: 1.3;
}

.bar-title-text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* A halo in the page colour keeps glyphs apart from text blurred behind. */
    text-shadow:
        0 0 0.18em var(--background-color),
        0 0 0.4em var(--background-color),
        0 0 0.8em var(--background-color);
    transform: translateY(var(--bar-title-shift, var(--bar-height)));
    will-change: transform;
}

/* A title may carry links or emphasis; in the bar it is only a label. These
 * selectors are deliberately specific: the link rules further down underline
 * .link.external and dot-underline .link.local.
 */
.bar-title .bar-title-text :is(a, .link, .link *) {
    color: inherit;
    text-decoration: none;
    box-shadow: none;
    border-bottom: 0;
    background: none;
}

.bar-title .bar-title-text :is(a, strong, em, span) {
    font: inherit;
}

/* Without scripts nothing would ever slide the title in, so just show it. */
@media (scripting: none) {
    .bar-title-text { transform: none; }
}

.metadata {
    color: var(--slug-color);
    font-size: 0.78em;
    font-weight: 400;
    line-height: 1.6;
    font-variant-numeric: lining-nums tabular-nums;
}

.top-header .metadata {
    margin-top: 0.6em;
    font-size: 0.82em;
}

.metadata ul {
    display: inline;
    margin: 0;
    padding-inline-start: 0;
}

.metadata li {
    margin-top: 0;
}

.metadata li::after {
    content: " · ";
}

.metadata li:last-child::after {
    content: "";
}

.metadata * {
    display: inline;
}

.link {
    cursor: pointer;
}

a {
    color: var(--link-color);
    text-decoration: inherit;
    text-underline-offset: 0.2em;
    text-decoration-thickness: 1px;
}

a:focus-visible {
    outline: 2px solid var(--target-color);
    outline-offset: 2px;
}

@media (hover: hover) {
    a.slug:hover,
    .edit-button:hover,
    .link:hover,
    a.backlink-link:hover,
    a.reference-link:hover {
        background-color: var(--hover-color-link);
    }
}

.svg-link:hover {
    filter: invert(100%);
    fill: var(--hover-color-link);
    fill-opacity: 1;
}

.link.external {
    text-decoration: underline;
}

span.link.local,
.link.local span,
a.slug,
a.backlink-link,
a.reference-link {
    box-shadow: none;
    text-decoration-line: underline;
    text-decoration-style: dotted;
    text-underline-offset: 0.2em;
    text-decoration-thickness: 1px;
}

p.backlink,
p.reference {
    margin-bottom: 0.4em;
}

a.backlink-link .backlink-slug,
a.reference-link .reference-slug,
.slug,
.doi,
.orcid {
    color: var(--slug-color);
    font-weight: 400;
}

.page-footer {
    margin-top: 2.2em;
    padding-top: 1em;
    border-top: 1px solid var(--rule-color);
    font-size: 0.88em;
}

.page-footer > section {
    margin-bottom: 1em;
}

.colophon {
    margin-top: 1.5em;
    color: var(--slug-color);
    font-size: 0.88em;
}

/* Keep the existing CSS-only TOC drawer: opening it never narrows the prose. */
#grid-wrapper[sidebar="false"] > :is(nav, .toc-toggle, .toc-button) {
    display: none;
}

.toc-toggle,
.toc-button {
    position: fixed;
    top: calc((var(--bar-height) - 2.2rem) / 2);
    right: 0.75rem;
    box-sizing: border-box;
    width: 2.2rem;
    height: 2.2rem;
    margin: 0;
}

.toc-toggle {
    z-index: 11;
    border-radius: 50%;
    opacity: 0;
    cursor: pointer;
}

.toc-button {
    z-index: 10;
    display: grid;
    place-items: center;
    border: 1px solid var(--rule-color);
    border-radius: 50%;
    background: var(--background-color);
    color: var(--text-color);
    font-family: var(--ui-font-family);
    font-size: 1.1rem;
    line-height: 1;
    pointer-events: none;
    transition: background-color 0.15s ease;
}

.toc-button::before {
    content: "\2630";
}

.toc-toggle:checked ~ .toc-button::before {
    content: "\2715";
}

@media (hover: hover) {
    .toc-toggle:hover + .toc-button {
        background-color: var(--hover-color-link);
    }
}

.toc-toggle:focus-visible + .toc-button {
    outline: 2px solid var(--target-color);
    outline-offset: 2px;
}

#grid-wrapper > nav {
    position: fixed;
    top: var(--bar-height);
    right: 0;
    bottom: 0;
    z-index: 7;
    box-sizing: border-box;
    width: max-content;
    max-width: 100vw;
    /* The bar's glass fades out over the first --bar-fade below it. */
    padding: calc(1.25rem + var(--bar-fade, 0px)) 1.25rem 1.5rem;
    /* Keep the shadow on the left; it must not spill onto the bar above. */
    clip-path: inset(0 0 0 -24px);
    overflow: auto;
    background: var(--background-color);
    border-left: 1px solid var(--rule-color);
    box-shadow: -4px 0 16px rgba(0, 0, 0, 0.08);
    font-size: 0.88rem;
    line-height: 1.65;
    transform: translateX(100%);
    visibility: hidden;
    transition: transform 0.2s ease, visibility 0s linear 0.2s;
}

#grid-wrapper > .toc-toggle:checked ~ nav {
    transform: none;
    visibility: visible;
    transition: transform 0.2s ease, visibility 0s;
}

#grid-wrapper > nav * {
    white-space: nowrap;
    overflow-wrap: normal;
}

@media (max-width: 500px) {
    html { font-size: 16px; }
    .block { padding-inline: 0.45em 0.15em; }
    .page-root { padding: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .block,
    .toc-button,
    #grid-wrapper > nav,
    #grid-wrapper > .toc-toggle:checked ~ nav {
        transition: none;
    }
}

@media print {
    :root {
        color-scheme: light;
        --text-color: #000;
        --link-color: #000;
        --background-color: #fff;
        --slug-color: #555;
        --rule-color: #ccc;
        --auto-filter: none;
    }
    html { font-size: 11pt; }
    body { width: 100%; max-width: none; margin: 0; }
    #grid-wrapper > article { font-size: 1rem; }
    .header,
    .toc-toggle,
    .toc-button,
    #grid-wrapper > nav,
    .colophon { display: none; }
    .block { transition: none; }
    /* Always print the light code variant, even from a dark-mode browser. */
    article pre[color-scheme="light"] { display: block; }
    article code[color-scheme="light"] { display: inline; }
    article :is(pre, code)[color-scheme="dark"] { display: none; }
    p { orphans: 3; widows: 3; }
    summary { break-after: avoid; }
    pre,
    figure { break-inside: avoid; }
}
