:root {
    --color-bg: #fafafa;
    --color-bg-alt: #ffffff;
    --color-text: #1a1a1a;
    --color-text-muted: #666666;
    --color-accent: #17325c;
    --color-accent-light: #2a4f87;
    /* Links are their own navy, lighter than the accent used for headings and
       buttons. At #17325c against #1a1a1a text a link was near enough to black
       that it read as emphasis rather than as something to click. */
    --color-link: #1f4f9c;
    --color-link-hover: #3170cc;
    --color-border: #e5e5e5;
    --font-serif: 'EB Garamond', Garamond, 'Adobe Garamond Pro', Georgia, 'Times New Roman', serif;
    --max-width: 1200px;
    --spacing-xs: 0.5rem;
    --spacing-sm: 1rem;
    --spacing-md: 2rem;
    --spacing-lg: 4rem;
    --spacing-xl: 6rem;
    --transition: 0.3s ease;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: var(--font-serif);
    font-size: 18px;
    line-height: 1.65;
    color: var(--color-text);
    background-color: var(--color-bg);
}

h1,
h2,
h3,
h4,
h5,
h6 {
    font-family: var(--font-serif);
    font-weight: 500;
    line-height: 1.3;
}

h1 {
    font-size: 3rem;
}

h2 {
    font-size: 2.25rem;
    margin-bottom: var(--spacing-md);
}

h3 {
    font-size: 1.5rem;
    margin-bottom: var(--spacing-sm);
}

p {
    margin-bottom: var(--spacing-sm);
}

a {
    color: var(--color-link);
    text-decoration: none;
    transition: color var(--transition);
}

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

img {
    max-width: 100%;
    height: auto;
    display: block;
}

/* Navigation */
.navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    background: var(--color-bg-alt);
    border-bottom: 1px solid var(--color-border);
    z-index: 1000;
}

.nav-container {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--spacing-sm) var(--spacing-md);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.nav-logo {
    font-family: var(--font-serif);
    font-size: 1.25rem;
    font-weight: 500;
    color: var(--color-text);
}

.nav-menu {
    display: flex;
    list-style: none;
    gap: var(--spacing-md);
}

.nav-link {
    color: var(--color-text-muted);
    font-size: 0.95rem;
    font-weight: 400;
    padding: var(--spacing-xs) 0;
    position: relative;
}

.nav-link::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    width: 0;
    height: 2px;
    background: var(--color-accent);
    transition: width var(--transition);
}

.nav-link:hover,
.nav-link.active {
    color: var(--color-text);
}

.nav-link:hover::after,
.nav-link.active::after {
    width: 100%;
}

.nav-toggle {
    display: none;
    flex-direction: column;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--spacing-xs);
}

.nav-toggle span {
    width: 24px;
    height: 2px;
    background: var(--color-text);
    transition: var(--transition);
}

/* Main Content */
main {
    padding-top: 80px;
}

section {
    padding: var(--spacing-xl) var(--spacing-md);
    max-width: var(--max-width);
    margin: 0 auto;
}

/* Hero Section */
.hero {
    min-height: calc(100vh - 80px);
    display: flex;
    align-items: center;
}

.hero-content {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--spacing-lg);
    align-items: center;
}

.hero-text h1 {
    margin-bottom: var(--spacing-md);
    color: var(--color-accent);
}

.hero-text p {
    font-size: 1.1rem;
    color: var(--color-text-muted);
}

.hero-image {
    display: flex;
    justify-content: center;
}

.hero-image img {
    border-radius: 8px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1);
    max-height: 500px;
    object-fit: cover;
}

.image-placeholder {
    width: 100%;
    max-width: 400px;
    aspect-ratio: 3/4;
    background: linear-gradient(135deg, var(--color-border) 0%, #d5d5d5 100%);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    text-align: center;
    padding: var(--spacing-md);
}

.image-placeholder small {
    margin-top: var(--spacing-xs);
    font-size: 0.8rem;
    opacity: 0.7;
}

/* About Section */
.about {
    background: var(--color-bg-alt);
    max-width: none;
    padding-left: var(--spacing-md);
    padding-right: var(--spacing-md);
}

.about h2 {
    text-align: center;
}

/* One column, not three. The three cards hold 67, 207 and 25 words; as equal
   grid columns they all stretched to the tallest, so the short one became a
   tall box around two lines. Stacking lets each card be its own height, and
   the narrower measure suits Garamond at this size. */
.about-grid {
    max-width: 600px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--spacing-md);
}

.about-card {
    background: var(--color-bg);
    padding: var(--spacing-md);
    border-radius: 8px;
    border: 1px solid var(--color-border);
}

.about-card h3 {
    color: var(--color-accent);
    font-size: 1.1rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-family: var(--font-serif);
    font-weight: 600;
}

.about-card p {
    color: var(--color-text-muted);
    font-size: 1rem;
}

.about-card p:last-child {
    margin-bottom: 0;
}

/* Contact Section */
.contact {
    text-align: center;
}

.btn {
    display: inline-block;
    background: var(--color-accent);
    color: white;
    padding: 0.75rem 2rem;
    border: none;
    border-radius: 4px;
    font-family: var(--font-serif);
    font-size: 1rem;
    font-weight: 500;
    cursor: pointer;
    transition: background var(--transition);
}

.btn:hover {
    background: var(--color-accent-light);
    color: white;
}

.page-lede {
    margin-top: var(--spacing-xs);
    margin-bottom: 0;
    color: var(--color-text-muted);
    font-size: 1.05rem;
    font-style: italic;
}

.contact-links {
    font-size: 1.1rem;
    margin-bottom: 0;
}

.contact-sep {
    color: var(--color-text-muted);
    margin: 0 var(--spacing-xs);
}

/* Contact form. Hidden until js/contact.js has somewhere to post to. */
.contact-form {
    max-width: 480px;
    margin: var(--spacing-md) auto 0;
    display: flex;
    flex-direction: column;
    gap: var(--spacing-xs);
    text-align: left;
}

.contact-form[hidden] {
    display: none;
}

.contact-form input,
.contact-form textarea {
    font-family: var(--font-serif);
    font-size: 1rem;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 3px;
    background: var(--color-bg-alt);
    color: var(--color-text);
    width: 100%;
    resize: vertical;
}

.contact-form input:focus,
.contact-form textarea:focus {
    outline: none;
    border-color: var(--color-accent);
}

.contact-form .btn {
    margin-top: var(--spacing-xs);
    align-self: center;
}

/* Off screen rather than display:none, which bots skip. */
.contact-bait {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
}

.contact-status {
    margin: var(--spacing-xs) 0 0;
    font-size: 0.9rem;
    font-style: italic;
    color: var(--color-text-muted);
    text-align: center;
}

.contact-status.is-error {
    color: #8c2f2f;
}

.empty-note {
    color: var(--color-text-muted);
    font-style: italic;
    text-align: center;
    padding: var(--spacing-lg) 0;
}

/* Footer */
footer {
    text-align: center;
    padding: var(--spacing-md);
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

/* Page Header (for subpages) */
.page-header {
    padding: var(--spacing-lg) var(--spacing-md);
    text-align: center;
    background: var(--color-bg-alt);
    border-bottom: 1px solid var(--color-border);
}

.page-header h1 {
    font-size: 2.5rem;
    color: var(--color-accent);
}

/* Labels that only a screen reader needs, where the placeholder carries the
   meaning visually. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Search boxes, shared by the writing, book and photograph pages */
.search {
    font-family: var(--font-serif);
    font-size: 0.9rem;
    padding: 0.3rem 0.55rem;
    border: 1px solid var(--color-border);
    border-radius: 3px;
    background: var(--color-bg-alt);
    color: var(--color-text);
    min-width: 14rem;
}

.search::placeholder {
    color: var(--color-text-muted);
    opacity: 1;
    /* Firefox dims placeholders by default */
}

.search:focus {
    outline: none;
    border-color: var(--color-accent);
}

/* The writing page has no toolbar of its own to sit in. It takes the measure
   of the post list below it so the box starts on the same line as the titles,
   and the box itself is only as wide as a search term needs rather than the
   whole column. */
.search-bar {
    max-width: 1000px;
    margin: 0 auto;
    padding: var(--spacing-md) var(--spacing-md) 0;
}

.search-bar .search {
    width: 100%;
    max-width: 22rem;
}

/* Content Sections */
.content-section {
    padding: var(--spacing-lg) var(--spacing-md);
    max-width: 800px;
    margin: 0 auto;
}

/* The list of posts. The search box sits directly above it, so the section's
   usual opening gap read as a gulf; and the cards are a title, a date and a
   line, which take a wider measure than an article's prose does. */
.content-section--posts {
    padding-top: var(--spacing-sm);
    max-width: 1000px;
}

.content-section p {
    font-size: inherit;
}

/* Writing Page */
.writing-list {
    list-style: none;
}

.writing-item {
    padding: var(--spacing-md) 0;
    border-bottom: 1px solid var(--color-border);
}

.writing-item:last-child,
.writing-item.is-last {
    /* last one still showing, once search hides some */
    border-bottom: none;
}

.writing-item h3 {
    margin-bottom: var(--spacing-xs);
}

.writing-item h3 a {
    color: var(--color-text);
}

.writing-item h3 a:hover {
    color: var(--color-accent);
}

.writing-meta {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1.25em;
    font-size: inherit;
    color: var(--color-text-muted);
}

.writing-when {
    flex: 0 0 auto;
    white-space: nowrap;
}

.writing-status {
    margin-left: 0.8em;
}

.writing-excerpt {
    flex: 1 1 auto;
    min-width: 0;
    text-align: right;
}

@media (max-width: 768px) {
    .writing-meta {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.15em;
    }

    .writing-excerpt {
        text-align: left;
    }
}

/* A line of the article itself, shown when that is where the search matched. */
.writing-hit {
    margin-top: var(--spacing-xs);
    padding-left: var(--spacing-sm);
    border-left: 2px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: inherit;
    font-style: italic;
}

/* CV Page */
.cv-section {
    margin-bottom: var(--spacing-lg);
}

.cv-section h3 {
    color: var(--color-accent);
    border-bottom: 2px solid var(--color-accent);
    padding-bottom: var(--spacing-xs);
    margin-bottom: var(--spacing-md);
}

.cv-item {
    margin-bottom: var(--spacing-md);
}

.cv-item h4 {
    font-family: var(--font-serif);
    font-weight: 600;
    font-size: 1.1rem;
    margin-bottom: 0.25rem;
}

.cv-item .cv-meta {
    font-size: 0.9rem;
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-xs);
}

.cv-item p {
    font-size: 0.95rem;
}

/* Responsive Design */
@media (max-width: 768px) {
    h1 {
        font-size: 2.25rem;
    }

    h2 {
        font-size: 1.75rem;
    }

    .nav-toggle {
        display: flex;
    }

    .nav-menu {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: var(--color-bg-alt);
        flex-direction: column;
        padding: var(--spacing-sm) var(--spacing-md);
        border-bottom: 1px solid var(--color-border);
        display: none;
        gap: 0;
    }

    .nav-menu.active {
        display: flex;
    }

    .nav-link {
        padding: var(--spacing-sm) 0;
    }

    /* The bar is pinned to the bottom of the link box, so the roomier tap
       padding here would otherwise drop it halfway to the item below. Inset it
       by the padding it gained, leaving the same gap under the word as on a
       wide screen. */
    .nav-link::after {
        bottom: var(--spacing-xs);
    }

    .hero-content {
        grid-template-columns: 1fr;
        text-align: center;
    }

    .hero-image {
        order: -1;
    }

    .image-placeholder {
        max-width: 280px;
        aspect-ratio: 1;
    }

    section {
        padding: var(--spacing-lg) var(--spacing-sm);
    }

}

@media (max-width: 480px) {
    h1 {
        font-size: 1.75rem;
    }

    h2 {
        font-size: 1.5rem;
    }

    .hero-text p {
        font-size: 1rem;
    }
}

/* Blog Post Styles */
.blog-post {
    max-width: 800px;
    margin: 0 auto;
    padding: var(--spacing-lg) var(--spacing-md);
}

.post-header {
    text-align: center;
    margin-bottom: var(--spacing-lg);
    padding-bottom: var(--spacing-md);
    border-bottom: 1px solid var(--color-border);
}

.post-header h1 {
    color: var(--color-accent);
    margin-bottom: var(--spacing-sm);
}

.post-meta {
    color: var(--color-text-muted);
    font-size: inherit;
}

/* A line qualifying the heading above it, rather than a paragraph of its own. */
.post-aside {
    color: var(--color-text-muted);
    font-style: italic;
    margin-top: calc(-1 * var(--spacing-xs));
}

/* One size for everything that is prose, here and on the list of posts. The
   body sets 18px; the meta lines, captions, excerpts and notes used to run at
   five different sizes between 0.85rem and 1.05rem, which on a page of plain
   text reads as inconsistency rather than as hierarchy. Headings are still
   headings. */
.post-content {
    font-size: inherit;
    line-height: 1.8;
}

.post-figure img {
    margin-inline: auto;
}


.post-content h2 {
    margin-top: var(--spacing-lg);
    margin-bottom: var(--spacing-sm);
    font-size: 1.75rem;
}

.post-content h3 {
    margin-top: var(--spacing-md);
    margin-bottom: var(--spacing-sm);
    font-size: 1.4rem;
}

.post-content h4 {
    margin-top: var(--spacing-md);
    margin-bottom: var(--spacing-xs);
    font-size: 1.2rem;
    font-family: var(--font-serif);
    font-weight: 600;
}

.post-content p {
    margin-bottom: var(--spacing-sm);
}

.post-content blockquote {
    margin: var(--spacing-md) 0;
    padding-left: var(--spacing-md);
    border-left: 2px solid var(--color-border);
}

.post-content ul,
.post-content ol {
    margin-bottom: var(--spacing-sm);
    padding-left: var(--spacing-md);
}

.post-content li {
    margin-bottom: var(--spacing-xs);
}

.post-content pre {
    background: #1e1e1e;
    color: #d4d4d4;
    padding: var(--spacing-sm);
    border-radius: 4px;
    overflow-x: auto;
    margin-bottom: var(--spacing-sm);
    font-size: 0.9rem;
    line-height: 1.5;
}

.post-content code {
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}

.post-content p code {
    background: var(--color-border);
    padding: 0.15rem 0.4rem;
    border-radius: 3px;
    font-size: 0.9em;
}

.post-figure {
    margin: var(--spacing-md) 0;
    text-align: center;
}

.post-figure img {
    max-width: 100%;
    height: auto;
    border-radius: 6px;
    margin: 0 auto;
}

/* An interactive figure (an app under apps/, in an iframe) gets the width a map
   needs, breaking out of the 800px reading column the way the sculpture
   galleries do; its caption stays on the reading measure. The frame's height is
   set from its content by a script beside it. */
.post-figure--app {
    width: min(100vw - 2rem, 1120px);
    margin-inline: calc(50% - min(50vw - 1rem, 560px));
}

.post-figure--app figcaption {
    max-width: 800px;
    margin-inline: auto;
}

.post-app {
    display: block;
    width: 100%;
    height: 1400px;
    border: 0;
    border-radius: 6px;
}

.post-figure--nerva {
    max-width: 22rem;
    margin-inline: auto;
}

.post-figure figcaption {
    margin-top: var(--spacing-xs);
    font-size: inherit;
    color: var(--color-text-muted);
    font-style: italic;
}

.post-content sup.cite {
    font-size: 0.72em;
    line-height: 0;
}

.post-content sup.cite a {
    text-decoration: none;
}

.biblio {
    list-style: decimal;
    padding-left: 1.7rem;
    margin: var(--spacing-sm) 0 var(--spacing-md);
}

.biblio li {
    margin-bottom: 0.45rem;
    padding-left: 0.25rem;
}

.biblio li:target {
    background: var(--color-bg-alt);
}

.figure-placeholder {
    background: linear-gradient(135deg, var(--color-border) 0%, #d5d5d5 100%);
    padding: var(--spacing-lg) var(--spacing-md);
    border-radius: 6px;
    color: var(--color-text-muted);
    font-style: italic;
}

.post-nav {
    margin-top: var(--spacing-lg);
    padding-top: var(--spacing-md);
    border-top: 1px solid var(--color-border);
}

.post-download {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    padding: var(--spacing-md);
    border-radius: 4px;
    margin: var(--spacing-md) 0;
}

.post-download .note {
    font-size: inherit;
    color: var(--color-text-muted);
    font-style: italic;
    margin-bottom: 0;
}

/* CV Page Enhancements */
.cv-item ul {
    margin-top: var(--spacing-xs);
    padding-left: var(--spacing-md);
}

.cv-item li {
    margin-bottom: 0.25rem;
    font-size: 0.95rem;
}

/* Route maps in the travel post */
.route {
    margin: var(--spacing-lg) 0;
    padding-top: var(--spacing-md);
    border-top: 1px solid var(--color-border);
}

.route-when {
    color: var(--color-accent);
    font-size: 0.9rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: var(--spacing-xs);
}

.route-blurb {
    color: var(--color-text-muted);
}

.route-map {
    height: 380px;
    margin: var(--spacing-md) 0;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    overflow: hidden;
    background: var(--color-bg-alt);
}

.route-list {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 0.5rem;
    counter-reset: stop;
    padding: 0;
    margin-bottom: var(--spacing-sm);
}

.route-stop {
    counter-increment: stop;
    font-size: 0.9rem;
    padding: 0.2rem 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: 3px;
    color: var(--color-text-muted);
}

.route-stop::before {
    content: counter(stop) ". ";
    color: var(--color-accent);
}

.route-stop.is-sight {
    border-color: var(--color-accent);
    color: var(--color-text);
}

.route-stop.is-airport {
    font-style: italic;
}

@media (max-width: 600px) {
    .route-map {
        height: 300px;
    }
}

/* The Roman quarry map in the stone carving post.

   The post is set to 800px, which is a measure for reading and far too narrow
   for a map of the Mediterranean or a tabletop of a thousand slabs. This
   breaks out of the column and takes most of the window instead, centring
   itself on the column it came from. On a narrow screen min() falls back to
   92vw, a little wider than the text, which is exactly what a map wants. */
.quarries {
    margin: var(--spacing-lg) 0;
    padding-top: var(--spacing-md);
    border-top: 1px solid var(--color-border);
    /* #quarries is a <section>, and the global rule for those caps them at
       --max-width and pads them by 6rem, neither of which suits a block
       sitting inside a post. */
    max-width: none;
    padding-left: 0;
    padding-right: 0;
    width: 100%;
}

/* A search term offered in the prose, which fills the box when clicked. */
.quarry-term {
    font-family: var(--font-serif);
    font-size: inherit;
    color: var(--color-accent);
    background: none;
    border: none;
    border-bottom: 1px dotted var(--color-accent);
    padding: 0;
    cursor: pointer;
}

.quarry-term:hover {
    color: var(--color-accent-light);
}

.quarry-bar {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-xs);
}

.quarry-count {
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

.quarry-map {
    height: min(720px, 78vh);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    overflow: hidden;
    background: var(--color-bg-alt);
}

.quarry-panel {
    margin-top: var(--spacing-sm);
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: 4px;
}

.quarry-panel[hidden] {
    display: none;
}

.quarry-name {
    font-size: 1.2rem;
    margin-bottom: 0.15rem;
    color: var(--color-accent);
}

.quarry-where {
    color: var(--color-text-muted);
    font-size: 0.9rem;
    margin-bottom: var(--spacing-xs);
}

.quarry-material {
    margin-bottom: var(--spacing-xs);
}

.quarry-coords {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    font-variant-numeric: tabular-nums;
    margin-bottom: var(--spacing-xs);
}

/* Links to the photographs and plans of the quarry in Harrell and Storemyr */
.quarry-figures {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-xs);
}

.quarry-refs-heading {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-accent);
    margin-bottom: 0.2rem;
}

.quarry-refs {
    list-style: none;
    padding: 0;
    margin: 0;
    font-size: 0.85rem;
    line-height: 1.5;
}

.quarry-refs li {
    padding-left: var(--spacing-sm);
    text-indent: calc(-1 * var(--spacing-sm));
    margin-bottom: 0.35rem;
    color: var(--color-text-muted);
}

/* A citation the gazetteer never spells out in its own reference list. */
.quarry-refs li.is-short {
    font-style: italic;
}

.quarry-empty {
    color: var(--color-text-muted);
    font-style: italic;
    margin: 0;
}

.quarry-source {
    margin-top: var(--spacing-sm);
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--color-text-muted);
}

@media (max-width: 600px) {
    .quarry-map {
        height: 460px;
    }

    /* Two slabs to a row on a phone rather than one enormous one. The extra
       class is needed because the rule it overrides comes later in the file. */
    .quarries .quarry-marbles {
        grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    }

    .quarry-panel {
        padding: var(--spacing-sm);
    }
}

/* An embedded map that is somebody else's application. Same reasoning as the
   quarry map: a geological map of the world is not a thing to read in a
   column meant for prose. */
.embed-figure {
    width: 100%;
}

.embed-frame {
    position: relative;
    height: 660px;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    overflow: hidden;
    background: var(--color-bg-alt);
}

.embed-frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

.embed-figure figcaption {
    text-align: left;
}

@media (max-width: 600px) {
    .embed-frame {
        height: 420px;
    }
}

/* Expanding a map or the tabletop.

   The post is 800px because that is a measure for reading. A map of the
   Mediterranean and a table of a thousand slabs both want more than that, but
   not all the time and not at the cost of the prose. So they stay in the
   column and take the whole window on request. Fixed positioning rather than
   the Fullscreen API: it behaves the same in every browser, needs no
   permission, and Escape closes it. */
.expand-btn {
    font-family: var(--font-serif);
    font-size: 0.82rem;
    padding: 0.15rem 0.7rem;
    background: none;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: 3px;
    cursor: pointer;
}

.expand-btn:hover {
    border-color: var(--color-accent);
    color: var(--color-accent);
}

.is-expanded {
    position: fixed;
    inset: 0;
    z-index: 3000;
    margin: 0;
    max-width: none;
    width: auto;
    overflow-y: auto;
    background: var(--color-bg);
    padding: var(--spacing-sm) var(--spacing-md) var(--spacing-md);
    border-top: none;
}

/* The map and the frame take the height that is going, less the room the
   toolbar and the caption need. */
.is-expanded .quarry-map,
.is-expanded .embed-frame {
    height: calc(100vh - 205px);
}

/* Only while it sits in the column. Unscoped, this outranked .is-expanded's
   position: fixed (a class and an attribute beat a class), so an expanded
   figure never left the column at all. */
.post-figure[data-expandable]:not(.is-expanded) {
    position: relative;
}

.post-figure[data-expandable] .expand-btn {
    margin-bottom: var(--spacing-xs);
}

.post-figure:not(.is-expanded)[data-expandable] img {
    cursor: zoom-in;
}

.post-figure.is-expanded {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    padding: var(--spacing-sm) var(--spacing-md) var(--spacing-md);
    background: var(--color-bg);
}

.post-figure.is-expanded .expand-btn {
    align-self: flex-end;
    margin-bottom: 0.5rem;
    z-index: 10;
}

.post-figure.is-expanded img {
    max-width: 100%;
    max-height: calc(100vh - 140px);
    width: auto;
    height: auto;
    object-fit: contain;
    margin: auto auto;
    cursor: zoom-out;
    background: #ffffff;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
}

.post-figure.is-expanded[data-fullres="true"] {
    display: block;
    overflow: auto;
    text-align: center;
}

.post-figure.is-expanded[data-fullres="true"] .expand-btn {
    float: right;
    margin-bottom: 1rem;
}

.post-figure.is-expanded[data-fullres="true"] img {
    max-width: none;
    max-height: none;
    width: max-content;
    height: auto;
    cursor: zoom-out;
}

/* A single image with a larger file behind it (data-full). Expanded, it fits
   the window, sharp because the large file is swapped in; a click then shows
   it at the size it was published, to pan around and read the small print,
   and another click fits it again. The button stays pinned while panning. */
.post-figure.is-expanded:not(.is-solo) img[data-full] {
    cursor: zoom-in;
}

.post-figure.is-expanded.is-solo:not(.figure-gallery) {
    display: block;
    overflow: auto;
    text-align: center;
}

/* Pinned to the window, not the image: sticky only holds in one direction,
   and panning right carried the button off the left edge. */
.post-figure.is-expanded.is-solo:not(.figure-gallery) .expand-btn {
    position: fixed;
    top: var(--spacing-sm);
    right: var(--spacing-md);
    z-index: 10;
    background: var(--color-bg);
}

.post-figure.is-expanded.is-solo:not(.figure-gallery) img.is-solo-target {
    max-width: none;
    max-height: none;
    width: max-content;
    height: auto;
    margin: 0;
    cursor: zoom-out;
}

/* An expanded figure is a centred flex column, which sizes children to their
   content. The frame's only content is an absolutely positioned iframe, so
   without this it shrinks to its own border and the map vanishes. */
.post-figure.is-expanded .embed-frame {
    align-self: stretch;
}

.post-figure.is-expanded figcaption {
    margin-top: 0.6rem;
    font-size: 0.92rem;
}

/* Expanded, the quarry box moves alongside the map rather than under it.
   Below it, a selected quarry was off the bottom of the screen and the point
   of expanding - seeing the map and what is on it at once - was lost. */
@media (min-width: 900px) {
    .quarries.is-expanded {
        display: grid;
        grid-template-columns: 1fr minmax(320px, 400px);
        column-gap: var(--spacing-md);
        align-content: start;
    }

    .quarries.is-expanded>*:not(.quarry-map):not(.quarry-panel) {
        grid-column: 1 / -1;
    }

    .quarries.is-expanded .quarry-map {
        grid-column: 1;
    }

    .quarries.is-expanded .quarry-marbles {
        margin-inline: auto;
    }

    .quarries.is-expanded .quarry-panel {
        grid-column: 2;
        margin-top: 0;
        max-height: calc(100vh - 205px);
        overflow-y: auto;
    }

    /* Nothing selected yet: the map takes the width rather than leaving a
       column of empty page beside it. */
    .quarries.is-expanded .quarry-panel[hidden]~* {
        grid-column: 1 / -1;
    }
}

/* Nothing behind an expanded panel should scroll. */
body.has-expanded {
    overflow: hidden;
}

/* Clears the search and any selected slab. Hidden while neither is set. */
.quarry-clear {
    font-family: var(--font-serif);
    font-size: 0.82rem;
    padding: 0.15rem 0.7rem;
    background: none;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: 3px;
    cursor: pointer;
}

.quarry-clear:hover {
    border-color: var(--color-accent);
    color: var(--color-accent);
}

.quarry-clear[hidden] {
    display: none;
}

/* What Harrell's survey adds to a quarry */
.quarry-worked {
    font-size: 0.82rem;
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-xs);
}

.quarry-stone {
    font-size: 0.88rem;
    line-height: 1.55;
    margin-bottom: var(--spacing-xs);
}

.quarry-ancient,
.quarry-italian {
    font-size: 0.88rem;
    font-style: italic;
    line-height: 1.5;
    margin-bottom: var(--spacing-xs);
}

/* The stone's own record, inside the box under the map */
.quarry-slab-geology {
    font-style: italic;
    margin-bottom: var(--spacing-xs);
}

.quarry-slab-class {
    font-size: 0.82rem;
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-xs);
}

.quarry-slab-comments {
    font-size: 0.88rem;
    line-height: 1.55;
    margin-bottom: var(--spacing-xs);
}

/* The other stones the collection holds from the open quarry */
.quarry-slab-more {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin-bottom: 0.35rem;
}

.quarry-slab-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 3px;
    margin-bottom: var(--spacing-xs);
}

.quarry-slab-chip {
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    line-height: 0;
    position: relative;
    width: 64px;
    aspect-ratio: 640 / 300;
    overflow: hidden;
    border-radius: 2px;
}

.quarry-slab-chip img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Same reasoning as the tabletop: an inset shadow would be buried under the
   photograph, so the ring goes on a layer above it. */
.quarry-slab-chip::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.quarry-slab-chip:hover::after {
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.9);
}

.quarry-slab-chip.is-on::after {
    box-shadow: inset 0 0 0 2px #111, inset 0 0 0 4px rgba(255, 255, 255, 0.85);
}

/* Leaflet ships its own sans-serif for the attribution, the scale bar, the
   zoom buttons and the tooltips. Those are all in our DOM, so they can be put
   into the site's face. The labels drawn on the tiles cannot: those are pixels
   baked into the images OpenStreetMap serves. */
.leaflet-container,
.leaflet-control-attribution,
.leaflet-control-scale-line,
.leaflet-bar a,
.leaflet-popup-content,
.leaflet-tooltip {
    font-family: var(--font-serif);
}

.leaflet-control-attribution,
.leaflet-control-scale-line {
    font-size: 0.75rem;
}

.leaflet-bar a {
    font-size: 1.1rem;
}

/* Source key above the quarry map */
.quarry-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 1rem;
    font-size: 0.82rem;
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-xs);
}

.key {
    display: inline-block;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    margin-right: 0.15rem;
    vertical-align: -1px;
}

.key-russell {
    background: #17325c;
}

.key-harrell {
    background: #8c5a1f;
}

/* Which gazetteer the open site came from */
.quarry-source-line {
    font-size: 0.78rem;
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-xs);
}

/* The slab shown with an open quarry */
.quarry-slab {
    margin: 4px 0 var(--spacing-sm);
    padding-left: 4px;
}

.quarry-slab img {
    width: 100%;
    max-width: 420px;
    border-radius: 2px;
    /* Framed in black, the way a slab selected in the tabletop is framed in
       white. Two selections are live at once - one in the box under the map,
       one among the tiles - and the colour is what says which is which. */
    box-shadow: 0 0 0 3px #111, 0 0 0 4px rgba(255, 255, 255, 0.85);
    border: none;
}

.quarry-slab figcaption {
    font-size: 0.78rem;
    color: var(--color-text-muted);
    margin-top: 0.2rem;
}

/* The slabs get the extra width; the heading, the count, the button and the
   credit stay in the column with the rest of the prose. Widening the whole
   block put the paragraph on a longer measure than the text above it, which
   is exactly the thing the 800px column exists to avoid. */
.quarries:not(.is-expanded) .quarry-marbles {
    width: min(1100px, 94vw);
    margin-left: 50%;
    transform: translateX(-50%);
}

/* The tabletop of slabs under the map.

   Laid edge to edge with nothing between them, which is how a specimen
   tabletop is actually cut: the slabs abut, and the pattern is in the
   meeting of one stone with the next. Names would put a gutter between
   every pair, so a tile carries only its photograph and says what it is
   when it is clicked. */
.quarry-marbles-wrap {
    margin-top: var(--spacing-lg);
}

.quarry-marbles-wrap[hidden] {
    display: none;
}

.quarry-marbles {
    display: grid;
    /* Big enough to read the stone. At 140px a slab was 157x74, which shows
       the colour and nothing else; the veining, the breccia clasts and the
       grain that tell one marble from another need more than that. */
    /* The column count is set by js/quarries.js, which picks one that divides
       the number of slabs so no row is left short. This is the fallback for
       the moment before it runs. */
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 0;
    margin-bottom: var(--spacing-sm);
    /* No frame and no background. A count like 46, whose only divisors are 2
       and 23, cannot fill its last row at any sensible tile size; without a
       border drawn round the whole grid, that row simply ends where it ends
       rather than leaving a gap inside a box. The table's edge is the edge of
       the slabs, which is what it is in a real one. */
}

.marble {
    display: block;
    padding: 0;
    margin: 0;
    border: none;
    background: var(--color-bg-alt);
    cursor: pointer;
    position: relative;
    line-height: 0;
    /* The shape the Museum photographs a slab at: 969 of the thousand are
       exactly 640x300. Fixing the tile to it keeps every row the same height,
       without which the taller strays set the row and leave a hairline of
       background under their shorter neighbours - visible as a gap in what is
       supposed to be a continuous surface. The 31 odd ones lose at most seven
       percent off top and bottom. */
    aspect-ratio: 640 / 300;
}

.marble img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
}

/* The ring around the slab being read.

   It has to be drawn on a layer of its own. An inset box-shadow on the button
   paints above the button's background but below its child content, and the
   photograph covers the tile exactly, so a shadow set on .marble itself is
   painted and then buried - the ring was there in the computed styles and
   invisible on screen. An absolutely positioned ::after is a positioned
   descendant, which paints above the static image.

   White with a dark line outside it, because the collection runs from
   near-black porphyry to white statuary marble and no single colour reads
   on both. */
.marble::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    transition: box-shadow var(--transition);
}

.marble:hover::after {
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.9);
}

.marble.is-open::after {
    box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 6px rgba(23, 50, 92, 0.9);
}

.marble.is-open {
    z-index: 2;
}

.marble:hover {
    z-index: 1;
}

/* No photograph: the tile is still the way into the quarries. */
.marble.is-bare {
    min-height: 90px;
    background: linear-gradient(135deg, var(--color-border) 0%, #d5d5d5 100%);
}

/* A stone whose locality matches no quarry on the map used to be drawn at
   half opacity. On a tabletop where 442 of the thousand are in that position
   it read as a fault in the photographs rather than a statement about the
   data, so the slabs are all shown as the Museum shot them. Which stones are
   placed is said in words, when one is clicked, and shown on the map. */

/* What a clicked slab says. It is inserted into the grid as a full-width row
   directly beneath the slab's own row, so with a thousand tiles on screen the
   words still belong to a stone you can see. Semi-transparent, so the
   tabletop it is lying on reads through it. */
.marble-open {
    grid-column: 1 / -1;
    margin: 0;
    padding: var(--spacing-sm) var(--spacing-md);
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    border-top: 2px solid var(--color-accent);
    border-bottom: 1px solid var(--color-border);
    font-size: 0.9rem;
    line-height: 1.5;
}

.marble-open[hidden] {
    display: none;
}

.marble-open p {
    margin-bottom: 0.35rem;
}

.marble-open p:last-child {
    margin-bottom: 0;
}

.marble-open-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.3rem 0.8rem;
}

.marble-open-name {
    font-size: 1.15rem;
    color: var(--color-accent);
}

.marble-open a {
    font-size: 0.8rem;
}

.marble-open-geology {
    font-style: italic;
}

.marble-open-where,
.marble-open-class {
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

.marble-open-comments {
    line-height: 1.55;
    padding-top: 0.15rem;
}

.quarry-more {
    font-size: 0.9rem;
    padding: 0.45rem 1.2rem;
}

/* .btn sets display:inline-block, which beats the browser's own rule for
   [hidden]; without this the button stayed on screen offering to show a
   negative number of stones. */
.quarry-more[hidden] {
    display: none;
}

.quarry-credit {
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--color-text-muted);
}

/* Admired list */
.admire-list {
    list-style: none;
    padding: 0;
    margin-bottom: var(--spacing-md);
}

.admire-list li {
    padding: 0.35rem 0;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.6rem;
}

.admire-list li:last-child {
    border-bottom: none;
}

.admire-name {
    font-size: 1.05rem;
}

.admire-note {
    color: var(--color-text-muted);
    font-size: 0.9rem;
    font-style: italic;
}

.admire-list a {
    font-size: 0.9rem;
}

.admire-list a::after {
    content: " \2197";
    font-size: 0.8em;
    opacity: 0.7;
}

/* The name itself is a link where there is an encyclopaedia entry for it. It
   keeps the size and colour of a plain name, and takes no arrow: the arrow
   marks the link out to the work, and two of them on one line reads as two
   destinations of equal weight, which they are not. */
.admire-list a.admire-name {
    font-size: 1.05rem;
    color: var(--color-text);
}

.admire-list a.admire-name::after {
    content: none;
}

.admire-list a.admire-name:hover {
    color: var(--color-accent);
}

/* One size for a post, headings included: the title, every heading inside it,
   the prose, the captions and the cards on the list of posts all set at the
   body's 18px. A heading is then told apart by weight, colour and the space
   around it rather than by being bigger - which is the whole of what a size
   was doing here, since the post has only ever been two levels deep.

   This block sits at the end of the file on purpose. Its selectors are no
   more specific than the ones they override - .post-content h2 against
   .post-content h2 - so the only thing deciding it is which comes last. */
.blog-post h1,
.blog-post h2,
.blog-post h3,
.blog-post h4,
.post-header h1,
.post-content h2,
.post-content h3,
.post-content h4,
.writing-item h3,
.quarries h2,
.quarries h3,
.route h2,
.route-when,
.route-blurb,
.route-stop {
    font-size: inherit;
}

/* Weight and colour carry the hierarchy now. */
.post-content h2,
.quarries h2 {
    font-weight: 600;
    color: var(--color-accent);
    letter-spacing: 0.02em;
}

.post-content h3,
.post-content h4,
.quarries h3 {
    font-weight: 600;
}

.post-header h1 {
    font-weight: 600;
    letter-spacing: 0.01em;
}

.writing-item h3 {
    font-weight: 600;
}

/* Tables and equations, from the LaTeX projects */
.table-wrap {
    overflow-x: auto;
    margin-bottom: var(--spacing-sm);
}

.table-wrap table {
    border-collapse: collapse;
    width: auto;
    max-width: 100%;
    margin-inline: auto;
    font-size: inherit;
}

.table-wrap th,
.table-wrap td {
    border-bottom: 1px solid var(--color-border);
    padding: 0.4rem 0.7rem;
    text-align: center;
    vertical-align: top;
}

.table-wrap th {
    font-weight: 600;
    color: var(--color-accent);
    border-bottom-width: 2px;
}

.table-caption {
    font-size: inherit;
    color: var(--color-text-muted);
    font-style: italic;
    text-align: center;
}

/* A displayed equation. KaTeX replaces the contents; until it loads this is
   the TeX as written, which is legible enough on its own. */
.math-block {
    overflow-x: auto;
    padding: var(--spacing-xs) 0;
    margin-bottom: var(--spacing-sm);
    text-align: center;
}

/* KaTeX's default is 1.21em, which sits well above the surrounding prose. */
.post-content .katex {
    font-size: 1.05em;
}

/* A Beamer deck kept as a deck: one slide at a time, arrows and swipe to
   move, and the compiled PDF a click away. The pages are rendered to images
   at build time because an embedded PDF shows nothing at all on a phone. */
.slide-deck {
    margin: var(--spacing-md) 0;
    outline: none;
}

.slide-deck .slide {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid var(--color-border);
    border-radius: 6px;
}

.slide-deck .slide[hidden] {
    display: none;
}

.slide-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-sm);
    margin-top: var(--spacing-xs);
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

.slide-bar button {
    font-family: var(--font-serif);
    font-size: 1rem;
    line-height: 1;
    padding: 0.25rem 0.7rem;
    color: var(--color-link);
    background: none;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    cursor: pointer;
    transition: border-color var(--transition), color var(--transition);
}

.slide-bar button:hover {
    color: var(--color-link-hover);
    border-color: var(--color-link-hover);
}

.slide-count {
    font-variant-numeric: tabular-nums;
}

.slide-pdf {
    margin-left: var(--spacing-xs);
}

/* Several photos or diagrams that sat together on one slide. */
.figure-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin: var(--spacing-md) 0;
    justify-content: center;
    align-items: flex-end;
}

.figure-row .post-figure {
    flex: 1 1 180px;
    margin: 0;
    min-width: 0;
}

/* Interstellar map: the same width as the post column, unless the reader
   opens it full screen. Travel numbers sit under the canvas; in full
   screen they sit in a strip at the bottom. */
.interstellar {
    position: relative;
    width: 100%;
    margin: var(--spacing-md) 0;
}

.interstellar-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 1 / 0.72;
    min-height: 420px;
    background: #07080c;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    overflow: hidden;
    cursor: grab;
}

.interstellar-stage:active {
    cursor: grabbing;
}

.interstellar-stage canvas {
    position: absolute;
    inset: 0;
    z-index: 0;
    display: block;
    width: 100%;
    height: 100%;
}

.interstellar-full {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    z-index: 4;
    font-family: var(--font-serif);
    font-size: 0.72rem;
    letter-spacing: 0.03em;
    padding: 0.16rem 0.5rem;
    color: rgba(232, 238, 246, 0.92);
    background: rgba(8, 10, 14, 0.52);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 0;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.18);
    cursor: pointer;
}

.interstellar-full:hover {
    color: #fff;
    background: rgba(20, 28, 42, 0.7);
}

.interstellar:fullscreen,
.interstellar.is-fullscreen {
    left: 0;
    transform: none;
    width: 100%;
    height: 100%;
    margin: 0;
    background: #07080c;
    display: flex;
    flex-direction: column;
    padding: 0;
}

.interstellar:fullscreen .interstellar-stage,
.interstellar.is-fullscreen .interstellar-stage {
    flex: 1;
    height: auto;
    min-height: 0;
    aspect-ratio: auto;
    border: 0;
    border-radius: 0;
}

.interstellar:fullscreen .interstellar-panel,
.interstellar.is-fullscreen .interstellar-panel {
    margin: 0;
    padding: 0.4rem 0.6rem 0.5rem;
    background: #080b11;
    color: #e8eef6;
    width: 100%;
    max-width: none;
    max-height: none;
    overflow: hidden;
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    flex: 0 0 auto;
}

.interstellar:fullscreen .interstellar-search-wrap,
.interstellar.is-fullscreen .interstellar-search-wrap {
    max-width: 22rem;
    margin: 0;
}

.interstellar:fullscreen .interstellar-dash,
.interstellar.is-fullscreen .interstellar-dash {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.45rem;
    align-items: stretch;
    min-height: 0;
}

.interstellar:fullscreen .interstellar-dash:has(.interstellar-planets[hidden]),
.interstellar.is-fullscreen .interstellar-dash:has(.interstellar-planets[hidden]) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.interstellar:fullscreen .interstellar-selected,
.interstellar.is-fullscreen .interstellar-selected,
.interstellar:fullscreen .interstellar-planets,
.interstellar.is-fullscreen .interstellar-planets,
.interstellar:fullscreen .interstellar-mission,
.interstellar.is-fullscreen .interstellar-mission,
.interstellar:fullscreen #interstellar-travel,
.interstellar.is-fullscreen #interstellar-travel {
    min-width: 0;
    min-height: 0;
    padding: 0.35rem 0.6rem 0.4rem;
    background: #121822;
    border-radius: 6px;
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.14);
}

.interstellar:fullscreen .interstellar-dash>[data-kicker]::before,
.interstellar.is-fullscreen .interstellar-dash>[data-kicker]::before {
    content: attr(data-kicker);
    display: block;
    font-family: var(--font-serif);
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(176, 200, 230, 0.72);
    margin: 0 0 0.32rem;
}

.interstellar:fullscreen .interstellar-selected h3,
.interstellar.is-fullscreen .interstellar-selected h3 {
    margin: 0 0 0.28rem;
    font-size: 1.12rem;
    line-height: 1.15;
}

.interstellar:fullscreen .interstellar-lede,
.interstellar.is-fullscreen .interstellar-lede {
    display: none;
}

.interstellar:fullscreen .interstellar-facts,
.interstellar.is-fullscreen .interstellar-facts {
    font-size: 0.78rem;
    margin: 0;
    max-width: none;
    display: grid;
    grid-template-columns: auto 1fr auto 1fr auto 1fr;
    column-gap: 0.5rem;
}

.interstellar:fullscreen .interstellar-facts tbody,
.interstellar.is-fullscreen .interstellar-facts tbody,
.interstellar:fullscreen .interstellar-facts tr,
.interstellar.is-fullscreen .interstellar-facts tr {
    display: contents;
}

.interstellar:fullscreen .interstellar-facts th,
.interstellar.is-fullscreen .interstellar-facts th,
.interstellar:fullscreen .interstellar-facts td,
.interstellar.is-fullscreen .interstellar-facts td {
    padding: 0.08rem 0.7rem 0.08rem 0;
}

.interstellar:fullscreen .interstellar-planets,
.interstellar.is-fullscreen .interstellar-planets {
    margin: 0;
    max-width: none;
    color: #e8eef6;
    gap: 0.4rem;
    font-size: 0.78rem;
}

.interstellar:fullscreen .interstellar-planets li,
.interstellar.is-fullscreen .interstellar-planets li {
    display: block;
    white-space: normal;
    padding: 0 0 0.4rem;
    border-bottom: 1px solid rgba(160, 190, 230, 0.12);
}

.interstellar:fullscreen .interstellar-planets li:last-child,
.interstellar.is-fullscreen .interstellar-planets li:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.interstellar:fullscreen .interstellar-planets strong,
.interstellar.is-fullscreen .interstellar-planets strong {
    display: block;
    color: #e8eef6;
    margin-bottom: 0.08rem;
}

.interstellar:fullscreen .interstellar-planets span,
.interstellar.is-fullscreen .interstellar-planets span {
    display: block;
    white-space: normal;
    line-height: 1.35;
    color: #9aa8b8;
}

.interstellar:fullscreen .interstellar-mission,
.interstellar.is-fullscreen .interstellar-mission {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.28rem 0.65rem;
    align-content: start;
}

.interstellar:fullscreen .interstellar-mission .interstellar-controls:first-child,
.interstellar.is-fullscreen .interstellar-mission .interstellar-controls:first-child {
    grid-column: 1 / -1;
}

.interstellar:fullscreen #interstellar-travel,
.interstellar.is-fullscreen #interstellar-travel {
    display: none;
}

.interstellar:fullscreen .interstellar-controls,
.interstellar.is-fullscreen .interstellar-controls {
    justify-content: flex-start;
    margin: 0;
    gap: 0.2rem 0.4rem;
}

.interstellar:fullscreen .interstellar-mission .interstellar-controls:not(:first-child) label,
.interstellar.is-fullscreen .interstellar-mission .interstellar-controls:not(:first-child) label {
    flex: 1 0 100%;
}

.interstellar:fullscreen .interstellar-controls label,
.interstellar.is-fullscreen .interstellar-controls label {
    font-size: 0.75rem;
    color: #9aa8b8;
}

.interstellar:fullscreen .interstellar-controls input[type="range"],
.interstellar.is-fullscreen .interstellar-controls input[type="range"] {
    width: 100%;
    min-width: 0;
    flex: 1;
}

.interstellar:fullscreen .interstellar-controls input[type="number"],
.interstellar.is-fullscreen .interstellar-controls input[type="number"] {
    width: 4.6rem;
    font-size: 0.78rem;
    padding: 0.08rem 0.3rem;
    background: #161a22;
    color: #e8eef6;
    border-color: #3d5a80;
}

.interstellar:fullscreen .interstellar-results,
.interstellar.is-fullscreen .interstellar-results {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.22rem 0.85rem;
    margin: 0;
    max-width: none;
    align-content: start;
}

.interstellar:fullscreen .interstellar-metric,
.interstellar.is-fullscreen .interstellar-metric {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.15rem 0.5rem;
    align-items: baseline;
}

.interstellar:fullscreen .interstellar-metric .v,
.interstellar.is-fullscreen .interstellar-metric .v {
    text-align: right;
    font-size: 0.86rem;
}

.interstellar:fullscreen .interstellar-metric.is-extra,
.interstellar.is-fullscreen .interstellar-metric.is-extra {
    display: grid;
}

.interstellar:fullscreen .interstellar-fuel-table,
.interstellar.is-fullscreen .interstellar-fuel-table,
.interstellar:fullscreen .table-wrap,
.interstellar.is-fullscreen .table-wrap {
    display: none;
}

.interstellar:fullscreen .interstellar-credit,
.interstellar.is-fullscreen .interstellar-credit {
    display: none;
}

.interstellar:fullscreen .search,
.interstellar.is-fullscreen .search {
    background: #161a22;
    color: #e8eef6;
    border-color: #3d5a80;
    font-size: 0.85rem;
    padding: 0.2rem 0.45rem;
}

.interstellar:fullscreen .interstellar-selected h3,
.interstellar.is-fullscreen .interstellar-selected h3,
.interstellar:fullscreen .interstellar-metric .v,
.interstellar.is-fullscreen .interstellar-metric .v {
    color: #e8eef6;
}

.interstellar:fullscreen .interstellar-facts th,
.interstellar.is-fullscreen .interstellar-facts th,
.interstellar:fullscreen .interstellar-lede,
.interstellar.is-fullscreen .interstellar-lede,
.interstellar:fullscreen .interstellar-metric .k,
.interstellar.is-fullscreen .interstellar-metric .k {
    color: #9aa8b8;
}

.interstellar:fullscreen .interstellar-facts td,
.interstellar.is-fullscreen .interstellar-facts td {
    color: #e8eef6;
}

.interstellar-hud {
    position: absolute;
    left: 0.45rem;
    bottom: 0.45rem;
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.32rem;
    max-width: min(34rem, calc(100% - 1rem));
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    pointer-events: none;
}

.interstellar-hud>* {
    pointer-events: auto;
}

.interstellar-hud-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.28rem 0.4rem;
}

.interstellar-hud-k {
    flex: 0 0 3.4rem;
    font-family: var(--font-serif);
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: rgba(176, 200, 230, 0.78);
    text-shadow: 0 0 6px #000;
}

.interstellar-seg {
    display: flex;
    flex-wrap: nowrap;
    gap: 0;
    border-radius: 3px;
    overflow: hidden;
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.16);
}

.interstellar-hud-group .interstellar-seg {
    flex-wrap: wrap;
    overflow: visible;
}

.interstellar-seg button,
.interstellar-toggle,
.interstellar-recenter,
.interstellar-hud-status {
    font-family: var(--font-serif);
    font-size: 0.72rem;
    letter-spacing: 0.01em;
    color: rgba(232, 238, 246, 0.92);
    background: rgba(8, 10, 14, 0.52);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 0;
    padding: 0.16rem 0.48rem;
}

.interstellar-seg button {
    cursor: pointer;
    border-right: 1px solid rgba(160, 190, 230, 0.14);
}

.interstellar-seg button:last-child {
    border-right: 0;
}

.interstellar-seg button:hover,
.interstellar-toggle:hover,
.interstellar-recenter:hover {
    color: #fff;
    background: rgba(20, 28, 42, 0.7);
}

.interstellar-seg button.is-on {
    background: rgba(42, 79, 135, 0.58);
    color: #e8f0ff;
}

.interstellar-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.28rem;
    cursor: pointer;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.16);
}

.interstellar-toggle input {
    margin: 0;
    accent-color: #6a96d4;
}

.interstellar-recenter {
    cursor: pointer;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.16);
}

.interstellar-hud-filters {
    align-items: flex-start;
}

.interstellar-filter-stack {
    display: flex;
    flex-direction: column;
    gap: 0.22rem;
}

.interstellar-filters {
    max-width: none;
    flex-wrap: nowrap;
    overflow: visible;
    box-shadow: none;
    gap: 0.22rem;
    background: none;
}

.interstellar-filters button {
    white-space: nowrap;
    border-right: 0;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.16);
}

.interstellar-hud-status {
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.16);
}

.interstellar-labels {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: 1;
}

.interstellar-labels span {
    position: absolute;
    transform: translate(8px, -50%);
    color: #c8e6ff;
    font-size: 0.72rem;
    line-height: 1.2;
    text-shadow: 0 0 6px #000, 0 0 2px #000;
    white-space: nowrap;
}

.interstellar-labels .is-grid {
    color: rgba(176, 200, 230, 0.88);
    font-size: 0.68rem;
}

.interstellar-panel {
    margin-top: var(--spacing-sm);
    text-align: center;
}

.interstellar-dash {
    margin-top: var(--spacing-sm);
}

.interstellar-planets {
    list-style: none;
    margin: 0 auto var(--spacing-sm);
    padding: 0;
    max-width: min(52rem, 100%);
    text-align: left;
    font-size: inherit;
    display: grid;
    gap: 0.28rem;
    overflow-x: auto;
}

.interstellar-planets li {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.7rem;
    align-items: baseline;
    white-space: nowrap;
}

.interstellar-planets strong {
    font-weight: 600;
    flex: none;
}

.interstellar-planets span {
    color: var(--color-text-muted);
}

.interstellar-planets[hidden],
.interstellar-mission[hidden],
#interstellar-travel[hidden] {
    display: none !important;
}

.interstellar-search-wrap {
    position: relative;
    max-width: 28rem;
    margin: 0 auto;
}

.interstellar-panel .search {
    width: 100%;
    min-width: 0;
}

.interstellar-lede {
    color: var(--color-text-muted);
    margin: 0.2rem auto 0.6rem;
    max-width: 36rem;
}

.interstellar-facts {
    width: 100%;
    max-width: min(52rem, 100%);
    margin: 0 auto var(--spacing-sm);
    border-collapse: collapse;
    text-align: left;
    font-size: inherit;
}

.interstellar-facts th {
    font-weight: 400;
    color: var(--color-text-muted);
    white-space: nowrap;
    vertical-align: baseline;
    padding: 0.18rem 1.1rem 0.18rem 0;
    width: 1%;
}

.interstellar-facts td {
    vertical-align: baseline;
    padding: 0.18rem 1.1rem 0.18rem 0;
}

.interstellar-facts td.v {
    white-space: nowrap;
    width: 1%;
}

.interstellar-facts td.note {
    color: var(--color-text-muted);
    padding-right: 0;
    width: auto;
}

.interstellar-suggest {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: 2;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-top: 0;
    max-height: 12rem;
    overflow-y: auto;
}

.interstellar-suggest button {
    display: block;
    width: 100%;
    text-align: left;
    font-family: var(--font-serif);
    font-size: inherit;
    padding: 0.35rem 0.55rem;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text);
    cursor: pointer;
}

.interstellar-suggest button:hover,
.interstellar-suggest button:focus {
    background: var(--color-bg);
    color: var(--color-accent);
}

.interstellar-selected h3 {
    margin-top: var(--spacing-sm);
    margin-bottom: 0;
    font-size: 1.3rem;
}

.interstellar-controls {
    display: grid;
    grid-template-columns: 115px 8rem 4.6rem 20px;
    gap: 0.35rem 0.5rem;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--spacing-sm);
    text-align: right;
}

.interstellar-controls--full {
    display: flex;
    justify-content: center;
    grid-column: 1 / -1;
}

.interstellar-controls label {
    font-size: inherit;
}

.interstellar-controls label input[type="radio"] {
    margin-right: 0.3rem;
}

.interstellar-controls input[type="range"] {
    width: 8rem;
    accent-color: var(--color-accent);
}

.interstellar-controls input[type="number"] {
    width: 100%;
    font-family: var(--font-serif);
    font-size: inherit;
    padding: 0.15rem 0.4rem;
    border: 1px solid var(--color-border);
    border-radius: 3px;
    box-sizing: border-box;
}

.interstellar-controls input.interstellar-value {
    width: 100%;
}

.interstellar-corner {
    position: absolute;
    right: 0.5rem;
    bottom: 0.5rem;
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.35rem;
    pointer-events: none;
}

.interstellar-nav,
.interstellar-scale,
.interstellar-fix {
    pointer-events: auto;
}

.interstellar-fix {
    display: flex;
    align-items: flex-end;
    gap: 0.4rem;
}

.interstellar-fix[hidden] {
    display: none;
}

.interstellar-fix canvas {
    width: 88px;
    height: 88px;
    display: block;
    border-radius: 3px;
    background: rgba(8, 10, 14, 0.52);
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.16);
}

.interstellar-fix-read {
    margin: 0;
    font-family: var(--font-serif);
    font-size: 0.72rem;
    line-height: 1.25;
    color: rgba(232, 238, 246, 0.92);
    text-shadow: 0 0 6px #000;
    white-space: pre;
    text-align: right;
}

.interstellar-nav {
    display: grid;
    grid-template-columns: repeat(3, 1.65rem);
    grid-template-rows: repeat(3, 1.65rem);
    gap: 0.12rem;
}

.interstellar-nav[hidden] {
    display: none;
}

.interstellar-nav-gap {
    display: block;
}

.interstellar-nav button {
    font-family: var(--font-serif);
    font-size: 0.72rem;
    line-height: 1;
    color: rgba(232, 238, 246, 0.92);
    background: rgba(8, 10, 14, 0.52);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 0;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.16);
    cursor: pointer;
    padding: 0;
}

.interstellar-nav button:hover {
    color: #fff;
    background: rgba(20, 28, 42, 0.7);
}

.interstellar-scale {
    min-width: 10rem;
    padding: 0.35rem 0.45rem 0.4rem;
    background: rgba(8, 10, 14, 0.55);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 0 0 1px rgba(160, 190, 230, 0.16);
    border-radius: 3px;
}

.interstellar-scale-cap {
    font-family: var(--font-serif);
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: rgba(176, 200, 230, 0.85);
    margin-bottom: 0.25rem;
}

.interstellar-scale-row {
    display: flex;
    gap: 0.15rem;
}

.interstellar-scale-chip {
    flex: 1;
    text-align: center;
    font-family: var(--font-serif);
    font-size: 0.68rem;
    color: #fff;
    text-shadow: 0 0 3px #000, 0 0 1px #000;
    padding: 0.12rem 0.1rem;
    border: 0;
    border-radius: 2px;
    cursor: pointer;
    min-width: 0;
}

.interstellar-scale-chip:hover {
    filter: brightness(1.12);
}

.interstellar-scale-row.is-filtered .interstellar-scale-chip {
    opacity: 0.38;
}

.interstellar-scale-row.is-filtered .interstellar-scale-chip.is-on {
    opacity: 1;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.85);
}

.interstellar-scale-bar {
    display: block;
    width: 100%;
    height: 10px;
    border-radius: 2px;
}

.interstellar-scale.is-ship {
    min-width: 11.5rem;
    padding: 0.28rem 0.4rem 0.28rem;
}

.interstellar-scale.is-ship .interstellar-scale-cap {
    margin-bottom: 0.12rem;
    text-transform: none;
    letter-spacing: 0.02em;
    max-width: 14rem;
    line-height: 1.25;
}

.interstellar-scale.is-ship .interstellar-scale-bar {
    height: 3px;
    border-radius: 1px;
}

.interstellar-scale-ticks {
    display: flex;
    justify-content: space-between;
    margin-top: 0.15rem;
    font-family: var(--font-serif);
    font-size: 0.62rem;
    color: rgba(232, 238, 246, 0.88);
}

.interstellar-fuel-table {
    font-size: inherit;
    width: 100%;
}

.interstellar-math {
    margin: var(--spacing-md) 0;
}

.interstellar-math summary {
    cursor: pointer;
    color: var(--color-accent);
    margin-bottom: var(--spacing-sm);
}

.interstellar-results {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
    gap: 0.45rem 1rem;
    margin: 0 auto var(--spacing-sm);
    text-align: left;
    max-width: 36rem;
}

.interstellar-metric {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
}

.interstellar-metric .k {
    color: var(--color-text-muted);
}

.interstellar-metric .k sub {
    font-size: 0.72em;
}

.interstellar-metric .v {
    margin: 0;
    font-variant-numeric: tabular-nums;
}

.interstellar-credit {
    font-size: inherit;
    color: var(--color-text-muted);
    margin: var(--spacing-sm) 0 0;
    text-align: left;
}

.interstellar-panel .table-wrap {
    margin-inline: auto;
}

/* Fermi-paradox models and the propulsion-post charts: controls, a
   canvas, a short result line. They sit in the column, unlike the
   interstellar map, because they are diagrams of an equation rather
   than a sky. */
.fermi,
.prop {
    margin: var(--spacing-md) 0 var(--spacing-lg);
    padding: var(--spacing-sm) 0;
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
}

.fermi-controls,
.prop-controls {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.4rem 1.2rem;
    margin-bottom: var(--spacing-sm);
    font-size: inherit;
}

.fermi-controls label,
.prop-controls label {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    color: var(--color-text-muted);
}

.fermi-slider {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

.fermi-controls input[type="range"],
.prop-controls input[type="range"] {
    width: 100%;
}

.fermi-slider input[type="range"] {
    flex: 1;
    width: auto;
    min-width: 0;
}

.fermi-controls input[type="number"],
.prop-controls input[type="number"],
.prop-controls select {
    width: 100%;
    font-family: var(--font-serif);
    font-size: 1rem;
    padding: 0.15rem 0.4rem;
    border: 1px solid var(--color-border);
    background: var(--color-bg);
    color: var(--color-text);
}

.fermi-controls input.fermi-value {
    width: 5.4rem;
    flex: none;
    font-variant-numeric: tabular-nums;
}

.prop-controls label.prop-check {
    flex-direction: row;
    align-items: center;
    gap: 0.45rem;
}

.fermi-actions,
.prop-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
    margin: 0.4rem 0 var(--spacing-sm);
}

.fermi-actions button,
.prop-actions button {
    font-family: var(--font-serif);
    font-size: inherit;
    padding: 0.2rem 0.7rem;
    color: var(--color-link);
    background: none;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    cursor: pointer;
}

.fermi-actions button:hover,
.prop-actions button:hover {
    color: var(--color-link-hover);
    border-color: var(--color-link-hover);
}

.fermi-canvas,
.prop-canvas {
    display: block;
    width: 100%;
    height: 280px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 6px;
}

.prop-canvas.tall {
    height: 340px;
}

.fermi-results,
.prop-results {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.1rem 1.2rem;
    margin: var(--spacing-sm) 0 0;
    font-variant-numeric: tabular-nums;
}

.fermi-results dt,
.prop-results dt {
    color: var(--color-text-muted);
}

.fermi-results dd,
.prop-results dd {
    margin: 0;
}

.fermi-legend {
    display: flex;
    gap: 1.2rem;
    flex-wrap: wrap;
    font-size: inherit;
    color: var(--color-text-muted);
    margin-top: 0.4rem;
}

.fermi-legend i {
    display: inline-block;
    width: 0.7rem;
    height: 0.7rem;
    margin-right: 0.35rem;
    vertical-align: middle;
}

.prop-pane+.prop-pane {
    margin-top: var(--spacing-md);
    padding-top: var(--spacing-md);
    border-top: 1px solid var(--color-border);
}

.prop-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem 1.15rem;
    list-style: none;
    margin: 0.55rem 0 0;
    padding: 0;
    font-size: inherit;
    color: var(--color-text-muted);
}

.prop-legend li {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    line-height: 1;
}

.prop-legend i {
    display: block;
    width: 0.7rem;
    height: 0.7rem;
    margin: 0;
    flex: none;
}

.solutions {
    list-style: decimal;
    margin: var(--spacing-sm) 0 var(--spacing-md);
    padding-left: 1.6rem;
}

.solutions>li {
    margin-bottom: 1.1rem;
    font-size: 1rem;
}

.solutions>li>strong:first-child {
    font-weight: 600;
    color: var(--color-text);
}

.sol-sum,
.sol-ref,
.sol-sf {
    display: block;
    margin-top: 0.2rem;
}

.sol-ref,
.sol-sf {
    font-size: 0.92rem;
    color: var(--color-text-muted);
}

.sol-ref a,
.sol-sf a {
    font-weight: 500;
}

.works-map {
    margin: var(--spacing-sm) 0 var(--spacing-md);
    padding-left: 1.4rem;
}

.works-map li {
    margin-bottom: 0.45rem;
}

/* Vertical column alignment for controls removed to fix layout issues */
.route-stop-method,
.route-stop-advisory,
.route-stop-logistics {
    font-size: 0.9em;
    margin-top: 0.25em;
}

.advisory-level-1 {
    color: #388e3c;
}

.advisory-level-2 {
    color: #f57c00;
}

.advisory-level-3 {
    color: #e64a19;
}

.advisory-level-4 {
    color: #d32f2f;
    font-weight: 600;
}

/* A figure holding several photographs of one work rather than a single
   image. Two shapes: a set stepped through one at a time (the sculptures,
   photographed from several sides), and a plate of many small prints. Both
   expand to fill the window, and a click on a photograph in the expanded
   view gives it at the size it was scanned. */
.figure-gallery .gallery-row {
    display: flex;
    gap: var(--spacing-xs);
    align-items: center;
    justify-content: center;
}

/* --- stepped through, one at a time --- */
.gallery-steps .gallery-row img {
    display: none;
}

/* Wider than the column it sits in. The post is 800px because that is a
   measure for reading, which a photograph of a sculpture is not. Only the
   collapsed figure is widened: the expanded one is already fixed to the
   whole window and resets its own margins. Nothing is centred with a
   transform, which would become the containing block and stop the expanded
   state's `position: fixed` meaning the window. */
.gallery-steps:not(.is-expanded) {
    width: min(100vw - 2rem, 1120px);
    margin-inline: calc(50% - min(50vw - 1rem, 560px));
}

.gallery-steps .gallery-row img.is-current {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    /* As large as the window allows, and never past the size it was scanned:
       max-height cannot upscale, so the small La Pensee pair stop at their
       own 850px while the marbles run to 1400. */
    max-height: min(82vh, 1400px);
    border-radius: 4px;
    margin: 0 auto;
    cursor: zoom-in;
}

.gallery-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-sm);
    margin-top: var(--spacing-xs);
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

.gallery-bar button {
    font-family: var(--font-serif);
    font-size: 1rem;
    line-height: 1;
    padding: 0.25rem 0.7rem;
    color: var(--color-link);
    background: none;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    cursor: pointer;
    transition: border-color var(--transition), color var(--transition);
}

.gallery-bar button:hover {
    color: var(--color-link-hover);
    border-color: var(--color-link-hover);
}

.gallery-count {
    font-variant-numeric: tabular-nums;
}

/* --- a plate of many prints --- */
.gallery-plate .gallery-row {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
    align-items: start;
}

.gallery-plate .gallery-row img {
    width: 100%;
    height: auto;
    /* One box per print, whatever proportion it was engraved at; `contain`
       squares them up without cropping anything out of the frame. */
    aspect-ratio: 3 / 4;
    object-fit: contain;
    border-radius: 4px;
    margin: 0;
    cursor: zoom-in;
}

/* --- expanded --- */
.post-figure.figure-gallery.is-expanded .gallery-row {
    height: calc(100vh - 170px);
    width: 100%;
}

.post-figure.gallery-steps.is-expanded .gallery-row img.is-current {
    max-height: 100%;
    max-width: 100%;
    height: 100%;
    width: auto;
    object-fit: contain;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
}

.post-figure.gallery-plate.is-expanded .gallery-row {
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    height: auto;
    max-height: calc(100vh - 170px);
    overflow: auto;
}

/* --- one photograph, at the size it was scanned --- */
.post-figure.figure-gallery.is-expanded.is-solo .gallery-row {
    display: block;
    height: auto;
    max-height: calc(100vh - 170px);
    overflow: auto;
    text-align: center;
}

.post-figure.figure-gallery.is-expanded.is-solo .gallery-row img {
    display: none;
}

.post-figure.figure-gallery.is-expanded.is-solo .gallery-row img.is-solo-target {
    display: inline-block;
    width: max-content;
    max-width: none;
    height: auto;
    max-height: none;
    aspect-ratio: auto;
    object-fit: fill;
    cursor: zoom-out;
}

@media (max-width: 700px) {
    .gallery-steps .gallery-row img.is-current {
        max-height: 62vh;
    }

    .gallery-steps:not(.is-expanded) {
        width: auto;
        margin-inline: 0;
    }

    .gallery-plate .gallery-row {
        grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
    }

    .post-figure.gallery-plate.is-expanded .gallery-row {
        grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
    }
}